X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fbackends%2Frdbms_common.py;h=ebbb648a08d94db82f0f966d2cd30b9fd9b3dd47;hb=d5597ec3a5458ae238e653aff0b333b44ad165a2;hp=5798c8d646e1ab223a16db221e06f52cf47a05e2;hpb=56e200d63c6098917037aee2587915a26afd1f8f;p=roundup.git diff --git a/roundup/backends/rdbms_common.py b/roundup/backends/rdbms_common.py index 5798c8d..ebbb648 100644 --- a/roundup/backends/rdbms_common.py +++ b/roundup/backends/rdbms_common.py @@ -812,6 +812,8 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): description="User is allowed to edit "+cn) self.security.addPermission(name="View", klass=cn, description="User is allowed to access "+cn) + self.security.addPermission(name="Retire", klass=cn, + description="User is allowed to retire "+cn) def getclasses(self): """ Return a list of the names of all existing classes. @@ -1080,8 +1082,34 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): raise ValueError('%r is not a hyperdb property class' % propklass) - def getnode(self, classname, nodeid): + def _materialize_multilink(self, classname, nodeid, node, propname): + """ evaluation of single Multilink (lazy eval may have skipped this) + """ + if propname not in node: + sql = 'select linkid from %s_%s where nodeid=%s'%(classname, + propname, self.arg) + self.sql(sql, (nodeid,)) + # extract the first column from the result + # XXX numeric ids + items = [int(x[0]) for x in self.cursor.fetchall()] + items.sort () + node[propname] = [str(x) for x in items] + + def _materialize_multilinks(self, classname, nodeid, node, props=None): + """ get all Multilinks of a node (lazy eval may have skipped this) + """ + cl = self.classes[classname] + props = props or [pn for (pn, p) in cl.properties.iteritems() + if isinstance(p, Multilink)] + for propname in props: + if propname not in node: + self._materialize_multilink(classname, nodeid, node, propname) + + def getnode(self, classname, nodeid, fetch_multilinks=True): """ Get a node from the database. + For optimisation optionally we don't fetch multilinks + (lazy Multilinks). + But for internal database operations we need them. """ # see if we have this node cached key = (classname, nodeid) @@ -1091,6 +1119,8 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): if __debug__: self.stats['cache_hits'] += 1 # return the cached information + if fetch_multilinks: + self._materialize_multilinks(classname, nodeid, self.cache[key]) return self.cache[key] if __debug__: @@ -1124,6 +1154,9 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database): value = self.to_hyperdb_value(props[name].__class__)(value) node[name] = value + if fetch_multilinks and mls: + self._materialize_multilinks(classname, nodeid, node, mls) + # save off in the cache key = (classname, nodeid) self._cache_save(key, node) @@ -1616,7 +1649,7 @@ class Class(hyperdb.Class): return nodeid # get the node's dict - d = self.db.getnode(self.classname, nodeid) + d = self.db.getnode(self.classname, nodeid, fetch_multilinks=False) # handle common case -- that property is in dict -- first # if None and one of creator/creation actor/activity return None if propname in d: @@ -1640,14 +1673,7 @@ class Class(hyperdb.Class): # lazy evaluation of Multilink if propname not in d and isinstance(prop, Multilink): - sql = 'select linkid from %s_%s where nodeid=%s'%(self.classname, - propname, self.db.arg) - self.db.sql(sql, (nodeid,)) - # extract the first column from the result - # XXX numeric ids - items = [int(x[0]) for x in self.db.cursor.fetchall()] - items.sort () - d[propname] = [str(x) for x in items] + self.db._materialize_multilink(self.classname, nodeid, d, propname) # handle there being no value in the table for the property if propname not in d or d[propname] is None: