X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fhyperdb.py;h=9aa575ac63813004cce38c19c62f53cf26501a31;hb=93d14d9ee2e0dbdb5c8971ace98c923bb5f155e7;hp=6551535e8cd734278511b306555819a7c8d072d5;hpb=e2b84cddf058518c493ede3c58a162a0b2cc6521;p=roundup.git diff --git a/roundup/hyperdb.py b/roundup/hyperdb.py index 6551535..9aa575a 100644 --- a/roundup/hyperdb.py +++ b/roundup/hyperdb.py @@ -15,18 +15,19 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: hyperdb.py,v 1.49 2002-01-16 07:02:57 richard Exp $ +# $Id: hyperdb.py,v 1.58 2002-02-27 03:23:16 richard Exp $ __doc__ = """ Hyperdatabase implementation, especially field types. """ # standard python modules -import cPickle, re, string, weakref +import re, string, weakref, os # roundup modules import date, password +DEBUG = os.environ.get('HYPERDBDEBUG', '') # # Types @@ -54,17 +55,24 @@ class Interval: class Link: """An object designating a Link property that links to a node in a specified class.""" - def __init__(self, classname): + def __init__(self, classname, do_journal='no'): self.classname = classname + self.do_journal = do_journal == 'yes' def __repr__(self): return '<%s to "%s">'%(self.__class__, self.classname) class Multilink: """An object designating a Multilink property that links to nodes in a specified class. + + "classname" indicates the class to link to + + "do_journal" indicates whether the linked-to nodes should have + 'link' and 'unlink' events placed in their journal """ - def __init__(self, classname): + def __init__(self, classname, do_journal='no'): self.classname = classname + self.do_journal = do_journal == 'yes' def __repr__(self): return '<%s to "%s">'%(self.__class__, self.classname) @@ -204,6 +212,11 @@ transaction. ''' raise NotImplementedError + def pack(self, pack_before): + ''' pack the database + ''' + raise NotImplementedError + def commit(self): ''' Commit the current transactions. @@ -309,8 +322,9 @@ class Class: propvalues[key] = value # register the link with the newly linked node - self.db.addjournal(link_class, value, 'link', - (self.classname, newid, key)) + if self.properties[key].do_journal: + self.db.addjournal(link_class, value, 'link', + (self.classname, newid, key)) elif isinstance(prop, Multilink): if type(value) != type([]): @@ -336,8 +350,9 @@ class Class: if not self.db.hasnode(link_class, id): raise IndexError, '%s has no node %s'%(link_class, id) # register the link with the newly linked node - self.db.addjournal(link_class, id, 'link', - (self.classname, newid, key)) + if self.properties[key].do_journal: + self.db.addjournal(link_class, id, 'link', + (self.classname, newid, key)) elif isinstance(prop, String): if type(value) != type(''): @@ -490,6 +505,13 @@ class Class: # the writeable properties. prop = self.properties[key] + # if the value's the same as the existing value, no sense in + # doing anything + if node.has_key(key) and value == node[key]: + del propvalues[key] + continue + + # do stuff based on the prop type if isinstance(prop, Link): link_class = self.properties[key].classname # if it isn't a number, it's a key @@ -505,15 +527,16 @@ class Class: if not self.db.hasnode(link_class, value): raise IndexError, '%s has no node %s'%(link_class, value) - # register the unlink with the old linked node - if node[key] is not None: - self.db.addjournal(link_class, node[key], 'unlink', - (self.classname, nodeid, key)) + if self.properties[key].do_journal: + # register the unlink with the old linked node + if node[key] is not None: + self.db.addjournal(link_class, node[key], 'unlink', + (self.classname, nodeid, key)) - # register the link with the newly linked node - if value is not None: - self.db.addjournal(link_class, value, 'link', - (self.classname, nodeid, key)) + # register the link with the newly linked node + if value is not None: + self.db.addjournal(link_class, value, 'link', + (self.classname, nodeid, key)) elif isinstance(prop, Multilink): if type(value) != type([]): @@ -543,19 +566,22 @@ class Class: if id in value: continue # register the unlink with the old linked node - self.db.addjournal(link_class, id, 'unlink', - (self.classname, nodeid, key)) + if self.properties[key].do_journal: + self.db.addjournal(link_class, id, 'unlink', + (self.classname, nodeid, key)) l.remove(id) # handle additions for id in value: if not self.db.hasnode(link_class, id): - raise IndexError, '%s has no node %s'%(link_class, id) + raise IndexError, '%s has no node %s'%( + link_class, id) if id in l: continue # register the link with the newly linked node - self.db.addjournal(link_class, id, 'link', - (self.classname, nodeid, key)) + if self.properties[key].do_journal: + self.db.addjournal(link_class, id, 'link', + (self.classname, nodeid, key)) l.append(id) elif isinstance(prop, String): @@ -579,6 +605,11 @@ class Class: node[key] = value + # nothing to do? + if not propvalues: + return + + # do the set, and journal it self.db.setnode(self.classname, nodeid, node) self.db.addjournal(self.classname, nodeid, 'set', propvalues) @@ -614,6 +645,10 @@ class Class: return self.db.getjournal(self.classname, nodeid) # Locating nodes: + def hasnode(self, nodeid): + '''Determine if the given nodeid actually exists + ''' + return self.db.hasnode(self.classname, nodeid) def setkey(self, propname): """Select a String property of this class to be the key property. @@ -827,7 +862,7 @@ class Class: else: continue break - elif t == 2 and not v.search(node[k]): + elif t == 2 and (node[k] is None or not v.search(node[k])): # RE search break elif t == 6 and node[k] != v: @@ -1039,14 +1074,54 @@ class Node: return self.cl.retire(self.nodeid) -def Choice(name, *options): - cl = Class(db, name, name=hyperdb.String(), order=hyperdb.String()) +def Choice(name, db, *options): + '''Quick helper to create a simple class with choices + ''' + cl = Class(db, name, name=String(), order=String()) for i in range(len(options)): - cl.create(name=option[i], order=i) + cl.create(name=options[i], order=i) return hyperdb.Link(name) # # $Log: not supported by cvs2svn $ +# Revision 1.57 2002/02/20 05:23:24 richard +# Didn't accomodate new values for new properties +# +# Revision 1.56 2002/02/20 05:05:28 richard +# . Added simple editing for classes that don't define a templated interface. +# - access using the admin "class list" interface +# - limited to admin-only +# - requires the csv module from object-craft (url given if it's missing) +# +# Revision 1.55 2002/02/15 07:27:12 richard +# Oops, precedences around the way w0rng. +# +# Revision 1.54 2002/02/15 07:08:44 richard +# . Alternate email addresses are now available for users. See the MIGRATION +# file for info on how to activate the feature. +# +# Revision 1.53 2002/01/22 07:21:13 richard +# . fixed back_bsddb so it passed the journal tests +# +# ... it didn't seem happy using the back_anydbm _open method, which is odd. +# Yet another occurrance of whichdb not being able to recognise older bsddb +# databases. Yadda yadda. Made the HYPERDBDEBUG stuff more sane in the +# process. +# +# Revision 1.52 2002/01/21 16:33:19 rochecompaan +# You can now use the roundup-admin tool to pack the database +# +# Revision 1.51 2002/01/21 03:01:29 richard +# brief docco on the do_journal argument +# +# Revision 1.50 2002/01/19 13:16:04 rochecompaan +# Journal entries for link and multilink properties can now be switched on +# or off. +# +# Revision 1.49 2002/01/16 07:02:57 richard +# . lots of date/interval related changes: +# - more relaxed date format for input +# # Revision 1.48 2002/01/14 06:32:34 richard # . #502951 ] adding new properties to old database #