summaryrefslogtreecommitdiffstats
path: root/Lib/bsddb
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/bsddb')
-rw-r--r--Lib/bsddb/dbobj.py8
-rw-r--r--Lib/bsddb/dbtables.py3
-rw-r--r--Lib/bsddb/test/test_associate.py2
-rw-r--r--Lib/bsddb/test/test_basics.py63
-rw-r--r--Lib/bsddb/test/test_join.py108
5 files changed, 174 insertions, 10 deletions
diff --git a/Lib/bsddb/dbobj.py b/Lib/bsddb/dbobj.py
index b2632a1..d23f533 100644
--- a/Lib/bsddb/dbobj.py
+++ b/Lib/bsddb/dbobj.py
@@ -15,6 +15,12 @@
# implied.
#
+#
+# TODO it would be *really nice* to have an automatic shadow class populator
+# so that new methods don't need to be added here manually after being
+# added to _bsddb.c.
+#
+
import db
try:
@@ -57,6 +63,8 @@ class DBEnv:
return apply(self._cobj.set_lk_max_objects, args, kwargs)
def set_mp_mmapsize(self, *args, **kwargs):
return apply(self._cobj.set_mp_mmapsize, args, kwargs)
+ def set_timeout(self, *args, **kwargs):
+ return apply(self._cobj.set_timeout, args, kwargs)
def set_tmp_dir(self, *args, **kwargs):
return apply(self._cobj.set_tmp_dir, args, kwargs)
def txn_begin(self, *args, **kwargs):
diff --git a/Lib/bsddb/dbtables.py b/Lib/bsddb/dbtables.py
index 85dbb4a..d052ca5 100644
--- a/Lib/bsddb/dbtables.py
+++ b/Lib/bsddb/dbtables.py
@@ -155,6 +155,9 @@ class bsdTableDB :
if truncate:
myflags |= DB_TRUNCATE
self.db = DB(self.env)
+ # this code relies on DBCursor.set* methods to raise exceptions
+ # rather than returning None
+ self.db.set_get_returns_none(1)
# allow duplicate entries [warning: be careful w/ metadata]
self.db.set_flags(DB_DUP)
self.db.open(filename, DB_BTREE, dbflags | myflags, mode)
diff --git a/Lib/bsddb/test/test_associate.py b/Lib/bsddb/test/test_associate.py
index 3061e45..5fe41a9 100644
--- a/Lib/bsddb/test/test_associate.py
+++ b/Lib/bsddb/test/test_associate.py
@@ -1,5 +1,5 @@
"""
-TestCases for multi-threaded access to a DB.
+TestCases for DB.associate.
"""
import sys, os, string
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index 224aef4..dbab231 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -282,11 +282,11 @@ class BasicTestCase(unittest.TestCase):
#----------------------------------------
- def test03_SimpleCursorStuff(self):
+ def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=1):
if verbose:
print '\n', '-=' * 30
- print "Running %s.test03_SimpleCursorStuff..." % \
- self.__class__.__name__
+ print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
+ (self.__class__.__name__, get_raises_error, set_raises_error)
if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
txn = self.env.txn_begin()
@@ -300,7 +300,15 @@ class BasicTestCase(unittest.TestCase):
count = count + 1
if verbose and count % 100 == 0:
print rec
- rec = c.next()
+ try:
+ rec = c.next()
+ except db.DBNotFoundError, val:
+ if get_raises_error:
+ assert val[0] == db.DB_NOTFOUND
+ if verbose: print val
+ rec = None
+ else:
+ self.fail("unexpected DBNotFoundError")
assert count == 1000
@@ -311,7 +319,15 @@ class BasicTestCase(unittest.TestCase):
count = count + 1
if verbose and count % 100 == 0:
print rec
- rec = c.prev()
+ try:
+ rec = c.prev()
+ except db.DBNotFoundError, val:
+ if get_raises_error:
+ assert val[0] == db.DB_NOTFOUND
+ if verbose: print val
+ rec = None
+ else:
+ self.fail("unexpected DBNotFoundError")
assert count == 1000
@@ -322,23 +338,29 @@ class BasicTestCase(unittest.TestCase):
assert rec[1] == self.makeData('0505')
try:
- c.set('bad key')
+ n = c.set('bad key')
except db.DBNotFoundError, val:
assert val[0] == db.DB_NOTFOUND
if verbose: print val
else:
- self.fail("expected exception")
+ if set_raises_error:
+ self.fail("expected exception")
+ if n != None:
+ self.fail("expected None: "+`n`)
rec = c.get_both('0404', self.makeData('0404'))
assert rec == ('0404', self.makeData('0404'))
try:
- c.get_both('0404', 'bad data')
+ n = c.get_both('0404', 'bad data')
except db.DBNotFoundError, val:
assert val[0] == db.DB_NOTFOUND
if verbose: print val
else:
- self.fail("expected exception")
+ if get_raises_error:
+ self.fail("expected exception")
+ if n != None:
+ self.fail("expected None: "+`n`)
if self.d.get_type() == db.DB_BTREE:
rec = c.set_range('011')
@@ -414,6 +436,29 @@ class BasicTestCase(unittest.TestCase):
# SF pybsddb bug id 667343
del oldcursor
+ def test03b_SimpleCursorWithoutGetReturnsNone0(self):
+ # same test but raise exceptions instead of returning None
+ if verbose:
+ print '\n', '-=' * 30
+ print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
+ self.__class__.__name__
+
+ old = self.d.set_get_returns_none(0)
+ assert old == 1
+ self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
+
+ def test03c_SimpleCursorGetReturnsNone2(self):
+ # same test but raise exceptions instead of returning None
+ if verbose:
+ print '\n', '-=' * 30
+ print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
+ self.__class__.__name__
+
+ old = self.d.set_get_returns_none(2)
+ assert old == 1
+ old = self.d.set_get_returns_none(2)
+ assert old == 2
+ self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
#----------------------------------------
diff --git a/Lib/bsddb/test/test_join.py b/Lib/bsddb/test/test_join.py
index ab75ba1..08784ac 100644
--- a/Lib/bsddb/test/test_join.py
+++ b/Lib/bsddb/test/test_join.py
@@ -1,9 +1,117 @@
"""TestCases for using the DB.join and DBCursor.join_item methods.
"""
+import sys, os, string
+import tempfile
+import time
+from pprint import pprint
+
+try:
+ from threading import Thread, currentThread
+ have_threads = 1
+except ImportError:
+ have_threads = 0
+
import unittest
+from test_all import verbose
+
+try:
+ # For Python 2.3
+ from bsddb import db, dbshelve
+except ImportError:
+ # For earlier Pythons w/distutils pybsddb
+ from bsddb3 import db, dbshelve
+
+
+#----------------------------------------------------------------------
+
+ProductIndex = [
+ ('apple', "Convenience Store"),
+ ('blueberry', "Farmer's Market"),
+ ('shotgun', "S-Mart"), # Aisle 12
+ ('pear', "Farmer's Market"),
+ ('chainsaw', "S-Mart"), # "Shop smart. Shop S-Mart!"
+ ('strawberry', "Farmer's Market"),
+]
+
+ColorIndex = [
+ ('blue', "blueberry"),
+ ('red', "apple"),
+ ('red', "chainsaw"),
+ ('red', "strawberry"),
+ ('yellow', "peach"),
+ ('yellow', "pear"),
+ ('black', "shotgun"),
+]
+
+class JoinTestCase(unittest.TestCase):
+ keytype = ''
+
+ def setUp(self):
+ self.filename = self.__class__.__name__ + '.db'
+ homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
+ self.homeDir = homeDir
+ try: os.mkdir(homeDir)
+ except os.error: pass
+ self.env = db.DBEnv()
+ self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK )
+
+ def tearDown(self):
+ self.env.close()
+ import glob
+ files = glob.glob(os.path.join(self.homeDir, '*'))
+ for file in files:
+ os.remove(file)
+
+ def test01_join(self):
+ if verbose:
+ print '\n', '-=' * 30
+ print "Running %s.test01_join..." % \
+ self.__class__.__name__
+
+ # create and populate primary index
+ priDB = db.DB(self.env)
+ priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
+ map(lambda t: apply(priDB.put, t), ProductIndex)
+
+ # create and populate secondary index
+ secDB = db.DB(self.env)
+ secDB.set_flags(db.DB_DUP | db.DB_DUPSORT)
+ secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
+ map(lambda t: apply(secDB.put, t), ColorIndex)
+
+ sCursor = None
+ jCursor = None
+ try:
+ # lets look up all of the red Products
+ sCursor = secDB.cursor()
+ assert sCursor.set('red')
+
+ # FIXME: jCursor doesn't properly hold a reference to its
+ # cursors, if they are closed before jcursor is used it
+ # can cause a crash.
+ jCursor = priDB.join([sCursor])
+
+ if jCursor.get(0) != ('apple', "Convenience Store"):
+ self.fail("join cursor positioned wrong")
+ if jCursor.join_item() != 'chainsaw':
+ self.fail("DBCursor.join_item returned wrong item")
+ if jCursor.get(0)[0] != 'strawberry':
+ self.fail("join cursor returned wrong thing")
+ if jCursor.get(0): # there were only three red items to return
+ self.fail("join cursor returned too many items")
+ finally:
+ if jCursor:
+ jCursor.close()
+ if sCursor:
+ sCursor.close()
+ priDB.close()
+ secDB.close()
def test_suite():
suite = unittest.TestSuite()
+
+ suite.addTest(unittest.makeSuite(JoinTestCase))
+
return suite