class Persistent(object): def __init__(self, name, **kw): super(Persistent, self).__init__() self.name = name self.storage = None self.synclock = RLock() self.path = kw.get('path', PDODIR) self.encode = kw.get('encode', repr) self.decode = kw.get('decode', eval) self.extension = kw.get('extension', 'dat') self.autopersist = kw.get('autopersist', True) if self.autopersist: self.load() def open(self): self.synclock.acquire() try: self.storage = FileStorage(self.path, self.name, self.extension) self.storage.open() finally: self.synclock.release() def close(self): self.synclock.acquire() try: self.storage.close() self.storage = None finally: self.synclock.release() def closed(self): storage = self.storage if storage is None: return True elif storage.closed(): return True return False def update_storage(self): """ Serialize and data associated with object and update storage record to match serialization. """ self.synclock.acquire() try: data = self.getencoded() self.storage.set(data) finally: self.synclock.release() def update_data(self): self.synclock.acquire() try: data = self.storage.getdata() self.setencoded(data) finally: self.synclock.release() def commit(self): """ Update storage with most recent data, then commit changes. """ self.synclock.acquire() try: self.update_storage() self.storage.commit() self.notify_committed() finally: self.synclock.release() def load(self): """ Load most recently stored data, then update current data with loaded content. """ self.synclock.acquire() try: if self.storage is None: self.open() self.storage.load() self.update_data() self.notify_loaded() finally: self.synclock.release() def serialize(self, data): if self.encode is not None: data = self.encode(data) return data def unserialize(self, data): if self.decode is not None: data = self.decode(data) return data def getencoded(self): """ Return encoded representation of current data object. This method must be overridden in type-specific subclasses. """ raise TypeError("Method must be overridden") def setencoded(self, data): """ Use encoded representation of persisted data object to update current data object. This method must be overridden in type-specific subclasses. """ raise TypeError("Method must be overridden") def notify_committed(self): pass def notify_loaded(self): pass