Back to index

nordugrid-arc-nox  1.1.0~rc6
zodbstore.py
Go to the documentation of this file.
00001 import arc
00002 import os, copy, threading, time
00003 from ZODB import FileStorage, DB
00004 from persistent import Persistent
00005 
00006 from arcom.store.basestore import BaseStore
00007 
00008 from arcom.logger import Logger
00009 log = Logger(arc.Logger(arc.Logger_getRootLogger(), 'arcom.ZODBStore'))
00010 
00011 class Metadata(Persistent):
00012     """
00013     Class for persistent mutable metadata
00014     """
00015     def __init__(self): 
00016         self.meta={}
00017     
00018     def addMeta(self, ID, object):
00019         self.meta[ID]=object
00020         self._p_changed = 1
00021         
00022     def delMeta(self, ID):
00023         del(self.meta[ID])
00024         self._p_changed = 1
00025         
00026     def __getitem__(self, ID):
00027         return self.meta[ID]
00028     
00029     def list(self):
00030         return self.meta.keys()
00031 
00032 class ZODBStore(BaseStore):
00033 
00034     def __init__(self, storecfg, non_existent_object = {}):
00035         """ Constructor of ZODBStore.
00036 
00037         ZODBStore(storecfg)
00038 
00039         'storecfg' is an XMLNode with a 'DataDir'
00040         'non_existent_object' will be returned if an object not found
00041         """
00042         BaseStore.__init__(self, storecfg, non_existent_object)
00043         log.msg(arc.VERBOSE, "ZODBStore constructor called")
00044         log.msg(arc.VERBOSE, "datadir:", self.datadir)
00045         self.dbfile = os.path.join(self.datadir,'metadata.fs')
00046         if os.path.isfile(self.dbfile):
00047             self.db = DB(FileStorage.FileStorage(self.dbfile))
00048             self.db.setCacheSize(4000)
00049             # decrease db file size in case of previous deletions 
00050             # (should maybe do this in a separate script?)
00051             #db.pack()
00052             self.metadata = self.db.open().root()['meta']
00053         else:
00054             self.db = DB(FileStorage.FileStorage(self.dbfile))
00055             root = self.db.open().root()
00056             root['meta'] = Metadata()
00057             get_transaction().commit()
00058             self.metadata = root['meta']
00059         self.period = 60
00060         threading.Thread(target = self.packingThread, args = [self.period]).start()
00061 
00062     def packingThread(self,period):
00063         time.sleep(7)
00064         while True:
00065             self.db.pack()
00066             time.sleep(period)
00067             
00068     def list(self):
00069         """ List the IDs of the existing entries.
00070         
00071         list()
00072         
00073         Returns a list of IDs.
00074         Only relevant for shepherd
00075         """
00076         #get_transaction().commit()
00077         return self.metadata.list()
00078 
00079     def get(self, ID):
00080         """ Returns the object with the given ID.
00081 
00082         get(ID)
00083 
00084         'ID' is the ID of the requested object.
00085         If there is no object with this ID, returns the given non_existent_object value.
00086         """
00087         try:
00088             #get_transaction().commit()
00089             return self.metadata[ID]
00090         except KeyError:
00091             # don't print 'KeyError' if there is no such ID
00092             pass
00093         except:
00094             # print whatever exception happened
00095             log.msg()
00096             log.msg(arc.ERROR, "ID", ID)
00097         # if there was an exception, return the given non_existent_object
00098         return copy.deepcopy(self.non_existent_object)
00099 
00100     def set(self, ID, object):
00101         """ Stores an object with the given ID..
00102 
00103         set(ID, object)
00104 
00105         'ID' is the ID of the object
00106         'object' is the object itself
00107         If there is already an object with this ID it will be overwritten completely.
00108         """
00109         if not ID:
00110             raise Exception, 'ID is empty'
00111         try:
00112             if object == None:
00113                 self.metadata.delMeta(ID)
00114             else:
00115                 self.metadata.addMeta(ID, object)
00116             get_transaction().commit()
00117         except:
00118             log.msg()