comparison roundup/backends/back_anydbm.py @ 1780:d2801a2b0a77

Initial implementation (half-baked) at new Tracker instance. Cleaned up caching API / comments in backends. Fixes to docs.
author Richard Jones <richard@users.sourceforge.net>
date Thu, 04 Sep 2003 00:47:01 +0000
parents ab7760caf6ff
children c8614db86be2
comparison
equal deleted inserted replaced
1777:fbe08359511a 1780:d2801a2b0a77
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 # 17 #
18 #$Id: back_anydbm.py,v 1.123 2003-08-26 00:06:55 richard Exp $ 18 #$Id: back_anydbm.py,v 1.124 2003-09-04 00:47:01 richard Exp $
19 ''' 19 '''
20 This module defines a backend that saves the hyperdatabase in a database 20 This module defines a backend that saves the hyperdatabase in a database
21 chosen by anydbm. It is guaranteed to always be available in python 21 chosen by anydbm. It is guaranteed to always be available in python
22 versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several 22 versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
23 serious bugs, and is not available) 23 serious bugs, and is not available)
281 print >>hyperdb.DEBUG, 'savenode', (self, classname, nodeid, node) 281 print >>hyperdb.DEBUG, 'savenode', (self, classname, nodeid, node)
282 self.transactions.append((self.doSaveNode, (classname, nodeid, node))) 282 self.transactions.append((self.doSaveNode, (classname, nodeid, node)))
283 283
284 def getnode(self, classname, nodeid, db=None, cache=1): 284 def getnode(self, classname, nodeid, db=None, cache=1):
285 ''' get a node from the database 285 ''' get a node from the database
286
287 Note the "cache" parameter is not used, and exists purely for
288 backward compatibility!
286 ''' 289 '''
287 if __debug__: 290 if __debug__:
288 print >>hyperdb.DEBUG, 'getnode', (self, classname, nodeid, db) 291 print >>hyperdb.DEBUG, 'getnode', (self, classname, nodeid, db)
289 if cache: 292
290 # try the cache 293 # try the cache
291 cache_dict = self.cache.setdefault(classname, {}) 294 cache_dict = self.cache.setdefault(classname, {})
292 if cache_dict.has_key(nodeid): 295 if cache_dict.has_key(nodeid):
293 if __debug__: 296 if __debug__:
294 print >>hyperdb.TRACE, 'get %s %s cached'%(classname, 297 print >>hyperdb.TRACE, 'get %s %s cached'%(classname,
295 nodeid) 298 nodeid)
296 return cache_dict[nodeid] 299 return cache_dict[nodeid]
297 300
298 if __debug__: 301 if __debug__:
299 print >>hyperdb.TRACE, 'get %s %s'%(classname, nodeid) 302 print >>hyperdb.TRACE, 'get %s %s'%(classname, nodeid)
300 303
301 # get from the database and save in the cache 304 # get from the database and save in the cache
1006 1009
1007 'nodeid' must be the id of an existing node of this class or an 1010 'nodeid' must be the id of an existing node of this class or an
1008 IndexError is raised. 'propname' must be the name of a property 1011 IndexError is raised. 'propname' must be the name of a property
1009 of this class or a KeyError is raised. 1012 of this class or a KeyError is raised.
1010 1013
1011 'cache' indicates whether the transaction cache should be queried 1014 'cache' exists for backward compatibility, and is not used.
1012 for the node. If the node has been modified and you need to
1013 determine what its values prior to modification are, you need to
1014 set cache=0.
1015 1015
1016 Attempts to get the "creation" or "activity" properties should 1016 Attempts to get the "creation" or "activity" properties should
1017 do the right thing. 1017 do the right thing.
1018 ''' 1018 '''
1019 if propname == 'id': 1019 if propname == 'id':
1020 return nodeid 1020 return nodeid
1021 1021
1022 # get the node's dict 1022 # get the node's dict
1023 d = self.db.getnode(self.classname, nodeid, cache=cache) 1023 d = self.db.getnode(self.classname, nodeid)
1024 1024
1025 # check for one of the special props 1025 # check for one of the special props
1026 if propname == 'creation': 1026 if propname == 'creation':
1027 if d.has_key('creation'): 1027 if d.has_key('creation'):
1028 return d['creation'] 1028 return d['creation']
1089 ''' Return a convenience wrapper for the node. 1089 ''' Return a convenience wrapper for the node.
1090 1090
1091 'nodeid' must be the id of an existing node of this class or an 1091 'nodeid' must be the id of an existing node of this class or an
1092 IndexError is raised. 1092 IndexError is raised.
1093 1093
1094 'cache' indicates whether the transaction cache should be queried 1094 'cache' exists for backwards compatibility, and is not used.
1095 for the node. If the node has been modified and you need to 1095 '''
1096 determine what its values prior to modification are, you need to 1096 return Node(self, nodeid)
1097 set cache=0.
1098 '''
1099 return Node(self, nodeid, cache=cache)
1100 1097
1101 def set(self, nodeid, **propvalues): 1098 def set(self, nodeid, **propvalues):
1102 '''Modify a property on an existing node of this class. 1099 '''Modify a property on an existing node of this class.
1103 1100
1104 'nodeid' must be the id of an existing node of this class or an 1101 'nodeid' must be the id of an existing node of this class or an
1132 raise DatabaseError, 'Database open read-only' 1129 raise DatabaseError, 'Database open read-only'
1133 1130
1134 self.fireAuditors('set', nodeid, propvalues) 1131 self.fireAuditors('set', nodeid, propvalues)
1135 # Take a copy of the node dict so that the subsequent set 1132 # Take a copy of the node dict so that the subsequent set
1136 # operation doesn't modify the oldvalues structure. 1133 # operation doesn't modify the oldvalues structure.
1137 try: 1134 oldvalues = copy.deepcopy(self.db.getnode(self.classname, nodeid))
1138 # try not using the cache initially
1139 oldvalues = copy.deepcopy(self.db.getnode(self.classname, nodeid,
1140 cache=0))
1141 except IndexError:
1142 # this will be needed if somone does a create() and set()
1143 # with no intervening commit()
1144 oldvalues = copy.deepcopy(self.db.getnode(self.classname, nodeid))
1145 1135
1146 node = self.db.getnode(self.classname, nodeid) 1136 node = self.db.getnode(self.classname, nodeid)
1147 if node.has_key(self.db.RETIRED_FLAG): 1137 if node.has_key(self.db.RETIRED_FLAG):
1148 raise IndexError 1138 raise IndexError
1149 num_re = re.compile('^\d+$') 1139 num_re = re.compile('^\d+$')
2038 # save off the "content" file 2028 # save off the "content" file
2039 self.db.storefile(self.classname, newid, None, content) 2029 self.db.storefile(self.classname, newid, None, content)
2040 return newid 2030 return newid
2041 2031
2042 def get(self, nodeid, propname, default=_marker, cache=1): 2032 def get(self, nodeid, propname, default=_marker, cache=1):
2043 ''' trap the content propname and get it from the file 2033 ''' Trap the content propname and get it from the file
2034
2035 'cache' exists for backwards compatibility, and is not used.
2044 ''' 2036 '''
2045 poss_msg = 'Possibly an access right configuration problem.' 2037 poss_msg = 'Possibly an access right configuration problem.'
2046 if propname == 'content': 2038 if propname == 'content':
2047 try: 2039 try:
2048 return self.db.getfile(self.classname, nodeid, None) 2040 return self.db.getfile(self.classname, nodeid, None)
2049 except IOError, (strerror): 2041 except IOError, (strerror):
2050 # XXX by catching this we donot see an error in the log. 2042 # XXX by catching this we donot see an error in the log.
2051 return 'ERROR reading file: %s%s\n%s\n%s'%( 2043 return 'ERROR reading file: %s%s\n%s\n%s'%(
2052 self.classname, nodeid, poss_msg, strerror) 2044 self.classname, nodeid, poss_msg, strerror)
2053 if default is not _marker: 2045 if default is not _marker:
2054 return Class.get(self, nodeid, propname, default, cache=cache) 2046 return Class.get(self, nodeid, propname, default)
2055 else: 2047 else:
2056 return Class.get(self, nodeid, propname, cache=cache) 2048 return Class.get(self, nodeid, propname)
2057 2049
2058 def getprops(self, protected=1): 2050 def getprops(self, protected=1):
2059 ''' In addition to the actual properties on the node, these methods 2051 ''' In addition to the actual properties on the node, these methods
2060 provide the "content" property. If the "protected" flag is true, 2052 provide the "content" property. If the "protected" flag is true,
2061 we include protected properties - those which may not be 2053 we include protected properties - those which may not be

Roundup Issue Tracker: http://roundup-tracker.org/