Skip to content

Commit 7787330

Browse files
author
Richard Jones
committed
Storing only marshallable data in the db - no nasty pickled class references.
1 parent 4c3862e commit 7787330

File tree

2 files changed

+61
-15
lines changed

2 files changed

+61
-15
lines changed

roundup/backends/back_bsddb.py

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
#$Id: back_bsddb.py,v 1.1 2001-07-23 07:22:13 richard Exp $
1+
#$Id: back_bsddb.py,v 1.2 2001-07-23 07:56:05 richard Exp $
22

3-
import bsddb, os, cPickle
3+
import bsddb, os, marshal
4+
# handle the older cPickle'd data
5+
import cPickle
46
from roundup import hyperdb, date
57

68
#
@@ -68,11 +70,21 @@ def getclassdb(self, classname, mode='r'):
6870
path = os.path.join(os.getcwd(), self.dir, 'nodes.%s'%classname)
6971
return bsddb.btopen(path, mode)
7072

73+
#
74+
# Nodes
75+
#
7176
def addnode(self, classname, nodeid, node):
7277
''' add the specified node to its class's db
7378
'''
7479
db = self.getclassdb(classname, 'c')
75-
db[nodeid] = cPickle.dumps(node, 1)
80+
# convert the instance data to builtin types
81+
properties = self.classes[classname].properties
82+
for key in res.keys():
83+
if properties[key].isDateType:
84+
res[key] = res[key].get_tuple()
85+
elif properties[key].isIntervalType:
86+
res[key] = res[key].get_tuple()
87+
db[nodeid] = marshal.dumps(node, 1)
7688
db.close()
7789
setnode = addnode
7890

@@ -82,7 +94,21 @@ def getnode(self, classname, nodeid, cldb=None):
8294
db = cldb or self.getclassdb(classname)
8395
if not db.has_key(nodeid):
8496
raise IndexError, nodeid
85-
res = cPickle.loads(db[nodeid])
97+
try:
98+
res = marshal.loads(db[nodeid])
99+
# convert the marshalled data to instances
100+
properties = self.classes[classname].properties
101+
for key in res.keys():
102+
if properties[key].isDateType:
103+
res[key] = date.Date(res[key])
104+
elif properties[key].isIntervalType:
105+
res[key] = date.Interval(res[key])
106+
except ValueError, message:
107+
if str(message) != 'bad marshal data':
108+
raise
109+
# handle the older cPickle'd data
110+
res = cPickle.loads(db[nodeid])
111+
86112
if not cldb: db.close()
87113
return res
88114

@@ -117,15 +143,16 @@ def addjournal(self, classname, nodeid, action, params):
117143
'link' or 'unlink' -- 'params' is (classname, nodeid, propname)
118144
'retire' -- 'params' is None
119145
'''
120-
entry = (nodeid, date.Date(), self.journaltag, action, params)
146+
entry = (nodeid, date.Date().journal_tuple(), self.journaltag, action,
147+
params)
121148
db = bsddb.btopen(os.path.join(self.dir, 'journals.%s'%classname), 'c')
122149
if db.has_key(nodeid):
123150
s = db[nodeid]
124-
l = cPickle.loads(db[nodeid])
151+
l = marshal.loads(db[nodeid])
125152
l.append(entry)
126153
else:
127154
l = [entry]
128-
db[nodeid] = cPickle.dumps(l)
155+
db[nodeid] = marshal.dumps(l)
129156
db.close()
130157

131158
def getjournal(self, classname, nodeid):
@@ -139,7 +166,12 @@ def getjournal(self, classname, nodeid):
139166
except bsddb.error, error:
140167
if error.args[0] != 2: raise
141168
return []
142-
res = cPickle.loads(db[nodeid])
169+
journal = marshal.loads(db[nodeid])
170+
res = []
171+
for entry in journal:
172+
(nodeid, date_stamp, self.journaltag, action, params) = entry
173+
date_obj = date.Date(set=date_stamp)
174+
res.append((nodeid, date_obj, self.journaltag, action, params))
143175
db.close()
144176
return res
145177

@@ -169,6 +201,10 @@ def rollback(self):
169201

170202
#
171203
#$Log: not supported by cvs2svn $
204+
#Revision 1.1 2001/07/23 07:22:13 richard
205+
#*sigh* some databases have _foo.so as their underlying implementation.
206+
#This time for sure, Rocky.
207+
#
172208
#Revision 1.1 2001/07/23 07:15:57 richard
173209
#Moved the backends into the backends package. Anydbm hasn't been tested at all.
174210
#

roundup/date.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: date.py,v 1.2 2001-07-22 12:09:32 richard Exp $
1+
# $Id: date.py,v 1.3 2001-07-23 07:56:05 richard Exp $
22

33
import time, re, calendar
44

@@ -56,18 +56,18 @@ class Date:
5656
'''
5757
isDate = 1
5858

