Compare commits
No commits in common. "b726f495b65125eb72dd9b1b7285e0578cf7a0bf" and "c2e09b2c10afb09c702ac449a73fea315ad92f86" have entirely different histories.
b726f495b6
...
c2e09b2c10
@ -5,8 +5,8 @@ etc. Objects inheriting from the `CO3` base class can then define data transform
|
|||||||
that connect to database components, and can be automatically collected for coordinated
|
that connect to database components, and can be automatically collected for coordinated
|
||||||
database insertion.
|
database insertion.
|
||||||
|
|
||||||
`co3` attempts to provide a general interface for interacting with storage media (e.g.,
|
`co3` attempts to provide a general interface for interacting with a storage media (e.g.,
|
||||||
databases, pickled objects, VSS framework, in-memory key-value stores, etc). The following
|
database, pickled objects, VSS framework, in-memory key-value stores, etc). The following
|
||||||
top-level classes capture the bulk of the operational model:
|
top-level classes capture the bulk of the operational model:
|
||||||
|
|
||||||
- **Database**: reference to a storage medium, with an `Accessor` for accessing data,
|
- **Database**: reference to a storage medium, with an `Accessor` for accessing data,
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
class Component[T]:
|
'''
|
||||||
'''
|
Component
|
||||||
Component
|
|
||||||
|
|
||||||
General wrapper for storage components to be used in various database contexts. Relations
|
General wrapper for storage components to be used in various database contexts. Relations
|
||||||
can be thought of generally as named data containers/entities serving as a fundamental
|
can be thought of generally as named data containers/entities serving as a fundamental
|
||||||
abstractions within particular storage protocols.
|
abstractions within particular storage protocols.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
class Component[T]:
|
||||||
def __init__(self, name, obj: T):
|
def __init__(self, name, obj: T):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
@ -18,3 +19,4 @@ class Component[T]:
|
|||||||
|
|
||||||
def get_attributes(self):
|
def get_attributes(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
from co3 import Resource
|
|
||||||
|
|
||||||
|
|
||||||
class Domain[R: Resource]:
|
|
||||||
'''
|
|
||||||
General Domain class
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
def __init__(self, content):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_resource(self, url: URL) -> Resource:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def connect(self, timeout=None):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
class SelectableDomain(Domain):
|
|
||||||
def select(self, component, *args, **kwargs):
|
|
||||||
raise NotImplementedError
|
|
@ -13,7 +13,7 @@ class Engine:
|
|||||||
derivative Engines, like SQLEngine, mostly just wrap another engine-like object, this
|
derivative Engines, like SQLEngine, mostly just wrap another engine-like object, this
|
||||||
is not the rule. That is, inheriting Engine subtypes shouldn't necessarily expect to
|
is not the rule. That is, inheriting Engine subtypes shouldn't necessarily expect to
|
||||||
rely on another object per se, and if such an object is required, _this_ is the class
|
rely on another object per se, and if such an object is required, _this_ is the class
|
||||||
meant to be the skeleton that supports its creation (and not merely a wrapper for some
|
is meant to be skeleton to supports its creation (and not merely a wrapper for some
|
||||||
other type, although it may appear that way when such a type is in fact readily
|
other type, although it may appear that way when such a type is in fact readily
|
||||||
available).
|
available).
|
||||||
|
|
@ -75,7 +75,7 @@ class SQLManager(RelationalManager[SQLTable]):
|
|||||||
'''
|
'''
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
'''
|
'''
|
||||||
The insert lock is a *re-entrant lock*, meaning the same thread can acquire the
|
The insert lock is a *reentrant lock*, meaning the same thread can acquire the
|
||||||
lock again without deadlocking (simplifying across methods of this class that
|
lock again without deadlocking (simplifying across methods of this class that
|
||||||
need it).
|
need it).
|
||||||
'''
|
'''
|
||||||
@ -112,13 +112,11 @@ class SQLManager(RelationalManager[SQLTable]):
|
|||||||
def insert(
|
def insert(
|
||||||
self,
|
self,
|
||||||
connection,
|
connection,
|
||||||
component: SQLTable,
|
component,
|
||||||
inserts: list[dict],
|
inserts: list[dict],
|
||||||
commit=True
|
commit=True
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Insert a group of
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
'''
|
'''
|
||||||
with self._insert_lock:
|
with self._insert_lock:
|
||||||
@ -137,13 +135,6 @@ class SQLManager(RelationalManager[SQLTable]):
|
|||||||
Perform provided table inserts, aligning the insert format of
|
Perform provided table inserts, aligning the insert format of
|
||||||
``Collector.collect_inserts()``.
|
``Collector.collect_inserts()``.
|
||||||
|
|
||||||
Note that the regular ``insert`` actually supports the usual notion of a "bulk
|
|
||||||
insert," inserting many entries under a single table. This method simply supports
|
|
||||||
the same but across multiple tables. It does so by just making calls to
|
|
||||||
``insert()`` after grouping entries for each component in the provided ``inserts``
|
|
||||||
dict, only committing the transaction after all components inserts have been
|
|
||||||
staged.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
inserts: component-indexed dictionary of insert lists
|
inserts: component-indexed dictionary of insert lists
|
||||||
'''
|
'''
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
import logging
|
|
||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class Medium[R: Resource]:
|
|
||||||
'''
|
|
||||||
Medium base class.
|
|
||||||
|
|
||||||
A Resource space
|
|
||||||
'''
|
|
||||||
def __init__(self, scope):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def connect(self, timeout=None):
|
|
||||||
'''
|
|
||||||
Open a connection to the database specified by the resource. Exactly what the
|
|
||||||
returned connection looks like remains relatively unconstrained given the wide
|
|
||||||
variety of possible database interactions. This function should be invoked in
|
|
||||||
with-statement contexts, constituting an "interaction session" with the database
|
|
||||||
(i.e., allowing several actions to be performed using the same connection).
|
|
||||||
'''
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def execute(self, query: Query[QL]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class BrowsableMedium[R: Resource](Medium[R]):
|
|
||||||
def browse(self, uri: URI[R]):
|
|
||||||
'''
|
|
||||||
Analog for Read (CRUD), SELECT (SQL), GET (REST)
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ABCDMedium[R: Resource](BrowsableMedium[R]):
|
|
||||||
def append(self, uri: URI[R], resource: R):
|
|
||||||
'''
|
|
||||||
Analog for Create (CRUD), INSERT (SQL), POST/PUT (REST)
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
def change(self, uri: URI[R], resource: R):
|
|
||||||
'''
|
|
||||||
Analog for Update (CRUD), UPDATE (SQL), PUT/PATCH (REST)
|
|
||||||
|
|
||||||
Can a URI be another object? Component for ex; could inherit from URI I guess
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
def delete(self, uri: URI[R]):
|
|
||||||
'''
|
|
||||||
Analog for Delete (CRUD), DELETE (SQL), DELETE (REST)
|
|
||||||
'''
|
|
||||||
pass
|
|
@ -2,8 +2,7 @@ from typing import Protocol
|
|||||||
|
|
||||||
|
|
||||||
class Resource:
|
class Resource:
|
||||||
def content(self) -> BinaryIO:
|
pass
|
||||||
pass
|
|
||||||
|
|
||||||
class SelectableResource(Protocol):
|
class SelectableResource(Protocol):
|
||||||
def select(self, component, *args, **kwargs):
|
def select(self, component, *args, **kwargs):
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
from co3.resources.disk import DiskResource
|
@ -1,12 +1,10 @@
|
|||||||
#from co3.resources.disk import DiskResource
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from co3.util import paths
|
from co3.util import paths
|
||||||
from co3.resource import SelectableDomain
|
from co3.resource import SelectableResource
|
||||||
|
|
||||||
|
|
||||||
class DiskDomain(SelectableDomain):
|
class DiskResource(SelectableResource):
|
||||||
def select(
|
def select(
|
||||||
self,
|
self,
|
||||||
path_list: str | Path | list[str | Path],
|
path_list: str | Path | list[str | Path],
|
15
co3/uri.py
15
co3/uri.py
@ -1,15 +0,0 @@
|
|||||||
from urllib import parse
|
|
||||||
|
|
||||||
|
|
||||||
class URI:
|
|
||||||
def __init__(self, url_str: str):
|
|
||||||
self.url_str = url_str
|
|
||||||
|
|
||||||
class URL(URI):
|
|
||||||
def __init__(self, url_str: str):
|
|
||||||
self.url_str = url_str
|
|
||||||
|
|
||||||
class URN(URI):
|
|
||||||
def __init__(self, url_str: str):
|
|
||||||
self.url_str = url_str
|
|
||||||
|
|
@ -2,9 +2,6 @@
|
|||||||
requires = ["setuptools", "wheel", "setuptools-git-versioning>=2.0,<3"]
|
requires = ["setuptools", "wheel", "setuptools-git-versioning>=2.0,<3"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[tool.setuptools-git-versioning]
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "co3"
|
name = "co3"
|
||||||
description = "Lightweight Python ORM for hierarchical storage management"
|
description = "Lightweight Python ORM for hierarchical storage management"
|
||||||
@ -40,7 +37,6 @@ docs = [
|
|||||||
"furo",
|
"furo",
|
||||||
"myst-parser",
|
"myst-parser",
|
||||||
]
|
]
|
||||||
jupyter = ["ipykernel"]
|
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "https://doc.olog.io/co3"
|
Homepage = "https://doc.olog.io/co3"
|
||||||
|
12
requirements.txt
Normal file
12
requirements.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# -- sphinx docs --
|
||||||
|
sphinx
|
||||||
|
sphinx-togglebutton
|
||||||
|
furo
|
||||||
|
myst-parser
|
||||||
|
sphinx-autodoc-typehints
|
||||||
|
|
||||||
|
sqlalchemy
|
||||||
|
numpy
|
||||||
|
wcmatch
|
||||||
|
|
||||||
|
pytest
|
Loading…
Reference in New Issue
Block a user