Skip to content

Commit 60a268c

Browse files
author
Andrey Lebedev
committed
checked to make sure that the restored item doesn't clash...
...with a new item using the same key value
1 parent ef69a5d commit 60a268c

File tree

5 files changed

+49
-9
lines changed

5 files changed

+49
-9
lines changed

roundup/backends/back_anydbm.py

Lines changed: 12 additions & 3 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.112 2003-03-16 22:24:54 kedder Exp $
18+
#$Id: back_anydbm.py,v 1.113 2003-03-17 22:03:04 kedder 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
@@ -1328,9 +1328,18 @@ def restore(self, nodeid):
13281328
if self.db.journaltag is None:
13291329
raise DatabaseError, 'Database open read-only'
13301330

1331-
self.fireAuditors('restore', nodeid, None)
1332-
13331331
node = self.db.getnode(self.classname, nodeid)
1332+
# check if key property was overrided
1333+
key = self.getkey()
1334+
try:
1335+
id = self.lookup(node[key])
1336+
except KeyError:
1337+
pass
1338+
else:
1339+
raise KeyError, "Key property (%s) of retired node clashes with \
1340+
existing one (%s)" % (key, node[key])
1341+
# Now we can safely restore node
1342+
self.fireAuditors('restore', nodeid, None)
13341343
del node[self.db.RETIRED_FLAG]
13351344
self.db.setnode(self.classname, nodeid, node)
13361345
if self.do_journal:

roundup/backends/back_metakit.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: back_metakit.py,v 1.42 2003-03-16 22:24:54 kedder Exp $
1+
# $Id: back_metakit.py,v 1.43 2003-03-17 22:03:04 kedder Exp $
22
'''
33
Metakit backend for Roundup, originally by Gordon McMillan.
44
@@ -684,6 +684,18 @@ def restore(self, nodeid):
684684
'''
685685
if self.db.journaltag is None:
686686
raise hyperdb.DatabaseError, 'Database open read-only'
687+
688+
# check if key property was overrided
689+
key = self.getkey()
690+
keyvalue = self.get(nodeid, key)
691+
try:
692+
id = self.lookup(keyvalue)
693+
except KeyError:
694+
pass
695+
else:
696+
raise KeyError, "Key property (%s) of retired node clashes with \
697+
existing one (%s)" % (key, keyvalue)
698+
# Now we can safely restore node
687699
self.fireAuditors('restore', nodeid, None)
688700
view = self.getview(1)
689701
ndx = view.find(id=int(nodeid))

roundup/backends/rdbms_common.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: rdbms_common.py,v 1.44 2003-03-16 22:24:55 kedder Exp $
1+
# $Id: rdbms_common.py,v 1.45 2003-03-17 22:03:08 kedder Exp $
22
''' Relational database (SQL) backend common code.
33
44
Basics:
@@ -1486,8 +1486,18 @@ def restore(self, nodeid):
14861486
if self.db.journaltag is None:
14871487
raise DatabaseError, 'Database open read-only'
14881488

1489-
self.fireAuditors('restore', nodeid, None)
1489+
node = self.db.getnode(self.classname, nodeid)
1490+
# check if key property was overrided
1491+
key = self.getkey()
1492+
try:
1493+
id = self.lookup(node[key])
1494+
except KeyError:
1495+
pass
1496+
else:
1497+
raise KeyError, "Key property (%s) of retired node clashes with \
1498+
existing one (%s)" % (key, node[key])
14901499

1500+
self.fireAuditors('restore', nodeid, None)
14911501
# use the arg for __retired__ to cope with any odd database type
14921502
# conversion (hello, sqlite)
14931503
sql = 'update _%s set __retired__=%s where id=%s'%(self.classname,

roundup/hyperdb.py

Lines changed: 8 additions & 1 deletion
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: hyperdb.py,v 1.86 2003-02-26 04:55:57 richard Exp $
18+
# $Id: hyperdb.py,v 1.87 2003-03-17 22:03:03 kedder Exp $
1919

2020
"""
2121
Hyperdatabase implementation, especially field types.
@@ -416,6 +416,13 @@ def retire(self, nodeid):
416416
"""
417417
raise NotImplementedError
418418

419+
def restore(self, nodeid):
420+
'''Restpre a retired node.
421+
422+
Make node available for all operations like it was before retirement.
423+
'''
424+
raise NotImplementedError
425+
419426
def is_retired(self, nodeid):
420427
'''Return true if the node is rerired
421428
'''

test/test_db.py

Lines changed: 4 additions & 2 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: test_db.py,v 1.77 2003-03-16 22:24:56 kedder Exp $
18+
# $Id: test_db.py,v 1.78 2003-03-17 22:03:08 kedder Exp $
1919

2020
import unittest, os, shutil, time
2121

@@ -273,6 +273,8 @@ def testKeyValue(self):
273273
# use the key again now that the old is retired
274274
newid2 = self.db.user.create(username="spam")
275275
self.assertNotEqual(newid, newid2)
276+
# try to restore old node. this shouldn't succeed!
277+
self.assertRaises(KeyError, self.db.user.restore, newid)
276278

277279
def testRetire(self):
278280
self.db.issue.create(title="spam", status='1')
@@ -926,7 +928,7 @@ def suite():
926928
unittest.makeSuite(anydbmDBTestCase, 'test'),
927929
unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
928930
]
929-
# return unittest.TestSuite(l)
931+
#return unittest.TestSuite(l)
930932

931933
from roundup import backends
932934
p = []

0 commit comments

Comments
 (0)