def __init__(self,*args,**kwargs): self.logger = logging.getLogger("MysteryMachine.store.file_store") self.logger.debug( args) super(filestore,self).__init__(*args,**kwargs) uri = args[0] create = kwargs.setdefault('create',False) self.path = self.GetCanonicalUri(GetPath(uri)) self._lock = RRwLock() if create: os.mkdir(self.path) #Create a transaction Log object self.tlog = FileLogger(self.path, track_state = False) self.newobjs = [] self.newcat = [] self.newattr = {}
class filestore(Base): """ A basic persistent Store which is designed to be simple but complaint with the Mysterymachine interface. There are no SCM methods attached to this store - will we create a mixin for the SCM actions. Reading data during a transaction yields undefined values. It can return pre-xaction values or current balues. """ uriScheme = "attrfile" supports_txn = True invalidobj = re.compile("^\.") @staticmethod def GetCanonicalUri(uri): #Canonical filepath. return os.path.normcase(os.path.normpath(os.path.realpath(os.path.expanduser(uri)))) def __init__(self,*args,**kwargs): self.logger = logging.getLogger("MysteryMachine.store.file_store") self.logger.debug( args) super(filestore,self).__init__(*args,**kwargs) uri = args[0] create = kwargs.setdefault('create',False) self.path = self.GetCanonicalUri(GetPath(uri)) self._lock = RRwLock() if create: os.mkdir(self.path) #Create a transaction Log object self.tlog = FileLogger(self.path, track_state = False) self.newobjs = [] self.newcat = [] self.newattr = {} def close(self,): self.tlog.close() def get_path(self): return self.path def start_store_transaction(self,): self._lock.acquire_read() try: self.tx = self.tlog.start_transaction() except: self._lock.release() raise def commit_store_transaction(self,): self.tlog.commit_transaction(self.tx) self.newobjs = [] self.newcat = [] self.newattr = {} self._lock.release() def abort_store_transaction(self,): self.tlog.abort_transaction(self.tx) self.newobjs = [] self.newcat = [] self.newattr = {} self._lock.release() def EnumCategories(self): for dentry in os.listdir(self.path): #Skip directories which we don't manage. #Current plan is to have one directory per store inside the # system if multiple stores are used. if os.path.isdir(os.path.join(self.path , dentry )): #Ignore hidden directories if dentry[0] != '.': if os.path.isfile(os.path.join(self.path,dentry,CATEGORY_SENTINEL_NAME)): yield dentry def EnumObjects(self,category): catpath = self.canonicalise(category) if catpath not in self.newcat: for dentry in os.listdir(os.path.join(self.path,*catpath)): objpath = catpath + [ dentry ] if not os.path.isdir(os.path.join(self.path,*objpath)) : continue sentinelpath = objpath + [ OBJECT_SENTINEL_NAME ] if not os.path.isfile(os.path.join(self.path,*sentinelpath)): continue yield dentry for obj in self.newobjs: #Search for obj created this txn, in this category. if obj[:len(catpath)] == catpath: yield obj[len(catpath)] def NewCategory(self,category): can_catpath = self.canonicalise(category) catpath = os.path.join( *can_catpath) try: self.tlog.Create_Dir(self.tx,catpath) except OSError, e: #Ignore Directory already exists errors . if e.errno != errno.EEXIST: raise except WindowsError, e: #Ignore Directory already exists errors . if e.errno != 183: raise