Skip to content

Commit c8ee937

Browse files
author
Richard Jones
committed
Implemented a switch to disable journalling for a Class.
CGI session database now uses it.
1 parent 03edfdf commit c8ee937

File tree

4 files changed

+96
-29
lines changed

4 files changed

+96
-29
lines changed

roundup/backends/back_anydbm.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.44 2002-07-14 02:05:53 richard Exp $
18+
#$Id: back_anydbm.py,v 1.45 2002-07-14 04:03:14 richard Exp $
1919
'''
2020
This module defines a backend that saves the hyperdatabase in a database
2121
chosen by anydbm. It is guaranteed to always be available in python
@@ -589,16 +589,24 @@ def __init__(self, db, classname, **properties):
589589
self.db = weakref.proxy(db) # use a weak ref to avoid circularity
590590
self.key = ''
591591

592+
# should we journal changes (default yes)
593+
self.do_journal = 1
594+
592595
# do the db-related init stuff
593596
db.addclass(self)
594597

595598
self.auditors = {'create': [], 'set': [], 'retire': []}
596599
self.reactors = {'create': [], 'set': [], 'retire': []}
597600

598-
def __repr__(self):
599-
'''Slightly more useful representation
601+
def enableJournalling(self):
602+
'''Turn journalling on for this class
600603
'''
601-
return '<hypderdb.Class "%s">'%self.classname
604+
self.do_journal = 1
605+
606+
def disableJournalling(self):
607+
'''Turn journalling off for this class
608+
'''
609+
self.do_journal = 0
602610

603611
# Editing nodes:
604612

@@ -672,7 +680,7 @@ def create(self, **propvalues):
672680
propvalues[key] = value
673681

674682
# register the link with the newly linked node
675-
if self.properties[key].do_journal:
683+
if self.do_journal and self.properties[key].do_journal:
676684
self.db.addjournal(link_class, value, 'link',
677685
(self.classname, newid, key))
678686

@@ -703,7 +711,7 @@ def create(self, **propvalues):
703711
if not self.db.hasnode(link_class, id):
704712
raise IndexError, '%s has no node %s'%(link_class, id)
705713
# register the link with the newly linked node
706-
if self.properties[key].do_journal:
714+
if self.do_journal and self.properties[key].do_journal:
707715
self.db.addjournal(link_class, id, 'link',
708716
(self.classname, newid, key))
709717

@@ -737,7 +745,8 @@ def create(self, **propvalues):
737745

738746
# done
739747
self.db.addnode(self.classname, newid, propvalues)
740-
self.db.addjournal(self.classname, newid, 'create', propvalues)
748+
if self.do_journal:
749+
self.db.addjournal(self.classname, newid, 'create', propvalues)
741750

742751
self.fireReactors('create', newid, None)
743752

@@ -762,20 +771,26 @@ def get(self, nodeid, propname, default=_marker, cache=1):
762771
return nodeid
763772

764773
if propname == 'creation':
774+
if not self.do_journal:
775+
raise ValueError, 'Journalling is disabled for this class'
765776
journal = self.db.getjournal(self.classname, nodeid)
766777
if journal:
767778
return self.db.getjournal(self.classname, nodeid)[0][1]
768779
else:
769780
# on the strange chance that there's no journal
770781
return date.Date()
771782
if propname == 'activity':
783+
if not self.do_journal:
784+
raise ValueError, 'Journalling is disabled for this class'
772785
journal = self.db.getjournal(self.classname, nodeid)
773786
if journal:
774787
return self.db.getjournal(self.classname, nodeid)[-1][1]
775788
else:
776789
# on the strange chance that there's no journal
777790
return date.Date()
778791
if propname == 'creator':
792+
if not self.do_journal:
793+
raise ValueError, 'Journalling is disabled for this class'
779794
journal = self.db.getjournal(self.classname, nodeid)
780795
if journal:
781796
name = self.db.getjournal(self.classname, nodeid)[0][2]
@@ -901,7 +916,7 @@ class or a KeyError is raised.
901916
if not self.db.hasnode(link_class, value):
902917
raise IndexError, '%s has no node %s'%(link_class, value)
903918

