Commit 6ba3329c authored by Jesus Cea's avatar Jesus Cea

bsddb code updated to version 4.7.3pre2. This code is the same than

Python 2.6 one, since the intention is to keep an unified 2.x/3.x
codebase.

The Python code is automatically translated using "2to3". Please, do not
update this code in Python 3.0 by hand. Update the 2.6 one and then do
"2to3".
parent 73c96dbf
This diff is collapsed.
......@@ -37,15 +37,24 @@
# case we ever want to augment the stuff in _db in any way. For now
# it just simply imports everything from _db.
if __name__.startswith('bsddb3.'):
# import _pybsddb binary as it should be the more recent version from
# a standalone pybsddb addon package than the version included with
# python as bsddb._bsddb.
from _pybsddb import *
from _pybsddb import __version__
else:
from _bsddb import *
from _bsddb import __version__
import sys
absolute_import = (sys.version_info[0] >= 3)
if version() < (3, 2, 0):
raise ImportError("correct BerkeleyDB symbols not found. Perhaps python was statically linked with an older version?")
if not absolute_import :
if __name__.startswith('bsddb3.') :
# import _pybsddb binary as it should be the more recent version from
# a standalone pybsddb addon package than the version included with
# python as bsddb._bsddb.
from _pybsddb import *
from _pybsddb import __version__
else:
from _bsddb import *
from _bsddb import __version__
else :
# Because this syntaxis is not valid before Python 2.5
if __name__.startswith('bsddb3.') :
exec("from ._pybsddb import *")
exec("from ._pybsddb import __version__")
else :
exec("from ._bsddb import *")
exec("from ._bsddb import __version__")
......@@ -21,12 +21,24 @@
# added to _bsddb.c.
#
from . import db
import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
try:
from collections import MutableMapping
except ImportError:
class MutableMapping: pass
if sys.version_info[0:2] <= (2, 5) :
try:
from UserDict import DictMixin
except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else :
import collections
MutableMapping = collections.MutableMapping
class DBEnv:
def __init__(self, *args, **kwargs):
......@@ -95,9 +107,8 @@ class DBEnv:
def set_get_returns_none(self, *args, **kwargs):
return self._cobj.set_get_returns_none(*args, **kwargs)
if db.version() >= (4,0):
def log_stat(self, *args, **kwargs):
return self._cobj.log_stat(*args, **kwargs)
def log_stat(self, *args, **kwargs):
return self._cobj.log_stat(*args, **kwargs)
if db.version() >= (4,1):
def dbremove(self, *args, **kwargs):
......@@ -115,7 +126,7 @@ class DBEnv:
class DB(MutableMapping):
def __init__(self, dbenv, *args, **kwargs):
# give it the proper DBEnv C object that its expecting
self._cobj = db.DB(dbenv._cobj, *args, **kwargs)
self._cobj = db.DB(*(dbenv._cobj,) + args, **kwargs)
# TODO are there other dict methods that need to be overridden?
def __len__(self):
......@@ -126,8 +137,10 @@ class DB(MutableMapping):
self._cobj[key] = value
def __delitem__(self, arg):
del self._cobj[arg]
def __iter__(self):
return iter(self.keys())
if sys.version_info[0:2] >= (2, 6) :
def __iter__(self) :
return self._cobj.__iter__()
def append(self, *args, **kwargs):
return self._cobj.append(*args, **kwargs)
......@@ -163,8 +176,6 @@ class DB(MutableMapping):
return self._cobj.key_range(*args, **kwargs)
def has_key(self, *args, **kwargs):
return self._cobj.has_key(*args, **kwargs)
def __contains__(self, key):
return self._cobj.has_key(key)
def items(self, *args, **kwargs):
return self._cobj.items(*args, **kwargs)
def keys(self, *args, **kwargs):
......
......@@ -29,6 +29,7 @@ From:
"""
import errno
import string
class DBRecIO:
def __init__(self, db, key, txn=None):
......@@ -38,6 +39,7 @@ class DBRecIO:
self.len = None
self.pos = 0
self.closed = 0
self.softspace = 0
def close(self):
if not self.closed:
......@@ -82,9 +84,9 @@ class DBRecIO:
if self.closed:
raise ValueError, "I/O operation on closed file"
if self.buflist:
self.buf = self.buf + ''.join(self.buflist)
self.buf = self.buf + string.joinfields(self.buflist, '')
self.buflist = []
i = self.buf.find('\n', self.pos)
i = string.find(self.buf, '\n', self.pos)
if i < 0:
newpos = self.len
else:
......@@ -133,7 +135,7 @@ class DBRecIO:
self.pos = newpos
def writelines(self, list):
self.write(''.join(list))
self.write(string.joinfields(list, ''))
def flush(self):
if self.closed:
......@@ -158,14 +160,14 @@ def _test():
if f.getvalue() != text:
raise RuntimeError, 'write failed'
length = f.tell()
print('File length =', length)
print 'File length =', length
f.seek(len(lines[0]))
f.write(lines[1])
f.seek(0)
print('First line =', repr(f.readline()))
print 'First line =', repr(f.readline())
here = f.tell()
line = f.readline()
print('Second line =', repr(line))
print 'Second line =', repr(line)
f.seek(-len(line), 1)
line2 = f.read(len(line))
if line != line2:
......@@ -177,8 +179,8 @@ def _test():
line2 = f.read()
if line != line2:
raise RuntimeError, 'bad result after seek back from EOF'
print('Read', len(list), 'more lines')
print('File length =', f.tell())
print 'Read', len(list), 'more lines'
print 'File length =', f.tell()
if f.tell() != length:
raise RuntimeError, 'bad length'
f.close()
......
......@@ -32,21 +32,43 @@ storage.
import pickle
import sys
import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
#At version 2.3 cPickle switched to using protocol instead of bin
if sys.version_info[:3] >= (2, 3, 0):
HIGHEST_PROTOCOL = pickle.HIGHEST_PROTOCOL
def _dumps(object, protocol):
return pickle.dumps(object, protocol=protocol)
from collections import MutableMapping
# In python 2.3.*, "cPickle.dumps" accepts no
# named parameters. "pickle.dumps" accepts them,
# so this seems a bug.
if sys.version_info[:3] < (2, 4, 0):
def _dumps(object, protocol):
return pickle.dumps(object, protocol)
else :
def _dumps(object, protocol):
return pickle.dumps(object, protocol=protocol)
else:
HIGHEST_PROTOCOL = None
def _dumps(object, protocol):
return pickle.dumps(object, bin=protocol)
class MutableMapping: pass
from . import db
_unspecified = object()
if sys.version_info[0:2] <= (2, 5) :
try:
from UserDict import DictMixin
except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else :
import collections
MutableMapping = collections.MutableMapping
#------------------------------------------------------------------------
......@@ -135,13 +157,15 @@ class DBShelf(MutableMapping):
def keys(self, txn=None):
if txn is not None:
if txn != None:
return self.db.keys(txn)
else:
return self.db.keys()
return list(self.db.keys())
if sys.version_info[0:2] >= (2, 6) :
def __iter__(self) :
return self.db.__iter__()
def __iter__(self):
return iter(self.keys())
def open(self, *args, **kwargs):
self.db.open(*args, **kwargs)
......@@ -157,14 +181,14 @@ class DBShelf(MutableMapping):
if self._closed:
return '<DBShelf @ 0x%x - closed>' % (id(self))
else:
return repr(dict(self.iteritems()))
return repr(dict(iter(self.items())))
def items(self, txn=None):
if txn is not None:
if txn != None:
items = self.db.items(txn)
else:
items = self.db.items()
items = list(self.db.items())
newitems = []
for k, v in items:
......@@ -172,12 +196,12 @@ class DBShelf(MutableMapping):
return newitems
def values(self, txn=None):
if txn is not None:
if txn != None:
values = self.db.values(txn)
else:
values = self.db.values()
values = list(self.db.values())
return map(pickle.loads, values)
return list(map(pickle.loads, values))
#-----------------------------------
# Other methods
......@@ -194,24 +218,28 @@ class DBShelf(MutableMapping):
def associate(self, secondaryDB, callback, flags=0):
def _shelf_callback(priKey, priData, realCallback=callback):
data = pickle.loads(priData)
# Safe in Python 2.x because expresion short circuit
if sys.version_info[0] < 3 or isinstance(priData, bytes) :
data = pickle.loads(priData)
else :
data = pickle.loads(bytes(priData, "iso8859-1")) # 8 bits
return realCallback(priKey, data)
return self.db.associate(secondaryDB, _shelf_callback, flags)
def get(self, key, default=_unspecified, txn=None, flags=0):
# If no default is given, we must not pass one to the
# extension module, so that an exception can be raised if
# set_get_returns_none is turned off.
if default is _unspecified:
data = self.db.get(key, txn=txn, flags=flags)
# if this returns, the default value would be None
default = None
else:
data = self.db.get(key, default, txn=txn, flags=flags)
if data is default:
return data
return pickle.loads(data)
#def get(self, key, default=None, txn=None, flags=0):
def get(self, *args, **kw):
# We do it with *args and **kw so if the default value wasn't
# given nothing is passed to the extension module. That way
# an exception can be raised if set_get_returns_none is turned
# off.
data = self.db.get(*args, **kw)
try:
return pickle.loads(data)
except (EOFError, TypeError, pickle.UnpicklingError):
return data # we may be getting the default value, or None,
# so it doesn't need unpickled.
def get_both(self, key, value, txn=None, flags=0):
data = _dumps(value, self.protocol)
......@@ -234,10 +262,6 @@ class DBShelf(MutableMapping):
raise NotImplementedError
def __contains__(self, key):
return self.db.has_key(key)
#----------------------------------------------
# Methods allowed to pass-through to self.db
#
......@@ -331,7 +355,11 @@ class DBShelfCursor:
return None
else:
key, data = rec
return key, pickle.loads(data)
# Safe in Python 2.x because expresion short circuit
if sys.version_info[0] < 3 or isinstance(data, bytes) :
return key, pickle.loads(data)
else :
return key, pickle.loads(bytes(data, "iso8859-1")) # 8 bits
#----------------------------------------------
# Methods allowed to pass-through to self.dbc
......
This diff is collapsed.
......@@ -19,8 +19,20 @@
#
#------------------------------------------------------------------------
import time
from . import db
#
# import the time.sleep function in a namespace safe way to allow
# "from bsddb.dbutils import *"
#
from time import sleep as _sleep
import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
# always sleep at least N seconds between retrys
_deadlock_MinSleepTime = 1.0/128
......@@ -54,22 +66,17 @@ def DeadlockWrap(function, *_args, **_kwargs):
while True:
try:
return function(*_args, **_kwargs)
except db.DBLockDeadlockError as e:
except db.DBLockDeadlockError:
if _deadlock_VerboseFile:
_deadlock_VerboseFile.write(
'bsddb.dbutils.DeadlockWrap: ' +
'sleeping %1.3f\n' % sleeptime)
time.sleep(sleeptime)
'dbutils.DeadlockWrap: sleeping %1.3f\n' % sleeptime)
_sleep(sleeptime)
# exponential backoff in the sleep time
sleeptime *= 2
if sleeptime > _deadlock_MaxSleepTime:
sleeptime = _deadlock_MaxSleepTime
max_retries -= 1
if max_retries == -1:
if _deadlock_VerboseFile:
_deadlock_VerboseFile.write(
'bsddb.dbutils.DeadlockWrap: ' +
'max_retries reached, reraising %s\n' % e)
raise
......
# http://bugs.python.org/issue1413192
#
# See the bug report for details.
# The problem was that the env was deallocated prior to the txn.
import shutil
import tempfile
from test.support import catch_warning
import warnings
try:
# For Pythons w/distutils and add-on pybsddb
from bsddb3 import db
except ImportError:
# For Python >= 2.3 builtin bsddb distribution
from bsddb import db
env_name = tempfile.mkdtemp()
# Wrap test operation in a class so we can control destruction rather than
# waiting for the controlling Python executable to exit
class Context:
def __init__(self):
self.env = db.DBEnv()
self.env.open(env_name,
db.DB_CREATE | db.DB_INIT_TXN | db.DB_INIT_MPOOL)
self.the_txn = self.env.txn_begin()
self.map = db.DB(self.env)
self.map.open('xxx.db', "p",
db.DB_HASH, db.DB_CREATE, 0o666, txn=self.the_txn)
del self.env
del self.the_txn
with catch_warning():
warnings.filterwarnings('ignore', 'DBTxn aborted in destructor')
context = Context()
del context
# try not to leave a turd
try:
shutil.rmtree(env_name)
except EnvironmentError:
pass
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,55 +2,51 @@
TestCases for python DB Btree key comparison function.
"""
import shutil
import sys, os, re
from io import StringIO
import tempfile
from . import test_all
from io import StringIO
import unittest
try:
# For Pythons w/distutils pybsddb
from bsddb3 import db, dbshelve
except ImportError:
# For Python 2.3
from bsddb import db, dbshelve
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
from .test_all import db, dbshelve, test_support, \
get_new_environment_path, get_new_database_path
lexical_cmp = cmp
def lowercase_cmp(left, right):
return cmp (str(left, encoding='ascii').lower(),
str(right, encoding='ascii').lower())
return cmp (left.lower(), right.lower())
def make_reverse_comparator (cmp):
def reverse (left, right, delegate=cmp):
return - delegate (left, right)
return reverse
_expected_lexical_test_data = [s.encode('ascii') for s in
('', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf')]
_expected_lowercase_test_data = [s.encode('ascii') for s in
('', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP')]
def CmpToKey(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) == -1
return K
_expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf']
_expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
class ComparatorTests (unittest.TestCase):
def comparator_test_helper (self, comparator, expected_data):
data = expected_data[:]
data.sort (key=CmpToKey(comparator))
import sys
if sys.version_info[0] < 3 :
if sys.version_info[:3] < (2, 4, 0):
data.sort(comparator)
else :
data.sort(cmp=comparator)
else : # Insertion Sort. Please, improve
data2 = []
for i in data :
for j, k in enumerate(data2) :
r = comparator(k, i)
if r == 1 :
data2.insert(j, i)
break
else :
data2.append(i)
data = data2
self.failUnless (data == expected_data,
"comparator `%s' is not right: %s vs. %s"
% (comparator, expected_data, data))
......@@ -71,30 +67,24 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
def setUp (self):
self.filename = self.__class__.__name__ + '.db'
homeDir = os.path.join (tempfile.gettempdir(), 'db_home%d'%os.getpid())
self.homeDir = homeDir
try:
os.mkdir (homeDir)
except os.error:
pass
env = db.DBEnv ()
self.homeDir = get_new_environment_path()
env = db.DBEnv()
env.open (self.homeDir,
db.DB_CREATE | db.DB_INIT_MPOOL
| db.DB_INIT_LOCK | db.DB_THREAD)
self.env = env
def tearDown (self):
self.closeDB ()
self.closeDB()
if self.env is not None:
self.env.close ()
self.env.close()
self.env = None
test_support.rmtree(self.homeDir)
def addDataToDB (self, data):
i = 0
for item in data:
self.db.put (item, str(i).encode("ascii"))
self.db.put (item, str (i))
i = i + 1
def createDB (self, key_comparator):
......@@ -128,10 +118,10 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
self.failUnless (index < len (expected),
"to many values returned from cursor")
self.failUnless (expected[index] == key,
"expected value %r at %d but got %r"
"expected value `%s' at %d but got `%s'"
% (expected[index], index, key))
index = index + 1
rec = curs.next ()
rec = next(curs)
self.failUnless (index == len (expected),
"not enough values returned from cursor")
finally:
......@@ -158,10 +148,10 @@ class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase):
def socialist_comparator (l, r):
return 0
self.createDB (socialist_comparator)
self.addDataToDB ([b'b', b'a', b'd'])
self.addDataToDB (['b', 'a', 'd'])
# all things being equal the first key will be the only key
# in the database... (with the last key's value fwiw)
self.finishTest ([b'b'])
self.finishTest (['b'])
class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
......@@ -200,9 +190,9 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
finally:
temp = sys.stderr
sys.stderr = stdErr
errorOut = temp.getvalue()
if not successRe.search(errorOut):
self.fail("unexpected stderr output: %r" % errorOut)
errorOut = temp.getvalue()
if not successRe.search(errorOut):
self.fail("unexpected stderr output:\n"+errorOut)
def _test_compare_function_exception (self):
self.startTest ()
......@@ -213,7 +203,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
raise RuntimeError("i'm a naughty comparison function")
self.createDB (bad_comparator)
#print "\n*** test should print 2 uncatchable tracebacks ***"
self.addDataToDB ([b'a', b'b', b'c']) # this should raise, but...
self.addDataToDB (['a', 'b', 'c']) # this should raise, but...
self.finishTest ()
def test_compare_function_exception(self):
......@@ -231,7 +221,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
return l
self.createDB (bad_comparator)
#print "\n*** test should print 2 errors about returning an int ***"
self.addDataToDB ([b'a', b'b', b'c']) # this should raise, but...
self.addDataToDB (['a', 'b', 'c']) # this should raise, but...
self.finishTest ()
def test_compare_function_bad_return(self):
......@@ -250,7 +240,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
self.createDB (my_compare)
try:
self.db.set_bt_compare (my_compare)
assert False, "this set should fail"
self.assert_(0, "this set should fail")
except RuntimeError as msg:
pass
......@@ -259,10 +249,9 @@ def test_suite ():
res = unittest.TestSuite ()
res.addTest (unittest.makeSuite (ComparatorTests))
if db.version () >= (3, 3, 11):
res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
return res
if __name__ == '__main__':
unittest.main (defaultTest = 'test_suite')
unittest.main (defaultTest = 'suite')
......@@ -3,18 +3,16 @@ Test cases adapted from the test_bsddb.py module in Python's
regression test suite.
"""
import sys, os
import os, string
import unittest
import tempfile
from bsddb.test.test_all import verbose
from bsddb import db, hashopen, btopen, rnopen
from .test_all import db, hashopen, btopen, rnopen, verbose, \
get_new_database_path
class CompatibilityTestCase(unittest.TestCase):
def setUp(self):
self.filename = tempfile.mktemp()
self.filename = get_new_database_path()
def tearDown(self):
try:
......@@ -36,31 +34,31 @@ class CompatibilityTestCase(unittest.TestCase):
f = rnopen(self.filename, 'c')
for x in range(len(data)):
f[x+1] = data[x].encode("ascii")
f[x+1] = data[x]
getTest = (f[1], f[2], f[3])
if verbose:
print('%s %s %s' % getTest)
assert getTest[1] == b'quick', 'data mismatch!'
self.assertEqual(getTest[1], 'quick', 'data mismatch!')
rv = f.set_location(3)
if rv != (3, b'brown'):
if rv != (3, 'brown'):
self.fail('recno database set_location failed: '+repr(rv))
f[25] = b'twenty-five'
f[25] = 'twenty-five'
f.close()
del f
f = rnopen(self.filename, 'w')
f[20] = b'twenty'
f[20] = 'twenty'
def noRec(f):
rec = f[15]
self.assertRaises(KeyError, noRec, f)
def badKey(f):
rec = f[b'a string']
rec = f['a string']
self.assertRaises(TypeError, badKey, f)
del f[3]
......@@ -70,7 +68,7 @@ class CompatibilityTestCase(unittest.TestCase):
if verbose:
print(rec)
try:
rec = f.next()
rec = next(f)
except KeyError:
break
......@@ -96,42 +94,42 @@ class CompatibilityTestCase(unittest.TestCase):
else:
if verbose: print("truth test: false")
f[b'0'] = b''
f[b'a'] = b'Guido'
f[b'b'] = b'van'
f[b'c'] = b'Rossum'
f[b'd'] = b'invented'
f['0'] = ''
f['a'] = 'Guido'
f['b'] = 'van'
f['c'] = 'Rossum'
f['d'] = 'invented'
# 'e' intentionally left out
f[b'f'] = b'Python'
f['f'] = 'Python'
if verbose:
print('%s %s %s' % (f['a'], f['b'], f['c']))
if verbose:
print('key ordering...')
start = f.set_location(f.first()[0])
if start != (b'0', b''):
if start != ('0', ''):
self.fail("incorrect first() result: "+repr(start))
while 1:
try:
rec = f.next()
rec = next(f)
except KeyError:
assert rec == f.last(), 'Error, last != last!'
self.assertEqual(rec, f.last(), 'Error, last <> last!')
f.previous()
break
if verbose:
print(rec)
assert f.has_key(b'f'), 'Error, missing key!'
self.assert_('f' in f, 'Error, missing key!')
# test that set_location() returns the next nearest key, value
# on btree databases and raises KeyError on others.
if factory == btopen:
e = f.set_location(b'e')
if e != (b'f', b'Python'):
e = f.set_location('e')
if e != ('f', 'Python'):
self.fail('wrong key,value returned: '+repr(e))
else:
try:
e = f.set_location(b'e')
e = f.set_location('e')
except KeyError:
pass
else:
......@@ -155,17 +153,17 @@ class CompatibilityTestCase(unittest.TestCase):
if verbose:
print('modification...')
f = factory(self.filename, 'w')
f[b'd'] = b'discovered'
f['d'] = 'discovered'
if verbose:
print('access...')
for key in f.keys():
for key in list(f.keys()):
word = f[key]
if verbose:
print(word)
def noRec(f):
rec = f[b'no such key']
rec = f['no such key']
self.assertRaises(KeyError, noRec, f)
def badKey(f):
......
import unittest
import tempfile
import sys, os, glob
import shutil
import tempfile
from bsddb import db
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
import os, glob
from .test_all import db, test_support, get_new_environment_path, \
get_new_database_path
#----------------------------------------------------------------------
......@@ -19,11 +11,7 @@ class pget_bugTestCase(unittest.TestCase):
db_name = 'test-cursor_pget.db'
def setUp(self):
self.homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid())
try:
os.mkdir(self.homeDir)
except os.error:
pass
self.homeDir = get_new_environment_path()
self.env = db.DBEnv()
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
self.primary_db = db.DB(self.env)
......@@ -32,9 +20,9 @@ class pget_bugTestCase(unittest.TestCase):
self.secondary_db.set_flags(db.DB_DUP)
self.secondary_db.open(self.db_name, 'secondary', db.DB_BTREE, db.DB_CREATE)
self.primary_db.associate(self.secondary_db, lambda key, data: data)
self.primary_db.put(b'salad', b'eggs')
self.primary_db.put(b'spam', b'ham')
self.primary_db.put(b'omelet', b'eggs')
self.primary_db.put('salad', 'eggs')
self.primary_db.put('spam', 'ham')
self.primary_db.put('omelet', 'eggs')
def tearDown(self):
......@@ -49,11 +37,11 @@ class pget_bugTestCase(unittest.TestCase):
def test_pget(self):
cursor = self.secondary_db.cursor()
self.assertEquals((b'eggs', b'salad', b'eggs'), cursor.pget(key=b'eggs', flags=db.DB_SET))
self.assertEquals((b'eggs', b'omelet', b'eggs'), cursor.pget(db.DB_NEXT_DUP))
self.assertEquals(('eggs', 'salad', 'eggs'), cursor.pget(key='eggs', flags=db.DB_SET))
self.assertEquals(('eggs', 'omelet', 'eggs'), cursor.pget(db.DB_NEXT_DUP))
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
self.assertEquals((b'ham', b'spam', b'ham'), cursor.pget(b'ham', b'spam', flags=db.DB_SET))
self.assertEquals(('ham', 'spam', 'ham'), cursor.pget('ham', 'spam', flags=db.DB_SET))
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
cursor.close()
......
import shutil
import sys, os
import os, string
import unittest
import tempfile
try:
# For Pythons w/distutils pybsddb
from bsddb3 import db, dbobj
except ImportError:
# For Python 2.3
from bsddb import db, dbobj
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
from .test_all import db, dbobj, test_support, get_new_environment_path, \
get_new_database_path
#----------------------------------------------------------------------
......@@ -24,10 +12,7 @@ class dbobjTestCase(unittest.TestCase):
db_name = 'test-dbobj.db'
def setUp(self):
homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid())
self.homeDir = homeDir
try: os.mkdir(homeDir)
except os.error: pass
self.homeDir = get_new_environment_path()
def tearDown(self):
if hasattr(self, 'db'):
......@@ -40,18 +25,18 @@ class dbobjTestCase(unittest.TestCase):
class TestDBEnv(dbobj.DBEnv): pass
class TestDB(dbobj.DB):
def put(self, key, *args, **kwargs):
key = key.decode("ascii").upper().encode("ascii")
key = key.upper()
# call our parent classes put method with an upper case key
return dbobj.DB.put(self, key, *args, **kwargs)
return dbobj.DB.put(*(self, key) + args, **kwargs)
self.env = TestDBEnv()
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
self.db = TestDB(self.env)
self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
self.db.put(b'spam', b'eggs')
assert self.db.get(b'spam') == None, \
"overridden dbobj.DB.put() method failed [1]"
assert self.db.get(b'SPAM') == b'eggs', \
"overridden dbobj.DB.put() method failed [2]"
self.db.put('spam', 'eggs')
self.assertEqual(self.db.get('spam'), None,
"overridden dbobj.DB.put() method failed [1]")
self.assertEqual(self.db.get('SPAM'), 'eggs',
"overridden dbobj.DB.put() method failed [2]")
self.db.close()
self.env.close()
......@@ -61,14 +46,14 @@ class dbobjTestCase(unittest.TestCase):
self.db = dbobj.DB(self.env)
self.db.open(self.db_name+'02', db.DB_HASH, db.DB_CREATE)
# __setitem__
self.db[b'spam'] = b'eggs'
self.db['spam'] = 'eggs'
# __len__
assert len(self.db) == 1
self.assertEqual(len(self.db), 1)
# __getitem__
assert self.db[b'spam'] == b'eggs'
self.assertEqual(self.db['spam'], 'eggs')
# __del__
del self.db[b'spam']
assert self.db.get(b'spam') == None, "dbobj __del__ failed"
del self.db['spam']
self.assertEqual(self.db.get('spam'), None, "dbobj __del__ failed")
self.db.close()
self.env.close()
......
This diff is collapsed.
This diff is collapsed.
"""TestCases for distributed transactions.
"""
import os
import unittest
from .test_all import db, test_support, get_new_environment_path, \
get_new_database_path
try :
a=set()
except : # Python 2.3
from sets import Set as set
else :
del a
from .test_all import verbose
#----------------------------------------------------------------------
class DBTxn_distributed(unittest.TestCase):
num_txns=1234
nosync=True
must_open_db=False
def _create_env(self, must_open_db) :
self.dbenv = db.DBEnv()
self.dbenv.set_tx_max(self.num_txns)
self.dbenv.set_lk_max_lockers(self.num_txns*2)
self.dbenv.set_lk_max_locks(self.num_txns*2)
self.dbenv.set_lk_max_objects(self.num_txns*2)
if self.nosync :
self.dbenv.set_flags(db.DB_TXN_NOSYNC,True)
self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_THREAD |
db.DB_RECOVER |
db.DB_INIT_TXN | db.DB_INIT_LOG | db.DB_INIT_MPOOL |
db.DB_INIT_LOCK, 0o666)
self.db = db.DB(self.dbenv)
self.db.set_re_len(db.DB_XIDDATASIZE)
if must_open_db :
if db.version() > (4,1) :
txn=self.dbenv.txn_begin()
self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0o666,
txn=txn)
txn.commit()
else :
self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0o666)
def setUp(self) :
self.homeDir = get_new_environment_path()
self.filename = "test"
return self._create_env(must_open_db=True)
def _destroy_env(self):
if self.nosync or (db.version()[:2] == (4,6)): # Known bug
self.dbenv.log_flush()
self.db.close()
self.dbenv.close()
def tearDown(self):
self._destroy_env()
test_support.rmtree(self.homeDir)
def _recreate_env(self,must_open_db) :
self._destroy_env()
self._create_env(must_open_db)
def test01_distributed_transactions(self) :
txns=set()
adapt = lambda x : x
import sys
if sys.version_info[0] >= 3 :
adapt = lambda x : bytes(x, "ascii")
# Create transactions, "prepare" them, and
# let them be garbage collected.
for i in range(self.num_txns) :
txn = self.dbenv.txn_begin()
gid = "%%%dd" %db.DB_XIDDATASIZE
gid = adapt(gid %i)
self.db.put(i, gid, txn=txn, flags=db.DB_APPEND)
txns.add(gid)
txn.prepare(gid)
del txn
self._recreate_env(self.must_open_db)
# Get "to be recovered" transactions but
# let them be garbage collected.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(self.num_txns,len(recovered_txns))
for gid,txn in recovered_txns :
self.assert_(gid in txns)
del txn
del recovered_txns
self._recreate_env(self.must_open_db)
# Get "to be recovered" transactions. Commit, abort and
# discard them.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(self.num_txns,len(recovered_txns))
discard_txns=set()
committed_txns=set()
state=0
for gid,txn in recovered_txns :
if state==0 or state==1:
committed_txns.add(gid)
txn.commit()
elif state==2 :
txn.abort()
elif state==3 :
txn.discard()
discard_txns.add(gid)
state=-1
state+=1
del txn
del recovered_txns
self._recreate_env(self.must_open_db)
# Verify the discarded transactions are still
# around, and dispose them.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(len(discard_txns),len(recovered_txns))
for gid,txn in recovered_txns :
txn.abort()
del txn
del recovered_txns
self._recreate_env(must_open_db=True)
# Be sure there are not pending transactions.
# Check also database size.
recovered_txns=self.dbenv.txn_recover()
self.assert_(len(recovered_txns)==0)
self.assertEquals(len(committed_txns),self.db.stat()["nkeys"])
class DBTxn_distributedSYNC(DBTxn_distributed):
nosync=False
class DBTxn_distributed_must_open_db(DBTxn_distributed):
must_open_db=True
class DBTxn_distributedSYNC_must_open_db(DBTxn_distributed):
nosync=False
must_open_db=True
#----------------------------------------------------------------------
def test_suite():
suite = unittest.TestSuite()
if db.version() >= (4,5) :
suite.addTest(unittest.makeSuite(DBTxn_distributed))
suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC))
if db.version() >= (4,6) :
suite.addTest(unittest.makeSuite(DBTxn_distributed_must_open_db))
suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC_must_open_db))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
"""TestCases for checking that it does not segfault when a DBEnv object
is closed before its DB objects.
"""
import os
import unittest
from .test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
# We're going to get warnings in this module about trying to close the db when
# its env is already closed. Let's just ignore those.
try:
import warnings
except ImportError:
pass
else:
warnings.filterwarnings('ignore',
message='DB could not be closed in',
category=RuntimeWarning)
#----------------------------------------------------------------------
class DBEnvClosedEarlyCrash(unittest.TestCase):
def setUp(self):
self.homeDir = get_new_environment_path()
self.filename = "test"
def tearDown(self):
test_support.rmtree(self.homeDir)
def test01_close_dbenv_before_db(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d2 = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
self.assertRaises(db.DBNoSuchFileError, d2.open,
self.filename+"2", db.DB_BTREE, db.DB_THREAD, 0o666)
d.put("test","this is a test")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
dbenv.close() # This "close" should close the child db handle also
self.assertRaises(db.DBError, d.get, "test")
def test02_close_dbenv_before_dbcursor(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
d.put("test","this is a test")
d.put("test2","another test")
d.put("test3","another one")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
c=d.cursor()
c.first()
next(c)
d.close() # This "close" should close the child db handle also
# db.close should close the child cursor
self.assertRaises(db.DBError,c.__next__)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
c=d.cursor()
c.first()
next(c)
dbenv.close()
# The "close" should close the child db handle also, with cursors
self.assertRaises(db.DBError, c.__next__)
def test03_close_db_before_dbcursor_without_env(self):
import os.path
path=os.path.join(self.homeDir,self.filename)
d = db.DB()
d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
d.put("test","this is a test")
d.put("test2","another test")
d.put("test3","another one")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
c=d.cursor()
c.first()
next(c)
d.close()
# The "close" should close the child db handle also
self.assertRaises(db.DBError, c.__next__)
def test04_close_massive(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
dbs=[db.DB(dbenv) for i in range(16)]
cursors=[]
for i in dbs :
i.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbs[10].put("test","this is a test")
dbs[10].put("test2","another test")
dbs[10].put("test3","another one")
self.assertEqual(dbs[4].get("test"), "this is a test", "put!=get")
for i in dbs :
cursors.extend([i.cursor() for j in range(32)])
for i in dbs[::3] :
i.close()
for i in cursors[::3] :
i.close()
# Check for missing exception in DB! (after DB close)
self.assertRaises(db.DBError, dbs[9].get, "test")
# Check for missing exception in DBCursor! (after DB close)
self.assertRaises(db.DBError, cursors[101].first)
cursors[80].first()
next(cursors[80])
dbenv.close() # This "close" should close the child db handle also
# Check for missing exception! (after DBEnv close)
self.assertRaises(db.DBError, cursors[80].__next__)
def test05_close_dbenv_delete_db_success(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbenv.close() # This "close" should close the child db handle also
del d
try:
import gc
except ImportError:
gc = None
if gc:
# force d.__del__ [DB_dealloc] to be called
gc.collect()
def test06_close_txn_before_dup_cursor(self) :
dbenv = db.DBEnv()
dbenv.open(self.homeDir,db.DB_INIT_TXN | db.DB_INIT_MPOOL |
db.DB_INIT_LOG | db.DB_CREATE)
d = db.DB(dbenv)
txn = dbenv.txn_begin()
if db.version() < (4,1) :
d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE)
else :
d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE,
txn=txn)
d.put("XXX", "yyy", txn=txn)
txn.commit()
txn = dbenv.txn_begin()
c1 = d.cursor(txn)
c2 = c1.dup()
self.assertEquals(("XXX", "yyy"), c1.first())
import warnings
# Not interested in warnings about implicit close.
warnings.simplefilter("ignore")
txn.commit()
warnings.resetwarnings()
self.assertRaises(db.DBCursorClosedError, c2.first)
if db.version() > (4,3,0) :
def test07_close_db_before_sequence(self):
import os.path
path=os.path.join(self.homeDir,self.filename)
d = db.DB()
d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbs=db.DBSequence(d)
d.close() # This "close" should close the child DBSequence also
dbs.close() # If not closed, core dump (in Berkeley DB 4.6.*)
#----------------------------------------------------------------------
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(DBEnvClosedEarlyCrash))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
......@@ -2,22 +2,17 @@
TestCases for checking set_get_returns_none.
"""
import sys, os, string
import tempfile
from pprint import pprint
import os, string
import unittest
from bsddb import db
from .test_all import db, verbose, get_new_database_path
from bsddb.test.test_all import verbose
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
#----------------------------------------------------------------------
class GetReturnsNoneTestCase(unittest.TestCase):
def setUp(self):
self.filename = tempfile.mktemp()
self.filename = get_new_database_path()
def tearDown(self):
try:
......@@ -31,25 +26,24 @@ class GetReturnsNoneTestCase(unittest.TestCase):
d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
d.set_get_returns_none(1)
for x in letters:
x = x.encode("ascii")
for x in string.letters:
d.put(x, x * 40)
data = d.get(b'bad key')
assert data == None
data = d.get('bad key')
self.assertEqual(data, None)
data = d.get(b'a')
assert data == b'a'*40
data = d.get(string.letters[0])
self.assertEqual(data, string.letters[0]*40)
count = 0
c = d.cursor()
rec = c.first()
while rec:
count = count + 1
rec = c.next()
rec = next(c)
assert rec == None
assert count == 52
self.assertEqual(rec, None)
self.assertEqual(count, len(string.letters))
c.close()
d.close()
......@@ -60,15 +54,14 @@ class GetReturnsNoneTestCase(unittest.TestCase):
d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
d.set_get_returns_none(0)
for x in letters:
x = x.encode("ascii")
for x in string.letters:
d.put(x, x * 40)
self.assertRaises(db.DBNotFoundError, d.get, b'bad key')
self.assertRaises(KeyError, d.get, b'bad key')
self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
self.assertRaises(KeyError, d.get, 'bad key')
data = d.get(b'a')
assert data == b'a'*40
data = d.get(string.letters[0])
self.assertEqual(data, string.letters[0]*40)
count = 0
exceptionHappened = 0
......@@ -77,14 +70,14 @@ class GetReturnsNoneTestCase(unittest.TestCase):
while rec:
count = count + 1
try:
rec = c.next()
rec = next(c)
except db.DBNotFoundError: # end of the records
exceptionHappened = 1
break
assert rec != None
assert exceptionHappened
assert count == 52
self.assertNotEqual(rec, None)
self.assert_(exceptionHappened)
self.assertEqual(count, len(string.letters))
c.close()
d.close()
......
"""TestCases for using the DB.join and DBCursor.join_item methods.
"""
import shutil
import sys, os
import tempfile
import time
from pprint import pprint
try:
from threading import Thread, current_thread
have_threads = 1
except ImportError:
have_threads = 0
import os
import unittest
from bsddb.test.test_all import verbose
from bsddb import db, dbshelve, StringKeys
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
from .test_all import db, dbshelve, test_support, verbose, \
get_new_environment_path, get_new_database_path
#----------------------------------------------------------------------
......@@ -44,18 +29,12 @@ ColorIndex = [
('black', "shotgun"),
]
def ASCII(s):
return s.encode("ascii")
class JoinTestCase(unittest.TestCase):
keytype = ''
def setUp(self):
self.filename = self.__class__.__name__ + '.db'
homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid())
self.homeDir = homeDir
try: os.mkdir(homeDir)
except os.error: pass
self.homeDir = get_new_environment_path()
self.env = db.DBEnv()
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK )
......@@ -72,13 +51,13 @@ class JoinTestCase(unittest.TestCase):
# create and populate primary index
priDB = db.DB(self.env)
priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
[priDB.put(ASCII(k),ASCII(v)) for k,v in ProductIndex]
list(map(lambda t, priDB=priDB: 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)
[secDB.put(ASCII(k),ASCII(v)) for k,v in ColorIndex]
list(map(lambda t, secDB=secDB: secDB.put(*t), ColorIndex))
sCursor = None
jCursor = None
......@@ -87,19 +66,19 @@ class JoinTestCase(unittest.TestCase):
sCursor = secDB.cursor()
# Don't do the .set() in an assert, or you can get a bogus failure
# when running python -O
tmp = sCursor.set(b'red')
assert tmp
tmp = sCursor.set('red')
self.assert_(tmp)
# 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) != (b'apple', b"Convenience Store"):
if jCursor.get(0) != ('apple', "Convenience Store"):
self.fail("join cursor positioned wrong")
if jCursor.join_item() != b'chainsaw':
if jCursor.join_item() != 'chainsaw':
self.fail("DBCursor.join_item returned wrong item")
if jCursor.get(0)[0] != b'strawberry':
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")
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment