102 lines
2.8 KiB
Python
102 lines
2.8 KiB
Python
import logging
|
|
from contextlib import contextmanager
|
|
|
|
from co3.engine import Engine, Connection, Resource, Group
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Medium[R: Resource]:
|
|
'''
|
|
Medium base class.
|
|
|
|
A Resource space
|
|
'''
|
|
_engine_cls: type[Engine] = Engine
|
|
|
|
def __init__(self, *scope_args, **scope_kwargs):
|
|
self.engine = self._engine_cls(*engine_args, **engine_kwargs)
|
|
pass
|
|
|
|
@contextmanager
|
|
def connect(self, timeout=None) -> Connection:
|
|
'''
|
|
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).
|
|
'''
|
|
return self.engine.connect(timeout=timeout)
|
|
|
|
def execute(self, query: Query[QL]):
|
|
pass
|
|
|
|
|
|
class ReadableMedium[R: Resource](Medium[R]):
|
|
def _resolve_relative_uri(self, protocol, value):
|
|
'''
|
|
Subclass to implement: fetch child object for supported protocol, i.e., single
|
|
component subpath
|
|
'''
|
|
...
|
|
|
|
def resolve_uri(self, uri: URI) -> ResourceCollection:
|
|
assert uri.protocols[0] in self.supported_protocols
|
|
|
|
obj = self._resolve_relative_uri(uri.protocols[0], uri.components[0])
|
|
|
|
# core the uri and recurse
|
|
cored_uri = uri.core():
|
|
|
|
if cored_uri:
|
|
rc = obj.resolve_uri(cored_uri)
|
|
else:
|
|
assert type(obj) is Resource
|
|
rc = ResourceCollection([obj])
|
|
|
|
return rc
|
|
|
|
def _to_uri_list(self, uri_like):
|
|
if type(uri) is not list:
|
|
uri = [uri]
|
|
...
|
|
|
|
def browse(
|
|
self,
|
|
connection: Connection,
|
|
uri: str | URI | list[str] | list[URI]
|
|
) -> ResourceCollection:
|
|
'''
|
|
Analog for Read (CRUD), SELECT (SQL), GET (REST)
|
|
'''
|
|
uris = self._to_uri_list(uri)
|
|
|
|
rc = ResourceCollection()
|
|
for uri in uris:
|
|
rc.extend(self._resolve_uri(uri))
|
|
|
|
return rc
|
|
|
|
|
|
class WritableMedium[R: Resource](ReadableMedium[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
|