index 09425b2ac35ce557ac24c11d5f93829cb8fbd827..ebbb648a08d94db82f0f966d2cd30b9fd9b3dd47 100644 (file)
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.
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)
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__:
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)
continue
cvt = self.to_hyperdb_value(property.__class__)
if isinstance(property, Password):
- params[param] = cvt(value)
+ params[param] = password.JournalPassword(value)
elif isinstance(property, Date):
params[param] = cvt(value)
elif isinstance(property, Interval):
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:
# 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:
if not isinstance(value, password.Password):
raise TypeError('new property "%s" not a Password'%propname)
propvalues[propname] = value
+ journalvalues[propname] = \
+ current and password.JournalPassword(current)
elif value is not None and isinstance(prop, Date):
if not isinstance(value, date.Date):
raise DatabaseError(_('Database open read-only'))
self.db.destroynode(self.classname, nodeid)
- def history(self, nodeid):
- """Retrieve the journal of edits on a particular node.
-
- 'nodeid' must be the id of an existing node of this class or an
- IndexError is raised.
-
- The returned list contains tuples of the form
-
- (nodeid, date, tag, action, params)
-
- 'date' is a Timestamp object specifying the time of the change and
- 'tag' is the journaltag specified when the database was opened.
- """
- if not self.do_journal:
- raise ValueError('Journalling is disabled for this class')
- return self.db.getjournal(self.classname, nodeid)
-
# Locating nodes:
def hasnode(self, nodeid):
"""Determine if the given nodeid actually exists