Fix test_bsddb3.

This commit is contained in:
Martin v. Löwis 2007-08-11 06:13:20 +00:00
parent 2cde0eb922
commit 32ca442b13
3 changed files with 64 additions and 62 deletions

View File

@ -27,14 +27,10 @@ import pickle
from bsddb.db import * from bsddb.db import *
# All table names, row names etc. must be ASCII strings # All table names, row names etc. must be ASCII strings
# However, rowids, when represented as strings, are latin-1 encoded
def _E(s): def _E(s):
return s.encode("ascii") return s.encode("ascii")
# Yet, rowid are arbitrary bytes; if there is a need to hash
# them, convert them to Latin-1 first
def _D(s):
return s.decode("latin-1")
# XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c # XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
try: try:
DBIncompleteError DBIncompleteError
@ -55,22 +51,22 @@ class Cond:
class ExactCond(Cond): class ExactCond(Cond):
"""Acts as an exact match condition function""" """Acts as an exact match condition function"""
def __init__(self, strtomatch): def __init__(self, strtomatch, encoding="utf-8"):
self.strtomatch = strtomatch self.strtomatch = strtomatch.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s == self.strtomatch return s == self.strtomatch
class PrefixCond(Cond): class PrefixCond(Cond):
"""Acts as a condition function for matching a string prefix""" """Acts as a condition function for matching a string prefix"""
def __init__(self, prefix): def __init__(self, prefix, encoding="utf-8"):
self.prefix = prefix self.prefix = prefix.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s[:len(self.prefix)] == self.prefix return s[:len(self.prefix)] == self.prefix
class PostfixCond(Cond): class PostfixCond(Cond):
"""Acts as a condition function for matching a string postfix""" """Acts as a condition function for matching a string postfix"""
def __init__(self, postfix): def __init__(self, postfix, encoding="utf-8"):
self.postfix = postfix self.postfix = postfix.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s[-len(self.postfix):] == self.postfix return s[-len(self.postfix):] == self.postfix
@ -80,7 +76,7 @@ class LikeCond(Cond):
string. Case insensitive and % signs are wild cards. string. Case insensitive and % signs are wild cards.
This isn't perfect but it should work for the simple common cases. This isn't perfect but it should work for the simple common cases.
""" """
def __init__(self, likestr, re_flags=re.IGNORECASE): def __init__(self, likestr, re_flags=re.IGNORECASE, encoding="utf-8"):
# escape python re characters # escape python re characters
chars_to_escape = '.*+()[]?' chars_to_escape = '.*+()[]?'
for char in chars_to_escape : for char in chars_to_escape :
@ -88,8 +84,9 @@ class LikeCond(Cond):
# convert %s to wildcards # convert %s to wildcards
self.likestr = likestr.replace('%', '.*') self.likestr = likestr.replace('%', '.*')
self.re = re.compile('^'+self.likestr+'$', re_flags) self.re = re.compile('^'+self.likestr+'$', re_flags)
self.encoding = encoding
def __call__(self, s): def __call__(self, s):
return self.re.match(s) return self.re.match(s.decode(self.encoding))
# #
# keys used to store database metadata # keys used to store database metadata
@ -264,10 +261,11 @@ class bsdTableDB :
txn.commit() txn.commit()
txn = None txn = None
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1] txn = None
def ListTableColumns(self, table): def ListTableColumns(self, table):
"""Return a list of columns in the given table. """Return a list of columns in the given table.
@ -342,9 +340,10 @@ class bsdTableDB :
self.__load_column_info(table) self.__load_column_info(table)
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1]
def __load_column_info(self, table) : def __load_column_info(self, table) :
@ -419,7 +418,11 @@ class bsdTableDB :
if txn: if txn:
txn.abort() txn.abort()
self.db.delete(_rowid_key(table, rowid)) self.db.delete(_rowid_key(table, rowid))
txn = None
raise TableDBError, dberror.args[1], info[2] raise TableDBError, dberror.args[1], info[2]
finally:
if txn:
txn.abort()
def Modify(self, table, conditions={}, mappings={}): def Modify(self, table, conditions={}, mappings={}):
@ -465,10 +468,9 @@ class bsdTableDB :
txn = None txn = None
# catch all exceptions here since we call unknown callables # catch all exceptions here since we call unknown callables
except: finally:
if txn: if txn:
txn.abort() txn.abort()
raise
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1] raise TableDBError, dberror.args[1]
@ -493,23 +495,23 @@ class bsdTableDB :
for column in columns: for column in columns:
# delete the data key # delete the data key
try: try:
self.db.delete(_data_key(table, column, rowid), self.db.delete(_data_key(table, column,
rowid.encode("latin-1")),
txn) txn)
except DBNotFoundError: except DBNotFoundError:
# XXXXXXX column may not exist, assume no error # XXXXXXX column may not exist, assume no error
pass pass
try: try:
self.db.delete(_rowid_key(table, rowid), txn) self.db.delete(_rowid_key(table, rowid.encode("latin-1")), txn)
except DBNotFoundError: except DBNotFoundError:
# XXXXXXX row key somehow didn't exist, assume no error # XXXXXXX row key somehow didn't exist, assume no error
pass pass
txn.commit() txn.commit()
txn = None txn = None
except DBError as dberror: finally:
if txn: if txn:
txn.abort() txn.abort()
raise
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1] raise TableDBError, dberror.args[1]
@ -603,7 +605,7 @@ class bsdTableDB :
key, data = cur.set_range(searchkey) key, data = cur.set_range(searchkey)
while key[:len(searchkey)] == searchkey: while key[:len(searchkey)] == searchkey:
# extract the rowid from the key # extract the rowid from the key
rowid = _D(key[-_rowid_str_len:]) rowid = key[-_rowid_str_len:].decode("latin-1")
if rowid not in rejected_rowids: if rowid not in rejected_rowids:
# if no condition was specified or the condition # if no condition was specified or the condition
@ -706,6 +708,7 @@ class bsdTableDB :
del self.__tablecolumns[table] del self.__tablecolumns[table]
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1]

