Mercurial > p > roundup > code
diff roundup/backends/back_metakit.py @ 1476:5a01e90b7dc9
fixed export/import of retired nodes [SF#685273]
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 26 Feb 2003 23:42:54 +0000 |
| parents | 378081f066cc |
| children | b3f2484babce |
line wrap: on
line diff
--- a/roundup/backends/back_metakit.py Wed Feb 26 21:10:21 2003 +0000 +++ b/roundup/backends/back_metakit.py Wed Feb 26 23:42:54 2003 +0000 @@ -38,6 +38,8 @@ _dbs = {} def Database(config, journaltag=None): + ''' Only have a single instance of the Database class for each instance + ''' db = _dbs.get(config.DATABASE, None) if db is None or db._db is None: db = _Database(config, journaltag) @@ -81,8 +83,10 @@ if self.journaltag is None: return None + # try to set the curuserid from the journaltag try: - self.curuserid = x = int(self.classes['user'].lookup(self.journaltag)) + x = int(self.classes['user'].lookup(self.journaltag)) + self.curuserid = x except KeyError: if self.journaltag == 'admin': self.curuserid = x = 1 @@ -91,6 +95,7 @@ return x elif classname == 'transactions': return self.dirty + # fall back on the classes return self.getclass(classname) def getclass(self, classname): try: @@ -100,6 +105,7 @@ def getclasses(self): return self.classes.keys() # --- end of ping's spec + # --- exposed methods def commit(self): if self.dirty: @@ -182,9 +188,10 @@ #usernm = userclass.get(str(row.user), 'username') dt = date.Date(time.gmtime(row.date)) #rslt.append((nodeid, dt, usernm, _actionnames[row.action], params)) - rslt.append((nodeid, dt, str(row.user), _actionnames[row.action], params)) + rslt.append((nodeid, dt, str(row.user), _actionnames[row.action], + params)) return rslt - + def destroyjournal(self, tablenm, nodeid): nodeid = int(nodeid) tblid = self.tables.find(name=tablenm) @@ -215,13 +222,22 @@ # --- internal def __open(self): + ''' Open the metakit database + ''' + # make the database dir if it doesn't exist if not os.path.exists(self.config.DATABASE): os.makedirs(self.config.DATABASE) + + # figure the file names self.dbnm = db = os.path.join(self.config.DATABASE, 'tracker.mk4') lockfilenm = db[:-3]+'lck' + + # get the database lock self.lockfile = locking.acquire_lock(lockfilenm) self.lockfile.write(str(os.getpid())) self.lockfile.flush() + + # see if the schema has changed since last db access self.fastopen = 0 if os.path.exists(db): dbtm = os.path.getmtime(db) @@ -236,18 +252,28 @@ else: # can't find schemamod - must be frozen self.fastopen = 1 + + # open the db db = metakit.storage(db, 1) hist = db.view('history') tables = db.view('tables') if not self.fastopen: + # create the database if it's brand new if not hist.structure(): hist = db.getas('history[tableid:I,nodeid:I,date:I,user:I,action:I,params:B]') if not tables.structure(): tables = db.getas('tables[name:S]') db.commit() + + # we now have an open, initialised database self.tables = tables self.hist = hist return db + + def setid(self, classname, maxid): + ''' No-op in metakit + ''' + pass _STRINGTYPE = type('') _LISTTYPE = type([]) @@ -632,10 +658,12 @@ ndx = view.find(id=int(nodeid)) if ndx < 0: raise KeyError, "nodeid %s not found" % nodeid + row = view[ndx] oldvalues = self.uncommitted.setdefault(row.id, {}) oldval = oldvalues['_isdel'] = row._isdel row._isdel = 1 + if self.do_journal: self.db.addjournal(self.classname, nodeid, _RETIRE, {}) if self.keyname: @@ -646,6 +674,16 @@ self.db.dirty = 1 self.fireReactors('retire', nodeid, None) + def is_retired(self, nodeid): + view = self.getview(1) + # node must exist & not be retired + id = int(nodeid) + ndx = view.find(id=id) + if ndx < 0: + raise IndexError, "%s has no node %s" % (self.classname, nodeid) + row = view[ndx] + return row._isdel + def history(self, nodeid): if not self.do_journal: raise ValueError, 'Journalling is disabled for this class' @@ -796,6 +834,7 @@ raise ValueError, "%s is already a property of %s"%(key, self.classname) self.ruprops.update(properties) + # Class structure has changed self.db.fastopen = 0 view = self.__getview() self.db.commit() @@ -1037,6 +1076,10 @@ elif isinstance(proptype, hyperdb.Password): value = str(value) l.append(repr(value)) + + # append retired flag + l.append(self.is_retired(nodeid)) + return l def import_list(self, propnames, proplist): @@ -1064,11 +1107,24 @@ value = int(calendar.timegm(value)) elif isinstance(prop, hyperdb.Interval): value = str(date.Interval(value)) + elif isinstance(prop, hyperdb.Number): + value = int(value) + elif isinstance(prop, hyperdb.Boolean): + value = int(value) + elif isinstance(prop, hyperdb.Link): + value = int(value) + elif isinstance(prop, hyperdb.Multilink): + value = map(int, value) d[propname] = value - view.append(d) - creator = d.get('creator', None) - creation = d.get('creation', None) - self.db.addjournal(self.classname, newid, 'create', {}, creator, + # is the item retired? + if int(proplist[-1]): + d['_isdel'] = 1 + # XXX this is BROKEN for reasons I don't understand! + ndx = view.append(d) + + creator = d.get('creator', 0) + creation = d.get('creation', 0) + self.db.addjournal(self.classname, newid, _CREATE, {}, creator, creation) return newid @@ -1101,11 +1157,20 @@ self.rbactions.append(action) # --- internal def __getview(self): + ''' Find the interface for a specific Class in the hyperdb. + + This method checks to see whether the schema has changed and + re-works the underlying metakit structure if it has. + ''' db = self.db._db view = db.view(self.classname) mkprops = view.structure() + + # if we have structure in the database, and the structure hasn't + # changed if mkprops and self.db.fastopen: return view.ordered(1) + # is the definition the same? for nm, rutyp in self.ruprops.items(): for mkprop in mkprops: @@ -1136,7 +1201,7 @@ return self.db._db.view(self.classname).ordered(1) def getindexview(self, RW=0): return self.db._db.view("_%s" % self.classname).ordered(1) - + def _fetchML(sv): l = [] for row in sv: @@ -1155,7 +1220,7 @@ return p def _fetchLink(n): - ''' Return None if the string is empty ?otherwise ensure it's a string? + ''' Return None if the link is 0 - otherwise strify it. ''' return n and str(n) or None
