X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fbackends%2Fback_anydbm.py;h=a039f1598d17b0b030c7e1233cecc04846ecc25a;hb=21b3acdf5b78d378f1f9044815f69f33bd2f168f;hp=e50a9603c0366e5125470da4489b1e2f485a7336;hpb=f1e45843492261e42dd63c15063ec943e5e71ab2;p=roundup.git diff --git a/roundup/backends/back_anydbm.py b/roundup/backends/back_anydbm.py index e50a960..a039f15 100644 --- a/roundup/backends/back_anydbm.py +++ b/roundup/backends/back_anydbm.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -#$Id: back_anydbm.py,v 1.80 2002-09-17 23:59:59 richard Exp $ +#$Id: back_anydbm.py,v 1.84 2002-09-23 00:50:32 richard Exp $ ''' This module defines a backend that saves the hyperdatabase in a database chosen by anydbm. It is guaranteed to always be available in python @@ -73,11 +73,21 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): os.umask(0002) def post_init(self): - '''Called once the schema initialisation has finished.''' + ''' Called once the schema initialisation has finished. + ''' # reindex the db if necessary if self.indexer.should_reindex(): self.reindex() + # figure the "curuserid" + if self.journaltag is None: + self.curuserid = None + elif self.journaltag == 'admin': + # admin user may not exist, but always has ID 1 + self.curuserid = '1' + else: + self.curuserid = self.user.lookup(self.journaltag) + def reindex(self): for klass in self.classes.values(): for nodeid in klass.list(): @@ -236,6 +246,15 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): ''' if __debug__: print >>hyperdb.DEBUG, 'addnode', (self, classname, nodeid, node) + + # we'll be supplied these props if we're doing an import + if not node.has_key('creator'): + # add in the "calculated" properties (dupe so we don't affect + # calling code's node assumptions) + node = node.copy() + node['creator'] = self.curuserid + node['creation'] = node['activity'] = date.Date() + self.newnodes.setdefault(classname, {})[nodeid] = 1 self.cache.setdefault(classname, {})[nodeid] = node self.savenode(classname, nodeid, node) @@ -247,6 +266,11 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): print >>hyperdb.DEBUG, 'setnode', (self, classname, nodeid, node) self.dirtynodes.setdefault(classname, {})[nodeid] = 1 + # update the activity time (dupe so we don't affect + # calling code's node assumptions) + node = node.copy() + node['activity'] = date.Date() + # can't set without having already loaded the node self.cache[classname][nodeid] = node self.savenode(classname, nodeid, node) @@ -569,6 +593,9 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): # save the indexer state self.indexer.save_index() + self.clearCache() + + def clearCache(self): # all transactions committed, back to normal self.cache = {} self.dirtynodes = {} @@ -619,7 +646,7 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): if creator: journaltag = creator else: - journaltag = self.journaltag + journaltag = self.curuserid if creation: journaldate = creation.serialise() else: @@ -937,7 +964,10 @@ class Class(hyperdb.Class): value = pwd d[propname] = value - # extract the extraneous journalling gumpf and nuke it + # add the node and journal + self.db.addnode(self.classname, newid, d) + + # extract the journalling stuff and nuke it if d.has_key('creator'): creator = d['creator'] del d['creator'] @@ -951,8 +981,6 @@ class Class(hyperdb.Class): if d.has_key('activity'): del d['activity'] - # add the node and journal - self.db.addnode(self.classname, newid, d) self.db.addjournal(self.classname, newid, 'create', d, creator, creation) return newid @@ -975,7 +1003,13 @@ class Class(hyperdb.Class): if propname == 'id': return nodeid + # get the node's dict + d = self.db.getnode(self.classname, nodeid, cache=cache) + + # check for one of the special props if propname == 'creation': + if d.has_key('creation'): + return d['creation'] if not self.do_journal: raise ValueError, 'Journalling is disabled for this class' journal = self.db.getjournal(self.classname, nodeid) @@ -985,6 +1019,8 @@ class Class(hyperdb.Class): # on the strange chance that there's no journal return date.Date() if propname == 'activity': + if d.has_key('activity'): + return d['activity'] if not self.do_journal: raise ValueError, 'Journalling is disabled for this class' journal = self.db.getjournal(self.classname, nodeid) @@ -994,20 +1030,29 @@ class Class(hyperdb.Class): # on the strange chance that there's no journal return date.Date() if propname == 'creator': + if d.has_key('creator'): + return d['creator'] if not self.do_journal: raise ValueError, 'Journalling is disabled for this class' journal = self.db.getjournal(self.classname, nodeid) if journal: - return self.db.getjournal(self.classname, nodeid)[0][2] + num_re = re.compile('^\d+$') + value = self.db.getjournal(self.classname, nodeid)[0][2] + if num_re.match(value): + return value + else: + # old-style "username" journal tag + try: + return self.db.user.lookup(value) + except KeyError: + # user's been retired, return admin + return '1' else: - return self.db.journaltag + return self.db.curuserid # get the property (raises KeyErorr if invalid) prop = self.properties[propname] - # get the node's dict - d = self.db.getnode(self.classname, nodeid, cache=cache) - if not d.has_key(propname): if default is _marker: if isinstance(prop, Multilink): @@ -1103,7 +1148,11 @@ class Class(hyperdb.Class): # this will raise the KeyError if the property isn't valid # ... we don't use getprops() here because we only care about # the writeable properties. - prop = self.properties[propname] + try: + prop = self.properties[propname] + except KeyError: + raise KeyError, '"%s" has no property named "%s"'%( + self.classname, propname) # if the value's the same as the existing value, no sense in # doing anything @@ -1388,7 +1437,8 @@ class Class(hyperdb.Class): return nodeid finally: cldb.close() - raise KeyError, keyvalue + raise KeyError, 'No key (%s) value "%s" for "%s"'%(self.key, + keyvalue, self.classname) # change from spec - allows multiple props to match def find(self, **propspec): @@ -1499,6 +1549,10 @@ class Class(hyperdb.Class): "sort" and "group" are (dir, prop) where dir is '+', '-' or None and prop is a prop name or None "search_matches" is {nodeid: marker} + + The filter must match all properties specificed - but if the + property value to match is a list, any one of the values in the + list may match for that property to match. ''' cn = self.classname @@ -1751,9 +1805,7 @@ class Class(hyperdb.Class): d['id'] = String() d['creation'] = hyperdb.Date() d['activity'] = hyperdb.Date() - # can't be a link to user because the user might have been - # retired since the journal entry was created - d['creator'] = hyperdb.String() + d['creator'] = hyperdb.Link('user') return d def addprop(self, **properties):