diff options
-rw-r--r-- | Lib/bsddb/__init__.py | 2 | ||||
-rw-r--r-- | Lib/bsddb/test/test_basics.py | 7 | ||||
-rw-r--r-- | Lib/bsddb/test/test_compat.py | 24 | ||||
-rw-r--r-- | Modules/_bsddb.c | 12 |
4 files changed, 39 insertions, 6 deletions
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py index 9c59b00..90bf92b 100644 --- a/Lib/bsddb/__init__.py +++ b/Lib/bsddb/__init__.py @@ -244,7 +244,7 @@ class _DBWithCursor(_iter_mixin): def set_location(self, key): self._checkOpen() self._checkCursor() - return self.dbc.set(key) + return self.dbc.set_range(key) def next(self): self._checkOpen() diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py index da7e18f..09571ab 100644 --- a/Lib/bsddb/test/test_basics.py +++ b/Lib/bsddb/test/test_basics.py @@ -385,7 +385,12 @@ class BasicTestCase(unittest.TestCase): rec = c.set_range('011',dlen=0,doff=0) if verbose: print "searched (partial) for '011', found: ", rec - if rec[1] != '': set.fail('expected empty data portion') + if rec[1] != '': self.fail('expected empty data portion') + + ev = c.set_range('empty value') + if verbose: + print "search for 'empty value' returned", ev + if ev[1] != '': self.fail('empty value lookup failed') c.set('0499') c.delete() diff --git a/Lib/bsddb/test/test_compat.py b/Lib/bsddb/test/test_compat.py index 12464ca..b108db4 100644 --- a/Lib/bsddb/test/test_compat.py +++ b/Lib/bsddb/test/test_compat.py @@ -49,6 +49,10 @@ class CompatibilityTestCase(unittest.TestCase): assert getTest[1] == 'quick', 'data mismatch!' + rv = f.set_location(3) + if rv != (3, 'brown'): + self.fail('recno database set_location failed: '+repr(rv)) + f[25] = 'twenty-five' f.close() del f @@ -83,7 +87,6 @@ class CompatibilityTestCase(unittest.TestCase): f.close() - def do_bthash_test(self, factory, what): if verbose: print '\nTesting: ', what @@ -103,13 +106,16 @@ class CompatibilityTestCase(unittest.TestCase): f['b'] = 'van' f['c'] = 'Rossum' f['d'] = 'invented' + # 'e' intentionally left out f['f'] = 'Python' if verbose: print '%s %s %s' % (f['a'], f['b'], f['c']) if verbose: print 'key ordering...' - f.set_location(f.first()[0]) + start = f.set_location(f.first()[0]) + if start != ('0', ''): + self.fail("incorrect first() result: "+repr(start)) while 1: try: rec = f.next() @@ -122,6 +128,20 @@ class CompatibilityTestCase(unittest.TestCase): assert f.has_key('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('e') + if e != ('f', 'Python'): + self.fail('wrong key,value returned: '+repr(e)) + else: + try: + e = f.set_location('e') + except KeyError: + pass + else: + self.fail("set_location on non-existant key did not raise KeyError") + f.sync() f.close() # truth test diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index a503a80..fcfcbd4 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -97,7 +97,7 @@ #error "eek! DBVER can't handle minor versions > 9" #endif -#define PY_BSDDB_VERSION "4.2.4" +#define PY_BSDDB_VERSION "4.2.5" static char *rcs_id = "$Id$"; @@ -2940,7 +2940,15 @@ DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs) data.data, data.size); break; } - FREE_DBT(key); + if (_DB_get_type(self->mydb) == DB_BTREE) { + /* the only time a malloced key is returned is when we + * call this on a BTree database because it performs + * partial matching and needs to return the real key. + * All others leave key untouched [where calling free() + * on it would often segfault]. + */ + FREE_DBT(key); + } FREE_DBT(data); } |