summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4d8d40c)
raw | patch | inline | side by side (parent: 4d8d40c)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 29 Jul 2002 00:27:36 +0000 (00:27 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 29 Jul 2002 00:27:36 +0000 (00:27 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@922 57a73879-2fb5-44c3-a270-3262357dd7e2
roundup/volatiledb.py | [deleted file] | patch | blob | history |
diff --git a/roundup/volatiledb.py b/roundup/volatiledb.py
--- a/roundup/volatiledb.py
+++ /dev/null
@@ -1,324 +0,0 @@
-import weakref, re
-
-from roundup import hyperdb
-from roundup.hyperdb import String, Password, Date, Interval, Link, \
- Multilink, DatabaseError, Boolean, Number
-
-class VolatileClass(hyperdb.Class):
- ''' This is a class that just sits in memory, no saving to disk.
- It has no journal.
- '''
- def __init__(self, db, classname, **properties):
- ''' Set up an in-memory store for the nodes of this class
- '''
- self.db = weakref.proxy(db) # use a weak ref to avoid circularity
- self.classname = classname
- self.properties = properties
- self.id_counter = 1
- self.store = {}
- self.by_key = {}
- self.key = ''
- db.addclass(self)
-
- def setkey(self, propname):
- prop = self.getprops()[propname]
- if not isinstance(prop, String):
- raise TypeError, 'key properties must be String'
- self.key = propname
-
- def getprops(self, protected=1):
- d = self.properties.copy()
- if protected:
- d['id'] = String()
- return d
-
- def create(self, **propvalues):
- ''' Create a new node in the in-memory store
- '''
- if propvalues.has_key('id'):
- raise KeyError, '"id" is reserved'
- newid = str(self.id_counter)
- self.id_counter += 1
-
- # get the key value, validate it
- if self.key:
- keyvalue = propvalues[self.key]
- try:
- self.lookup(keyvalue)
- except KeyError:
- pass
- else:
- raise ValueError, 'node with key "%s" exists'%keyvalue
- self.by_key[keyvalue] = newid
-
- # validate propvalues
- num_re = re.compile('^\d+$')
-
- for key, value in propvalues.items():
-
- # try to handle this property
- try:
- prop = self.properties[key]
- except KeyError:
- raise KeyError, '"%s" has no property "%s"'%(self.classname,
- key)
-
- if isinstance(prop, Link):
- if type(value) != type(''):
- raise ValueError, 'link value must be String'
- link_class = self.properties[key].classname
- # if it isn't a number, it's a key
- if not num_re.match(value):
- try:
- value = self.db.classes[link_class].lookup(value)
- except (TypeError, KeyError):
- raise IndexError, 'new property "%s": %s not a %s'%(
- key, value, link_class)
- elif not self.db.hasnode(link_class, value):
- raise IndexError, '%s has no node %s'%(link_class, value)
-
- # save off the value
- propvalues[key] = value
-
- elif isinstance(prop, Multilink):
- if type(value) != type([]):
- raise TypeError, 'new property "%s" not a list of ids'%key
-
- # clean up and validate the list of links
- link_class = self.properties[key].classname
- l = []
- for entry in value:
- if type(entry) != type(''):
- raise ValueError, '"%s" link value (%s) must be '\
- 'String'%(key, value)
- # if it isn't a number, it's a key
- if not num_re.match(entry):
- try:
- entry = self.db.classes[link_class].lookup(entry)
- except (TypeError, KeyError):
- raise IndexError, 'new property "%s": %s not a %s'%(
- key, entry, self.properties[key].classname)
- l.append(entry)
- value = l
- propvalues[key] = value
-
- # handle additions
- for id in value:
- if not self.db.hasnode(link_class, id):
- raise IndexError, '%s has no node %s'%(link_class, id)
-
- elif isinstance(prop, String):
- if type(value) != type(''):
- raise TypeError, 'new property "%s" not a string'%key
-
- elif isinstance(prop, Password):
- if not isinstance(value, password.Password):
- raise TypeError, 'new property "%s" not a Password'%key
-
- elif isinstance(prop, Date):
- if value is not None and not isinstance(value, date.Date):
- raise TypeError, 'new property "%s" not a Date'%key
-
- elif isinstance(prop, Interval):
- if value is not None and not isinstance(value, date.Interval):
- raise TypeError, 'new property "%s" not an Interval'%key
-
- # make sure there's data where there needs to be
- for key, prop in self.properties.items():
- if propvalues.has_key(key):
- continue
- if key == self.key:
- raise ValueError, 'key property "%s" is required'%key
- if isinstance(prop, Multilink):
- propvalues[key] = []
- else:
- propvalues[key] = None
-
- # done
- self.store[newid] = propvalues
-
- return newid
-
- _marker = []
- def get(self, nodeid, propname, default=_marker, cache=1):
- ''' Get the node from the in-memory store
- '''
- if propname == 'id':
- return nodeid
- return self.store[nodeid][propname]
-
- def set(self, nodeid, **propvalues):
- ''' Set properties on the node in the in-memory store
- '''
- if not propvalues:
- return
-
- if propvalues.has_key('id'):
- raise KeyError, '"id" is reserved'
-
- node = self.store[nodeid]
- num_re = re.compile('^\d+$')
-
- for propname, value in propvalues.items():
- # check to make sure we're not duplicating an existing key
- if propname == self.key and node[propname] != value:
- try:
- self.lookup(value)
- except KeyError:
- pass
- else:
- raise ValueError, 'node with key "%s" exists'%value
-
- # 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]
-
- # if the value's the same as the existing value, no sense in
- # doing anything
- if node.has_key(propname) and value == node[propname]:
- del propvalues[propname]
- continue
-
- # do stuff based on the prop type
- if isinstance(prop, Link):
- link_class = self.properties[propname].classname
- # if it isn't a number, it's a key
- if type(value) != type(''):
- raise ValueError, 'link value must be String'
- if not num_re.match(value):
- try:
- value = self.db.classes[link_class].lookup(value)
- except (TypeError, KeyError):
- raise IndexError, 'new property "%s": %s not a %s'%(
- propname, value, self.properties[propname].classname)
-
- if not self.db.hasnode(link_class, value):
- raise IndexError, '%s has no node %s'%(link_class, value)
-
- elif isinstance(prop, Multilink):
- if type(value) != type([]):
- raise TypeError, 'new property "%s" not a list of'\
- ' ids'%propname
- link_class = self.properties[propname].classname
- l = []
- for entry in value:
- # if it isn't a number, it's a key
- if type(entry) != type(''):
- raise ValueError, 'new property "%s" link value ' \
- 'must be a string'%propname
- if not num_re.match(entry):
- try:
- entry = self.db.classes[link_class].lookup(entry)
- except (TypeError, KeyError):
- raise IndexError, 'new property "%s": %s not a %s'%(
- propname, entry,
- self.properties[propname].classname)
- l.append(entry)
- value = l
- propvalues[propname] = value
-
- elif isinstance(prop, String):
- if value is not None and type(value) != type(''):
- raise TypeError, 'new property "%s" not a string'%propname
-
- elif isinstance(prop, Password):
- if not isinstance(value, password.Password):
- raise TypeError, 'new property "%s" not a Password'%propname
- propvalues[propname] = value
-
- elif value is not None and isinstance(prop, Date):
- if not isinstance(value, date.Date):
- raise TypeError, 'new property "%s" not a Date'% propname
- propvalues[propname] = value
-
- elif value is not None and isinstance(prop, Interval):
- if not isinstance(value, date.Interval):
- raise TypeError, 'new property "%s" not an '\
- 'Interval'%propname
- propvalues[propname] = value
-
- elif value is not None and isinstance(prop, Number):
- try:
- float(value)
- except ValueError:
- raise TypeError, 'new property "%s" not numeric'%propname
-
- elif value is not None and isinstance(prop, Boolean):
- try:
- int(value)
- except ValueError:
- raise TypeError, 'new property "%s" not boolean'%propname
-
- node[propname] = value
-
- # do the set
- self.store[nodeid] = node
-
- def lookup(self, keyvalue):
- ''' look up the key node in the store
- '''
- return self.by_key[keyvalue]
-
- def hasnode(self, nodeid):
- nodeid = str(nodeid)
- return self.store.has_key(nodeid)
-
- def list(self):
- l = self.store.keys()
- l.sort()
- return l
-
- def index(self, nodeid):
- pass
-
- def stringFind(self, **requirements):
- """Locate a particular node by matching a set of its String
- properties in a caseless search.
-
- If the property is not a String property, a TypeError is raised.
-
- The return is a list of the id of all nodes that match.
- """
- for propname in requirements.keys():
- prop = self.properties[propname]
- if isinstance(not prop, String):
- raise TypeError, "'%s' not a String property"%propname
- requirements[propname] = requirements[propname].lower()
- l = []
- for nodeid, node in self.store.items():
- for key, value in requirements.items():
- if node[key] and node[key].lower() != value:
- break
- else:
- l.append(nodeid)
- return l
-
- def getkey(self):
- """Return the name of the key property for this class or None."""
- return self.key
-
- def labelprop(self, default_to_id=0):
- ''' Return the property name for a label for the given node.
-
- This method attempts to generate a consistent label for the node.
- It tries the following in order:
- 1. key property
- 2. "name" property
- 3. "title" property
- 4. first property from the sorted property name list
- '''
- k = self.getkey()
- if k:
- return k
- props = self.getprops()
- if props.has_key('name'):
- return 'name'
- elif props.has_key('title'):
- return 'title'
- if default_to_id:
- return 'id'
- props = props.keys()
- props.sort()
- return props[0]
-