Skip to content

Commit 36476a0

Browse files
author
Richard Jones
committed
Moved the backends into the backends package. Anydbm hasn't been tested at all.
1 parent 6603280 commit 36476a0

File tree

2 files changed

+178
-3
lines changed

2 files changed

+178
-3
lines changed

roundup/backends/_anydbm.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#$Id: _anydbm.py,v 1.1 2001-07-23 07:15:57 richard Exp $
2+
3+
import anydbm, os, cPickle
4+
from roundup import hyperdb, date
5+
6+
#
7+
# Now the database
8+
#
9+
class Database(hyperdb.Database):
10+
"""A database for storing records containing flexible data types."""
11+
12+
def __init__(self, storagelocator, journaltag=None):
13+
"""Open a hyperdatabase given a specifier to some storage.
14+
15+
The meaning of 'storagelocator' depends on the particular
16+
implementation of the hyperdatabase. It could be a file name,
17+
a directory path, a socket descriptor for a connection to a
18+
database over the network, etc.
19+
20+
The 'journaltag' is a token that will be attached to the journal
21+
entries for any edits done on the database. If 'journaltag' is
22+
None, the database is opened in read-only mode: the Class.create(),
23+
Class.set(), and Class.retire() methods are disabled.
24+
"""
25+
self.dir, self.journaltag = storagelocator, journaltag
26+
self.classes = {}
27+
28+
#
29+
# Classes
30+
#
31+
def __getattr__(self, classname):
32+
"""A convenient way of calling self.getclass(classname)."""
33+
return self.classes[classname]
34+
35+
def addclass(self, cl):
36+
cn = cl.classname
37+
if self.classes.has_key(cn):
38+
raise ValueError, cn
39+
self.classes[cn] = cl
40+
41+
def getclasses(self):
42+
"""Return a list of the names of all existing classes."""
43+
l = self.classes.keys()
44+
l.sort()
45+
return l
46+
47+
def getclass(self, classname):
48+
"""Get the Class object representing a particular class.
49+
50+
If 'classname' is not a valid class name, a KeyError is raised.
51+
"""
52+
return self.classes[classname]
53+
54+
#
55+
# Class DBs
56+
#
57+
def clear(self):
58+
for cn in self.classes.keys():
59+
db = os.path.join(self.dir, 'nodes.%s'%cn)
60+
anydbm.open(db, 'n')
61+
db = os.path.join(self.dir, 'journals.%s'%cn)
62+
anydbm.open(db, 'n')
63+
64+
def getclassdb(self, classname, mode='r'):
65+
''' grab a connection to the class db that will be used for
66+
multiple actions
67+
'''
68+
path = os.path.join(os.getcwd(), self.dir, 'nodes.%s'%classname)
69+
return anydbm.open(path, mode)
70+
71+
def addnode(self, classname, nodeid, node):
72+
''' add the specified node to its class's db
73+
'''
74+
db = self.getclassdb(classname, 'c')
75+
db[nodeid] = cPickle.dumps(node, 1)
76+
db.close()
77+
setnode = addnode
78+
79+
def getnode(self, classname, nodeid, cldb=None):
80+
''' add the specified node to its class's db
81+
'''
82+
db = cldb or self.getclassdb(classname)
83+
if not db.has_key(nodeid):
84+
raise IndexError, nodeid
85+
res = cPickle.loads(db[nodeid])
86+
if not cldb: db.close()
87+
return res
88+
89+
def hasnode(self, classname, nodeid, cldb=None):
90+
''' add the specified node to its class's db
91+
'''
92+
db = cldb or self.getclassdb(classname)
93+
res = db.has_key(nodeid)
94+
if not cldb: db.close()
95+
return res
96+
97+
def countnodes(self, classname, cldb=None):
98+
db = cldb or self.getclassdb(classname)
99+
return len(db.keys())
100+
if not cldb: db.close()
101+
return res
102+
103+
def getnodeids(self, classname, cldb=None):
104+
db = cldb or self.getclassdb(classname)
105+
res = db.keys()
106+
if not cldb: db.close()
107+
return res
108+
109+
#
110+
# Journal
111+
#
112+
def addjournal(self, classname, nodeid, action, params):
113+
''' Journal the Action
114+
'action' may be:
115+
116+
'create' or 'set' -- 'params' is a dictionary of property values
117+
'link' or 'unlink' -- 'params' is (classname, nodeid, propname)
118+
'retire' -- 'params' is None
119+
'''
120+
entry = (nodeid, date.Date(), self.journaltag, action, params)
121+
db = anydbm.open(os.path.join(self.dir, 'journals.%s'%classname), 'c')
122+
if db.has_key(nodeid):
123+
s = db[nodeid]
124+
l = cPickle.loads(db[nodeid])
125+
l.append(entry)
126+
else:
127+
l = [entry]
128+
db[nodeid] = cPickle.dumps(l)
129+
db.close()
130+
131+
def getjournal(self, classname, nodeid):
132+
''' get the journal for id
133+
'''
134+
db = anydbm.open(os.path.join(self.dir, 'journals.%s'%classname), 'r')
135+
res = cPickle.loads(db[nodeid])
136+
db.close()
137+
return res
138+
139+
def close(self):
140+
''' Close the Database - we must release the circular refs so that
141+
we can be del'ed and the underlying anydbm connections closed
142+
cleanly.
143+
'''
144+
self.classes = None
145+
146+
147+
#
148+
# Basic transaction support
149+
#
150+
# TODO: well, write these methods (and then use them in other code)
151+
def register_action(self):
152+
''' Register an action to the transaction undo log
153+
'''
154+
155+
def commit(self):
156+
''' Commit the current transaction, start a new one
157+
'''
158+
159+
def rollback(self):
160+
''' Reverse all actions from the current transaction
161+
'''
162+
163+
#
164+
#$Log: not supported by cvs2svn $
165+
#
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#$Id: bsddb.py,v 1.1 2001-07-23 06:23:41 richard Exp $
1+
#$Id: _bsddb.py,v 1.1 2001-07-23 07:15:57 richard Exp $
22

33
import bsddb, os, cPickle
4-
import hyperdb, date
4+
from roundup import hyperdb, date
55

66
#
77
# Now the database
@@ -131,7 +131,14 @@ def addjournal(self, classname, nodeid, action, params):
131131
def getjournal(self, classname, nodeid):
132132
''' get the journal for id
133133
'''
134-
db = bsddb.btopen(os.path.join(self.dir, 'journals.%s'%classname), 'r')
134+
# attempt to open the journal - in some rare cases, the journal may
135+
# not exist
136+
try:
137+
db = bsddb.btopen(os.path.join(self.dir, 'journals.%s'%classname),
138+
'r')
139+
except bsddb.error, error:
140+
if error.args[0] != 2: raise
141+
return []
135142
res = cPickle.loads(db[nodeid])
136143
db.close()
137144
return res
@@ -162,6 +169,9 @@ def rollback(self):
162169

163170
#
164171
#$Log: not supported by cvs2svn $
172+
#Revision 1.1 2001/07/23 06:23:41 richard
173+
#moved hyper_bsddb.py to the new backends package as bsddb.py
174+
#
165175
#Revision 1.2 2001/07/22 12:09:32 richard
166176
#Final commit of Grande Splite
167177
#

0 commit comments

Comments
 (0)