index 7091d19bd218995e1bd78a529f6c06b49bb207eb..6fb115d5ae1da2555e7cec64177affc3060259cf 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_anydbm.py,v 1.138 2004-03-18 01:58:45 richard Exp $
+#$Id: back_anydbm.py,v 1.139 2004-03-19 04:47:59 richard Exp $
'''This module defines a backend that saves the hyperdatabase in a
database chosen by anydbm. It is guaranteed to always be available in python
versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
from roundup import hyperdb, date, password, roundupdb, security
from blobfiles import FileStorage
from sessions_dbm import Sessions, OneTimeKeys
-from roundup.indexer import Indexer
+from indexer_dbm import Indexer
from roundup.backends import locking
from roundup.hyperdb import String, Password, Date, Interval, Link, \
Multilink, DatabaseError, Boolean, Number, Node
elif isinstance(prop, String):
if type(value) != type('') and type(value) != type(u''):
raise TypeError, 'new property "%s" not a string'%key
+ self.db.indexer.add_text((self.classname, newid, key), value)
elif isinstance(prop, Password):
if not isinstance(value, password.Password):
These operations trigger detectors and can be vetoed. Attempts
to modify the "creation" or "activity" properties cause a KeyError.
'''
+ self.fireAuditors('set', nodeid, propvalues)
+ oldvalues = copy.deepcopy(self.db.getnode(self.classname, nodeid))
+ propvalues = self.set_inner(nodeid, **propvalues)
+ self.fireReactors('set', nodeid, oldvalues)
+ return propvalues
+
+ def set_inner(self, nodeid, **propvalues):
+ ''' Called by set, in-between the audit and react calls.
+ '''
if not propvalues:
return propvalues
if self.db.journaltag is None:
raise DatabaseError, 'Database open read-only'
- self.fireAuditors('set', nodeid, propvalues)
- # Take a copy of the node dict so that the subsequent set
- # operation doesn't modify the oldvalues structure.
- oldvalues = copy.deepcopy(self.db.getnode(self.classname, nodeid))
-
node = self.db.getnode(self.classname, nodeid)
if node.has_key(self.db.RETIRED_FLAG):
raise IndexError
elif isinstance(prop, String):
if value is not None and type(value) != type('') and type(value) != type(u''):
raise TypeError, 'new property "%s" not a string'%propname
+ self.db.indexer.add_text((self.classname, nodeid, propname),
+ value)
elif isinstance(prop, Password):
if not isinstance(value, password.Password):
if self.do_journal:
self.db.addjournal(self.classname, nodeid, 'set', journalvalues)
- self.fireReactors('set', nodeid, oldvalues)
-
- return propvalues
+ return propvalues
def retire(self, nodeid):
'''Retire a node.
self.properties.update(properties)
def index(self, nodeid):
- '''Add (or refresh) the node to search indexes
- '''
+ ''' Add (or refresh) the node to search indexes '''
# find all the String properties that have indexme
for prop, propclass in self.getprops().items():
- if isinstance(propclass, String) and propclass.indexme:
+ if isinstance(propclass, hyperdb.String) and propclass.indexme:
+ # index them under (classname, nodeid, property)
try:
value = str(self.get(nodeid, prop))
except IndexError:
- # node no longer exists - entry should be removed
- self.db.indexer.purge_entry((self.classname, nodeid, prop))
- else:
- # and index them under (classname, nodeid, property)
- self.db.indexer.add_text((self.classname, nodeid, prop),
- value)
+ # node has been destroyed
+ continue
+ self.db.indexer.add_text((self.classname, nodeid, prop), value)
+
#
# Detector interface
content = propvalues['content']
del propvalues['content']
+ # make sure we have a MIME type
+ mime_type = propvalues.get('type', self.default_mime_type)
+
# do the database create
- newid = Class.create_inner(self, **propvalues)
+ newid = self.create_inner(**propvalues)
+
+ # and index!
+ self.db.indexer.add_text((self.classname, newid, 'content'), content,
+ mime_type)
# fire reactors
self.fireReactors('create', newid, None)
else:
return Class.get(self, nodeid, propname)
+ def set(self, itemid, **propvalues):
+ ''' Snarf the "content" propvalue and update it in a file
+ '''
+ self.fireAuditors('set', itemid, propvalues)
+ oldvalues = copy.deepcopy(self.db.getnode(self.classname, itemid))
+
+ # now remove the content property so it's not stored in the db
+ content = None
+ if propvalues.has_key('content'):
+ content = propvalues['content']
+ del propvalues['content']
+
+ # do the database create
+ propvalues = self.set_inner(itemid, **propvalues)
+
+ # do content?
+ if content:
+ # store and index
+ self.db.storefile(self.classname, itemid, None, content)
+ mime_type = propvalues.get('type', self.get(itemid, 'type'))
+ if not mime_type:
+ mime_type = self.default_mime_type
+ self.db.indexer.add_text((self.classname, itemid, 'content'),
+ content, mime_type)
+
+ # fire reactors
+ self.fireReactors('set', itemid, oldvalues)
+ return propvalues
+
def getprops(self, protected=1):
''' In addition to the actual properties on the node, these methods
provide the "content" property. If the "protected" flag is true,
d['content'] = hyperdb.String()
return d
- def index(self, nodeid):
- ''' Index the node in the search index.
-
- We want to index the content in addition to the normal String
- property indexing.
- '''
- # perform normal indexing
- Class.index(self, nodeid)
-
- # get the content to index
- content = self.get(nodeid, 'content')
-
- # figure the mime type
- if self.properties.has_key('type'):
- mime_type = self.get(nodeid, 'type')
- else:
- mime_type = self.default_mime_type
-
- # and index!
- self.db.indexer.add_text((self.classname, nodeid, 'content'), content,
- mime_type)
# deviation from spec - was called ItemClass
class IssueClass(Class, roundupdb.IssueClass):