View File

@ -79,7 +79,7 @@ class TableDBTestCase(unittest.TestCase):
values = list(values) values = list(values)
colval = pickle.loads(values[0][colname]) colval = pickle.loads(values[0][colname])
assert(colval > 3.141 and colval < 3.142) self.assertTrue(colval > 3.141 and colval < 3.142)
def test02(self): def test02(self):
@ -105,11 +105,11 @@ class TableDBTestCase(unittest.TestCase):
conditions={col0: lambda x: pickle.loads(x) >= 8}) conditions={col0: lambda x: pickle.loads(x) >= 8})
values = list(values) values = list(values)
assert len(values) == 2 self.assertEquals(len(values), 2)
if values[0]['Species'] == 'Penguin' : if values[0]['Species'] == b'Penguin' :
assert values[1]['Species'] == 'SR-71A Blackbird' self.assertEquals(values[1]['Species'], b'SR-71A Blackbird')
elif values[0]['Species'] == 'SR-71A Blackbird' : elif values[0]['Species'] == b'SR-71A Blackbird' :
assert values[1]['Species'] == 'Penguin' self.assertEquals(values[1]['Species'], b'Penguin')
else : else :
if verbose: if verbose:
print("values= %r" % (values,)) print("values= %r" % (values,))
@ -139,13 +139,13 @@ class TableDBTestCase(unittest.TestCase):
{'a': "", {'a': "",
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
'f': "Zero"}) 'f': "Zero"})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
try: try:
self.tdb.Select(tabname, [], conditions={'foo': '123'}) self.tdb.Select(tabname, [], conditions={'foo': '123'})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
@ -174,7 +174,7 @@ class TableDBTestCase(unittest.TestCase):
values = self.tdb.Select(tabname, ['b', 'a', 'd'], values = self.tdb.Select(tabname, ['b', 'a', 'd'],
conditions={'e': re.compile('wuzzy').search, conditions={'e': re.compile('wuzzy').search,
'a': re.compile('^[0-9]+$').match}) 'a': re.compile('^[0-9]+$').match})
assert len(values) == 2 self.assertEquals(len(values), 2)
# now lets delete one of them and try again # now lets delete one of them and try again
self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')}) self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')})
@ -182,14 +182,14 @@ class TableDBTestCase(unittest.TestCase):
tabname, ['a', 'd', 'b'], tabname, ['a', 'd', 'b'],
conditions={'e': dbtables.PrefixCond('Fuzzy')}) conditions={'e': dbtables.PrefixCond('Fuzzy')})
values = list(values) values = list(values)
assert len(values) == 1 self.assertEquals(len(values), 1)
assert values[0]['d'] == None self.assertEquals(values[0]['d'], None)
values = self.tdb.Select(tabname, ['b'], values = self.tdb.Select(tabname, ['b'],
conditions={'c': lambda c: c == 'meep'}) conditions={'c': lambda c: c.decode("ascii") == 'meep'})
values = list(values) values = list(values)
assert len(values) == 1 self.assertEquals(len(values), 1)
assert values[0]['b'] == "bad" self.assertEquals(values[0]['b'], b"bad")
def test04_MultiCondSelect(self): def test04_MultiCondSelect(self):
@ -205,7 +205,7 @@ class TableDBTestCase(unittest.TestCase):
{'a': "", {'a': "",
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
'f': "Zero"}) 'f': "Zero"})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
@ -229,7 +229,7 @@ class TableDBTestCase(unittest.TestCase):
'a': dbtables.ExactCond('A'), 'a': dbtables.ExactCond('A'),
'd': dbtables.PrefixCond('-') 'd': dbtables.PrefixCond('-')
} ) } )
assert len(values) == 0, values self.assertEquals(len(values), 0, values)
def test_CreateOrExtend(self): def test_CreateOrExtend(self):
@ -242,7 +242,7 @@ class TableDBTestCase(unittest.TestCase):
{'taste': 'crap', {'taste': 'crap',
'filling': 'no', 'filling': 'no',
'is it Guinness?': 'no'}) 'is it Guinness?': 'no'})
assert 0, "Insert should've failed due to bad column name" self.fail("Insert should've failed due to bad column name")
except: except:
pass pass
self.tdb.CreateOrExtendTable(tabname, self.tdb.CreateOrExtendTable(tabname,
@ -277,17 +277,17 @@ class TableDBTestCase(unittest.TestCase):
tabname, ['p', 'e'], tabname, ['p', 'e'],
conditions={'e': dbtables.PrefixCond('the l')}) conditions={'e': dbtables.PrefixCond('the l')})
values = list(values) values = list(values)
assert len(values) == 2, values self.assertEquals(len(values), 2)
assert values[0]['e'] == values[1]['e'], values self.assertEquals(values[0]['e'], values[1]['e'])
assert values[0]['p'] != values[1]['p'], values self.assertNotEquals(values[0]['p'], values[1]['p'])
values = self.tdb.Select( values = self.tdb.Select(
tabname, ['d', 'a'], tabname, ['d', 'a'],
conditions={'a': dbtables.LikeCond('%aardvark%')}) conditions={'a': dbtables.LikeCond('%aardvark%')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['d'] == "is for dog", values self.assertEquals(values[0]['d'], b"is for dog")
assert values[0]['a'] == "is for aardvark", values self.assertEquals(values[0]['a'], b"is for aardvark")
values = self.tdb.Select(tabname, None, values = self.tdb.Select(tabname, None,
{'b': dbtables.Cond(), {'b': dbtables.Cond(),
@ -297,9 +297,9 @@ class TableDBTestCase(unittest.TestCase):
'c':dbtables.PrefixCond('is for'), 'c':dbtables.PrefixCond('is for'),
'p':lambda s: not s}) 'p':lambda s: not s})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['d'] == "is for dog", values self.assertEquals(values[0]['d'], b"is for dog")
assert values[0]['a'] == "is for aardvark", values self.assertEquals(values[0]['a'], b"is for aardvark")
def test_Delete(self): def test_Delete(self):
tabname = "test_Delete" tabname = "test_Delete"
@ -315,7 +315,7 @@ class TableDBTestCase(unittest.TestCase):
self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')}) self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')})
values = self.tdb.Select(tabname, ['y'], values = self.tdb.Select(tabname, ['y'],
conditions={'x': dbtables.PrefixCond('X')}) conditions={'x': dbtables.PrefixCond('X')})
assert len(values) == 0 self.assertEquals(len(values), 0)
def test_Modify(self): def test_Modify(self):
tabname = "test_Modify" tabname = "test_Modify"
@ -362,26 +362,26 @@ class TableDBTestCase(unittest.TestCase):
tabname, None, tabname, None,
conditions={'Type': dbtables.ExactCond('Unknown')}) conditions={'Type': dbtables.ExactCond('Unknown')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Name'] == None, values self.assertEquals(values[0]['Name'], None)
assert values[0]['Access'] == None, values self.assertEquals(values[0]['Access'], None)
# Modify value by select conditions # Modify value by select conditions
values = self.tdb.Select( values = self.tdb.Select(
tabname, None, tabname, None,
conditions={'Name': dbtables.ExactCond('Nifty.MP3')}) conditions={'Name': dbtables.ExactCond('Nifty.MP3')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Type'] == "MP3", values self.assertEquals(values[0]['Type'], b"MP3")
assert values[0]['Access'] == "2", values self.assertEquals(values[0]['Access'], b"2")
# Make sure change applied only to select conditions # Make sure change applied only to select conditions
values = self.tdb.Select( values = self.tdb.Select(
tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')}) tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Type'] == "Word", values self.assertEquals(values[0]['Type'], b"Word")
assert values[0]['Access'] == "9", values self.assertEquals(values[0]['Access'], b"9")
def test_suite(): def test_suite():

View File

@ -24,8 +24,7 @@ if 'silent' in sys.argv: # take care of old flag, just in case
def suite(): def suite():
try: try:
# this is special, it used to segfault the interpreter # this is special, it used to segfault the interpreter
#import bsddb.test.test_1413192 import bsddb.test.test_1413192
pass
except: except:
for f in ['__db.001', '__db.002', '__db.003', 'log.0000000001']: for f in ['__db.001', '__db.002', '__db.003', 'log.0000000001']:
unlink(f) unlink(f)