bsddb3 4.2.2, adds DBCursor.get_current_size() method to return the length
of the current value without reading the value itself.
This commit is contained in:
parent
efb3a161c3
commit
be0db8b125
|
@ -49,6 +49,8 @@ class BasicTestCase(unittest.TestCase):
|
||||||
envflags = 0
|
envflags = 0
|
||||||
envsetflags = 0
|
envsetflags = 0
|
||||||
|
|
||||||
|
_numKeys = 1002 # PRIVATE. NOTE: must be an even value
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
if self.useEnv:
|
if self.useEnv:
|
||||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||||
|
@ -106,17 +108,23 @@ class BasicTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def populateDB(self):
|
def populateDB(self, _txn=None):
|
||||||
d = self.d
|
d = self.d
|
||||||
for x in range(500):
|
|
||||||
key = '%04d' % (1000 - x) # insert keys in reverse order
|
|
||||||
data = self.makeData(key)
|
|
||||||
d.put(key, data)
|
|
||||||
|
|
||||||
for x in range(500):
|
for x in range(self._numKeys/2):
|
||||||
|
key = '%04d' % (self._numKeys - x) # insert keys in reverse order
|
||||||
|
data = self.makeData(key)
|
||||||
|
d.put(key, data, _txn)
|
||||||
|
|
||||||
|
d.put('empty value', '', _txn)
|
||||||
|
|
||||||
|
for x in range(self._numKeys/2-1):
|
||||||
key = '%04d' % x # and now some in forward order
|
key = '%04d' % x # and now some in forward order
|
||||||
data = self.makeData(key)
|
data = self.makeData(key)
|
||||||
d.put(key, data)
|
d.put(key, data, _txn)
|
||||||
|
|
||||||
|
if _txn:
|
||||||
|
_txn.commit()
|
||||||
|
|
||||||
num = len(d)
|
num = len(d)
|
||||||
if verbose:
|
if verbose:
|
||||||
|
@ -236,20 +244,20 @@ class BasicTestCase(unittest.TestCase):
|
||||||
if verbose:
|
if verbose:
|
||||||
print data
|
print data
|
||||||
|
|
||||||
assert len(d) == 1000
|
assert len(d) == self._numKeys
|
||||||
keys = d.keys()
|
keys = d.keys()
|
||||||
assert len(keys) == 1000
|
assert len(keys) == self._numKeys
|
||||||
assert type(keys) == type([])
|
assert type(keys) == type([])
|
||||||
|
|
||||||
d['new record'] = 'a new record'
|
d['new record'] = 'a new record'
|
||||||
assert len(d) == 1001
|
assert len(d) == self._numKeys+1
|
||||||
keys = d.keys()
|
keys = d.keys()
|
||||||
assert len(keys) == 1001
|
assert len(keys) == self._numKeys+1
|
||||||
|
|
||||||
d['new record'] = 'a replacement record'
|
d['new record'] = 'a replacement record'
|
||||||
assert len(d) == 1001
|
assert len(d) == self._numKeys+1
|
||||||
keys = d.keys()
|
keys = d.keys()
|
||||||
assert len(keys) == 1001
|
assert len(keys) == self._numKeys+1
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print "the first 10 keys are:"
|
print "the first 10 keys are:"
|
||||||
|
@ -261,7 +269,7 @@ class BasicTestCase(unittest.TestCase):
|
||||||
assert d.has_key('spam') == 0
|
assert d.has_key('spam') == 0
|
||||||
|
|
||||||
items = d.items()
|
items = d.items()
|
||||||
assert len(items) == 1001
|
assert len(items) == self._numKeys+1
|
||||||
assert type(items) == type([])
|
assert type(items) == type([])
|
||||||
assert type(items[0]) == type(())
|
assert type(items[0]) == type(())
|
||||||
assert len(items[0]) == 2
|
assert len(items[0]) == 2
|
||||||
|
@ -271,7 +279,7 @@ class BasicTestCase(unittest.TestCase):
|
||||||
pprint(items[:10])
|
pprint(items[:10])
|
||||||
|
|
||||||
values = d.values()
|
values = d.values()
|
||||||
assert len(values) == 1001
|
assert len(values) == self._numKeys+1
|
||||||
assert type(values) == type([])
|
assert type(values) == type([])
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
|
@ -293,7 +301,7 @@ class BasicTestCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
txn = None
|
txn = None
|
||||||
c = self.d.cursor(txn=txn)
|
c = self.d.cursor(txn=txn)
|
||||||
|
|
||||||
rec = c.first()
|
rec = c.first()
|
||||||
count = 0
|
count = 0
|
||||||
while rec is not None:
|
while rec is not None:
|
||||||
|
@ -309,8 +317,9 @@ class BasicTestCase(unittest.TestCase):
|
||||||
rec = None
|
rec = None
|
||||||
else:
|
else:
|
||||||
self.fail("unexpected DBNotFoundError")
|
self.fail("unexpected DBNotFoundError")
|
||||||
|
assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
|
||||||
assert count == 1000
|
|
||||||
|
assert count == self._numKeys
|
||||||
|
|
||||||
|
|
||||||
rec = c.last()
|
rec = c.last()
|
||||||
|
@ -329,14 +338,20 @@ class BasicTestCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.fail("unexpected DBNotFoundError")
|
self.fail("unexpected DBNotFoundError")
|
||||||
|
|
||||||
assert count == 1000
|
assert count == self._numKeys
|
||||||
|
|
||||||
rec = c.set('0505')
|
rec = c.set('0505')
|
||||||
rec2 = c.current()
|
rec2 = c.current()
|
||||||
assert rec == rec2
|
assert rec == rec2
|
||||||
assert rec[0] == '0505'
|
assert rec[0] == '0505'
|
||||||
assert rec[1] == self.makeData('0505')
|
assert rec[1] == self.makeData('0505')
|
||||||
|
assert c.get_current_size() == len(rec[1])
|
||||||
|
|
||||||
|
# make sure we get empty values properly
|
||||||
|
rec = c.set('empty value')
|
||||||
|
assert rec[1] == ''
|
||||||
|
assert c.get_current_size() == 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
n = c.set('bad key')
|
n = c.set('bad key')
|
||||||
except db.DBNotFoundError, val:
|
except db.DBNotFoundError, val:
|
||||||
|
@ -575,23 +590,8 @@ class BasicTransactionTestCase(BasicTestCase):
|
||||||
|
|
||||||
|
|
||||||
def populateDB(self):
|
def populateDB(self):
|
||||||
d = self.d
|
|
||||||
txn = self.env.txn_begin()
|
txn = self.env.txn_begin()
|
||||||
for x in range(500):
|
BasicTestCase.populateDB(self, _txn=txn)
|
||||||
key = '%04d' % (1000 - x) # insert keys in reverse order
|
|
||||||
data = self.makeData(key)
|
|
||||||
d.put(key, data, txn)
|
|
||||||
|
|
||||||
for x in range(500):
|
|
||||||
key = '%04d' % x # and now some in forward order
|
|
||||||
data = self.makeData(key)
|
|
||||||
d.put(key, data, txn)
|
|
||||||
|
|
||||||
txn.commit()
|
|
||||||
|
|
||||||
num = len(d)
|
|
||||||
if verbose:
|
|
||||||
print "created %d records" % num
|
|
||||||
|
|
||||||
self.txn = self.env.txn_begin()
|
self.txn = self.env.txn_begin()
|
||||||
|
|
||||||
|
@ -626,7 +626,7 @@ class BasicTransactionTestCase(BasicTestCase):
|
||||||
if verbose and count % 100 == 0:
|
if verbose and count % 100 == 0:
|
||||||
print rec
|
print rec
|
||||||
rec = c.next()
|
rec = c.next()
|
||||||
assert count == 1001
|
assert count == self._numKeys+1
|
||||||
|
|
||||||
c.close() # Cursors *MUST* be closed before commit!
|
c.close() # Cursors *MUST* be closed before commit!
|
||||||
self.txn.commit()
|
self.txn.commit()
|
||||||
|
@ -855,7 +855,7 @@ class BasicMultiDBTestCase(BasicTestCase):
|
||||||
if verbose and (count % 50) == 0:
|
if verbose and (count % 50) == 0:
|
||||||
print rec
|
print rec
|
||||||
rec = c1.next()
|
rec = c1.next()
|
||||||
assert count == 1000
|
assert count == self._numKeys
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
rec = c2.first()
|
rec = c2.first()
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
|
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
|
||||||
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
|
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
|
||||||
|
|
||||||
#define PY_BSDDB_VERSION "4.2.1"
|
#define PY_BSDDB_VERSION "4.2.2"
|
||||||
static char *rcs_id = "$Id$";
|
static char *rcs_id = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
|
@ -2981,6 +2981,39 @@ DBC_get_both(DBCursorObject* self, PyObject* args)
|
||||||
self->mydb->moduleFlags.getReturnsNone);
|
self->mydb->moduleFlags.getReturnsNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return size of entry */
|
||||||
|
static PyObject*
|
||||||
|
DBC_get_current_size(DBCursorObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
int err, flags=DB_CURRENT;
|
||||||
|
PyObject* retval = NULL;
|
||||||
|
DBT key, data;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, ":get_current_size"))
|
||||||
|
return NULL;
|
||||||
|
CHECK_CURSOR_NOT_CLOSED(self);
|
||||||
|
CLEAR_DBT(key);
|
||||||
|
CLEAR_DBT(data);
|
||||||
|
|
||||||
|
/* We don't allocate any memory, forcing a ENOMEM error and thus
|
||||||
|
getting the record size. */
|
||||||
|
data.flags = DB_DBT_USERMEM;
|
||||||
|
data.ulen = 0;
|
||||||
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
|
err = self->dbc->c_get(self->dbc, &key, &data, flags);
|
||||||
|
MYDB_END_ALLOW_THREADS;
|
||||||
|
if (err == ENOMEM || !err) {
|
||||||
|
/* ENOMEM means positive size, !err means zero length value */
|
||||||
|
retval = PyInt_FromLong((long)data.size);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_DBT(key);
|
||||||
|
FREE_DBT(data);
|
||||||
|
RETURN_IF_ERR();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
DBC_set_both(DBCursorObject* self, PyObject* args)
|
DBC_set_both(DBCursorObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
|
@ -4079,6 +4112,7 @@ static PyMethodDef DBCursor_methods[] = {
|
||||||
{"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
|
{"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
|
||||||
{"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
|
{"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
|
||||||
{"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
|
{"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
|
||||||
|
{"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
|
||||||
{"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
|
{"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
|
||||||
{"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
|
{"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
|
||||||
{"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
|
{"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
|
||||||
|
|
Loading…
Reference in New Issue