59-
def __init__(self, spec='.', offset=0, set=None):
59+
def __init__(self, spec='.', offset=0):
6060
"""Construct a date given a specification and a time zone offset.
6161
6262
'spec' is a full date or a partial form, with an optional
63-
added or subtracted interval.
63+
added or subtracted interval. Or a date 9-tuple.
6464
'offset' is the local time zone offset from GMT in hours.
6565
"""
66-
if set is None:
66+
if type(spec) == type(''):
6767
self.set(spec, offset=offset)
6868
else:
6969
self.year, self.month, self.day, self.hour, self.minute, \
70-
self.second, x, x, x = set
70+
self.second, x, x, x = spec
7171
self.offset = offset
7272

7373
def applyInterval(self, interval):
@@ -90,7 +90,7 @@ def __add__(self, other):
9090
self.hour + other.sign * other.hour,
9191
self.minute + other.sign * other.minute,
9292
self.second + other.sign * other.second, 0, 0, 0)
93-
return Date(set = time.gmtime(calendar.timegm(t)))
93+
return Date(time.gmtime(calendar.timegm(t)))
9494

9595
# XXX deviates from spec to allow subtraction of dates as well
9696
def __sub__(self, other):
@@ -128,7 +128,7 @@ def __sub__(self, other):
128128
self.hour - other.sign * other.hour,
129129
self.minute - other.sign * other.minute,
130130
self.second - other.sign * other.second, 0, 0, 0)
131-
return Date(set = time.gmtime(calendar.timegm(t)))
131+
return Date(time.gmtime(calendar.timegm(t)))
132132

133133
def __cmp__(self, other):
134134
"""Compare this date to another date."""
@@ -193,6 +193,9 @@ def local(self, offset):
193193
self.year, self.month, self.day, self.hour, self.minute, \
194194
self.second, x, x, x = time.gmtime(calendar.timegm(t))
195195

196+
def get_tuple(self):
197+
return (self.year, self.month, self.day, self.hour, self.minute,
198+
self.second, 0, 0, 0)
196199

197200
class Interval:
198201
'''
@@ -321,6 +324,10 @@ def pretty(self, threshold=('d', 5)):
321324
return '1/2 an hour'
322325
return '%s/4 hour'%quart
323326

327+
def get_tuple(self):
328+
return (self.year, self.month, self.day, self.hour, self.minute,
329+
self.second)
330+
324331

325332
def test():
326333
intervals = (" 3w 1 d 2:00", " + 2d", "3w")
@@ -344,6 +351,9 @@ def test():
344351

345352
#
346353
# $Log: not supported by cvs2svn $
354+
# Revision 1.2 2001/07/22 12:09:32 richard
355+
# Final commit of Grande Splite
356+
#
347357
# Revision 1.1 2001/07/22 11:58:35 richard
348358
# More Grande Splite
349359
#

0 commit comments

Comments
 (0)