904-
if self.properties[key].do_journal:
919+
if self.do_journal and self.properties[key].do_journal:
905920
# register the unlink with the old linked node
906921
if node[key] is not None:
907922
self.db.addjournal(link_class, node[key], 'unlink',
@@ -941,7 +956,7 @@ class or a KeyError is raised.
941956
if id in value:
942957
continue
943958
# register the unlink with the old linked node
944-
if self.properties[key].do_journal:
959+
if self.do_journal and self.properties[key].do_journal:
945960
self.db.addjournal(link_class, id, 'unlink',
946961
(self.classname, nodeid, key))
947962
l.remove(id)
@@ -954,7 +969,7 @@ class or a KeyError is raised.
954969
if id in l:
955970
continue
956971
# register the link with the newly linked node
957-
if self.properties[key].do_journal:
972+
if self.do_journal and self.properties[key].do_journal:
958973
self.db.addjournal(link_class, id, 'link',
959974
(self.classname, nodeid, key))
960975
l.append(id)
@@ -986,7 +1001,8 @@ class or a KeyError is raised.
9861001

9871002
# do the set, and journal it
9881003
self.db.setnode(self.classname, nodeid, node)
989-
self.db.addjournal(self.classname, nodeid, 'set', propvalues)
1004+
if self.do_journal:
1005+
self.db.addjournal(self.classname, nodeid, 'set', propvalues)
9901006

9911007
self.fireReactors('set', nodeid, oldvalues)
9921008

@@ -1010,7 +1026,8 @@ def retire(self, nodeid):
10101026
node = self.db.getnode(self.classname, nodeid)
10111027
node[self.db.RETIRED_FLAG] = 1
10121028
self.db.setnode(self.classname, nodeid, node)
1013-
self.db.addjournal(self.classname, nodeid, 'retired', None)
1029+
if self.do_journal:
1030+
self.db.addjournal(self.classname, nodeid, 'retired', None)
10141031

10151032
self.fireReactors('retire', nodeid, None)
10161033

@@ -1027,6 +1044,8 @@ def history(self, nodeid):
10271044
'date' is a Timestamp object specifying the time of the change and
10281045
'tag' is the journaltag specified when the database was opened.
10291046
"""
1047+
if not self.do_journal:
1048+
raise ValueError, 'Journalling is disabled for this class'
10301049
return self.db.getjournal(self.classname, nodeid)
10311050

10321051
# Locating nodes:
@@ -1596,6 +1615,9 @@ def __init__(self, db, classname, **properties):
15961615

15971616
#
15981617
#$Log: not supported by cvs2svn $
1618+
#Revision 1.44 2002/07/14 02:05:53 richard
1619+
#. all storage-specific code (ie. backend) is now implemented by the backends
1620+
#
15991621
#Revision 1.43 2002/07/10 06:30:30 richard
16001622
#...except of course it's nice to use valid Python syntax
16011623
#

roundup/backends/back_metakit.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,19 @@ def __init__(self, db, classname, **properties):
216216
self.properties = self.ruprops
217217
self.db.addclass(self)
218218
self.idcache = {}
219+
220+
# default is to journal changes
221+
self.do_journal = 1
222+
223+
def enableJournalling(self):
224+
'''Turn journalling on for this class
225+
'''
226+
self.do_journal = 1
227+
228+
def disableJournalling(self):
229+
'''Turn journalling off for this class
230+
'''
231+
self.do_journal = 0
219232

220233
# --- the roundup.Class methods
221234
def audit(self, event, detector):
@@ -349,7 +362,7 @@ def set(self, nodeid, **propvalues):
349362
setattr(row, key, int(value))
350363
changes[key] = oldvalue
351364

352-
if prop.do_journal:
365+
if self.do_journal and prop.do_journal:
353366
# register the unlink with the old linked node
354367
if oldvalue:
355368
self.db.addjournal(link_class, value, _UNLINK, (self.classname, str(row.id), key))
@@ -385,7 +398,7 @@ def set(self, nodeid, **propvalues):
385398
if id not in value:
386399
rmvd.append(id)
387400
# register the unlink with the old linked node
388-
if prop.do_journal:
401+
if self.do_journal and prop.do_journal:
389402
self.db.addjournal(link_class, id, _UNLINK, (self.classname, str(row.id), key))
390403

391404
# handle additions
@@ -397,7 +410,7 @@ def set(self, nodeid, **propvalues):
397410
link_class, id)
398411
adds.append(id)
399412
# register the link with the newly linked node
400-
if prop.do_journal:
413+
if self.do_journal and prop.do_journal:
401414
self.db.addjournal(link_class, id, _LINK, (self.classname, str(row.id), key))
402415

403416
sv = getattr(row, key)
@@ -457,10 +470,11 @@ def set(self, nodeid, **propvalues):
457470
row.creator = self.db.curuserid
458471

459472
self.db.dirty = 1
460-
if isnew:
461-
self.db.addjournal(self.classname, nodeid, _CREATE, {})
462-
else:
463-
self.db.addjournal(self.classname, nodeid, _SET, changes)
473+
if self.do_journal:
474+
if isnew:
475+
self.db.addjournal(self.classname, nodeid, _CREATE, {})
476+
else:
477+
self.db.addjournal(self.classname, nodeid, _SET, changes)
464478

465479
def retire(self, nodeid):
466480
view = self.getview(1)
@@ -471,13 +485,16 @@ def retire(self, nodeid):
471485
oldvalues = self.uncommitted.setdefault(row.id, {})
472486
oldval = oldvalues['_isdel'] = row._isdel
473487
row._isdel = 1
474-
self.db.addjournal(self.classname, nodeid, _RETIRE, {})
488+
if self.do_journal:
489+
self.db.addjournal(self.classname, nodeid, _RETIRE, {})
475490
iv = self.getindexview(1)
476491
ndx = iv.find(k=getattr(row, self.keyname),i=row.id)
477492
if ndx > -1:
478493
iv.delete(ndx)
479494
self.db.dirty = 1
480495
def history(self, nodeid):
496+
if not self.do_journal:
497+
raise ValueError, 'Journalling is disabled for this class'
481498
return self.db.gethistory(self.classname, nodeid)
482499
def setkey(self, propname):
483500
if self.keyname:
@@ -930,11 +947,8 @@ def index(self, nodeid):
930947
self.db.indexer.add_text((self.classname, nodeid, 'content'),
931948
self.get(nodeid, 'content'), mimetype)
932949

933-
# Yuck - c&p to avoid getting hyperdb.Class
934950
class IssueClass(Class, roundupdb.IssueClass):
935-
936951
# Overridden methods:
937-
938952
def __init__(self, db, classname, **properties):
939953
"""The newly-created class automatically includes the "messages",
940954
"files", "nosy", and "superseder" properties. If the 'properties'

roundup/cgi_client.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: cgi_client.py,v 1.137 2002-07-10 07:00:30 richard Exp $
18+
# $Id: cgi_client.py,v 1.138 2002-07-14 04:03:13 richard Exp $
1919

2020
__doc__ = """
2121
WWW request handler (also used in the stand-alone server).
@@ -1214,11 +1214,14 @@ def opendb(self, user):
12141214
try:
12151215
sessions = self.db.getclass('__sessions')
12161216
except:
1217-
# add the sessions Class
1218-
sessions = hyperdb.Class(self.db, '__sessions',
1217+
# add the sessions Class - use a non-journalling Class
1218+
# TODO: not happy with how we're getting the Class here :(
1219+
sessions = self.instance.dbinit.Class(self.db, '__sessions',
12191220
sessid=hyperdb.String(), user=hyperdb.String(),
12201221
last_use=hyperdb.Date())
12211222
sessions.setkey('sessid')
1223+
# make sure session db isn't journalled
1224+
sessions.disableJournalling()
12221225

12231226
def main(self):
12241227
'''Wrap the database accesses so we can close the database cleanly
@@ -1253,6 +1256,7 @@ def main(self):
12531256
except KeyError:
12541257
user = 'anonymous'
12551258
else:
1259+
# update the lifetime datestamp
12561260
sessions.set(self.session, last_use=date.Date())
12571261
self.db.commit()
12581262
user = sessions.get(sessid, 'user')
@@ -1460,7 +1464,7 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
14601464
# Quite likely to be a FormItem instance
14611465
value = value.value
14621466
if not isinstance(value, type([])):
1463-
value = [i.strip() for i in value.value.split(',')]
1467+
value = [i.strip() for i in value.split(',')]
14641468
else:
14651469
value = [i.strip() for i in value]
14661470
link = cl.properties[key].classname
@@ -1496,6 +1500,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
14961500

14971501
#
14981502
# $Log: not supported by cvs2svn $
1503+
# Revision 1.137 2002/07/10 07:00:30 richard
1504+
# removed debugging
1505+
#
14991506
# Revision 1.136 2002/07/10 06:51:08 richard
15001507
# . #576241 ] MultiLink problems in parsePropsFromForm
15011508
#

test/test_db.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: test_db.py,v 1.28 2002-07-14 02:16:29 richard Exp $
18+
# $Id: test_db.py,v 1.29 2002-07-14 04:03:15 richard Exp $
1919

20-
import unittest, os, shutil
20+
import unittest, os, shutil, time
2121

2222
from roundup.hyperdb import String, Password, Link, Multilink, Date, \
2323
Interval, DatabaseError
@@ -284,6 +284,26 @@ def testJournals(self):
284284
self.assertEqual('unlink', action)
285285
self.assertEqual(('issue', '1', 'fixer'), params)
286286

287+
# test disabling journalling
288+
# ... get the last entry
289+
time.sleep(1)
290+
entry = self.db.getjournal('issue', '1')[-1]
291+
(x, date_stamp, x, x, x) = entry
292+
self.db.issue.disableJournalling()
293+
self.db.issue.set('1', title='hello world')
294+
self.db.commit()
295+
entry = self.db.getjournal('issue', '1')[-1]
296+
(x, date_stamp2, x, x, x) = entry
297+
# see if the change was journalled when it shouldn't have been
298+
self.assertEqual(date_stamp, date_stamp2)
299+
self.db.issue.enableJournalling()
300+
self.db.issue.set('1', title='hello world 2')
301+
self.db.commit()
302+
entry = self.db.getjournal('issue', '1')[-1]
303+
(x, date_stamp2, x, x, x) = entry
304+
# see if the change was journalled
305+
self.assertNotEqual(date_stamp, date_stamp2)
306+
287307
def testPack(self):
288308
self.db.issue.create(title="spam", status='1')
289309
self.db.commit()
@@ -504,6 +524,10 @@ def suite():
504524

505525
#
506526
# $Log: not supported by cvs2svn $
527+
# Revision 1.28 2002/07/14 02:16:29 richard
528+
# Fixes for the metakit backend (removed the cut-n-paste IssueClass, removed
529+
# a special case for it in testing)
530+
#
507531
# Revision 1.27 2002/07/14 02:05:54 richard
508532
# . all storage-specific code (ie. backend) is now implemented by the backends
509533
#

0 commit comments

Comments
 (0)