X-Git-Url: http://dolda2000.com/gitweb/?p=didex.git;a=blobdiff_plain;f=didex%2Fstore.py;h=43c134873e71bfbfa8898e20ee0d82fa2a309bcc;hp=15d2eca11beab793506299b83fbe93eabff9adc9;hb=d6d41a45b2882bf919cd7702d7590ead03e9d590;hpb=b080a59cbbe6b293d754bfa97c386eeede6b51ee diff --git a/didex/store.py b/didex/store.py index 15d2eca..43c1348 100644 --- a/didex/store.py +++ b/didex/store.py @@ -2,16 +2,26 @@ import threading, pickle from . import db, index, cache from .db import txnfun +__all__ = ["environment", "datastore", "autostore"] + class environment(object): - def __init__(self, path): - self.path = path + def __init__(self, *, path=None, getpath=None, recover=False): + if path is not None: + self.path = path + self.getpath = None + else: + self.path = None + self.getpath = getpath + self.recover = recover self.lk = threading.Lock() self.bk = None def __call__(self): with self.lk: if self.bk is None: - self.bk = db.environment(self.path) + if self.path is None: + self.path = self.getpath() + self.bk = db.environment(self.path, recover=self.recover) return self.bk def close(self): @@ -34,14 +44,14 @@ def storedescs(obj): t.__didex_attr = ret return ret -class store(object): +class datastore(object): def __init__(self, name, *, env=None, path=".", ncache=None): self.name = name self.lk = threading.Lock() if env: self.env = env else: - self.env = environment(path) + self.env = environment(path=path) self._db = None if ncache is None: ncache = cache.cache() @@ -75,16 +85,38 @@ class store(object): return id @txnfun(lambda self: self.db().env.env) - def unregister(self, id, *, tx): + def unregister(self, id, *, vfy=None, tx): obj = self.get(id) + if vfy is not None and obj is not vfy: + raise RuntimeError("object identity crisis: " + str(vfy) + " is not cached object " + obj) for nm, attr in storedescs(obj): attr.unregister(id, obj, tx) self.db().remove(id, tx=tx) self.cache.remove(id) @txnfun(lambda self: self.db().env.env) - def update(self, id, *, tx): + def update(self, id, *, vfy=None, tx): obj = self.get(id, load=False) + if vfy is not None and obj is not vfy: + raise RuntimeError("object identity crisis: " + str(vfy) + " is not cached object " + obj) for nm, attr, in storedescs(obj): attr.update(id, obj, tx) self.db().replace(id, self._encode(obj), tx=tx) + +class autotype(type): + def __call__(self, *args, **kwargs): + new = super().__call__(*args, **kwargs) + new.id = self.store.register(new) + self.store.update(new.id, vfy=new) # This doesn't feel too nice. + return new + +class autostore(object, metaclass=autotype): + def __init__(self): + self.id = None + + def save(self): + self.store.update(self.id, vfy=self) + + def remove(self): + self.store.unregister(self.id, vfy=self) + self.id = None