bsddb3 4.2.2, adds DBCursor.get_current_size() method to return the length
of the current value without reading the value itself.
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index 2e6b922..93a7fb7 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -49,6 +49,8 @@
     envflags     = 0
     envsetflags  = 0
 
+    _numKeys      = 1002    # PRIVATE.  NOTE: must be an even value
+
     def setUp(self):
         if self.useEnv:
             homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
@@ -106,17 +108,23 @@
 
 
 
-    def populateDB(self):
+    def populateDB(self, _txn=None):
         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
             data = self.makeData(key)
-            d.put(key, data)
+            d.put(key, data, _txn)
+
+        if _txn:
+            _txn.commit()
 
         num = len(d)
         if verbose:
@@ -236,20 +244,20 @@
             if verbose:
                 print data
 
-        assert len(d) == 1000
+        assert len(d) == self._numKeys
         keys = d.keys()
-        assert len(keys) == 1000
+        assert len(keys) == self._numKeys
         assert type(keys) == type([])
 
         d['new record'] = 'a new record'
-        assert len(d) == 1001
+        assert len(d) == self._numKeys+1
         keys = d.keys()
-        assert len(keys) == 1001
+        assert len(keys) == self._numKeys+1
 
         d['new record'] = 'a replacement record'
-        assert len(d) == 1001
+        assert len(d) == self._numKeys+1
         keys = d.keys()
-        assert len(keys) == 1001
+        assert len(keys) == self._numKeys+1
 
         if verbose:
             print "the first 10 keys are:"
@@ -261,7 +269,7 @@
         assert d.has_key('spam') == 0
 
         items = d.items()
-        assert len(items) == 1001
+        assert len(items) == self._numKeys+1
         assert type(items) == type([])
         assert type(items[0]) == type(())
         assert len(items[0]) == 2
@@ -271,7 +279,7 @@
             pprint(items[:10])
 
         values = d.values()
-        assert len(values) == 1001
+        assert len(values) == self._numKeys+1
         assert type(values) == type([])
 
         if verbose:
@@ -293,7 +301,7 @@
         else:
             txn = None
         c = self.d.cursor(txn=txn)
-
+        
         rec = c.first()
         count = 0
         while rec is not None:
@@ -309,8 +317,9 @@
                     rec = None
                 else:
                     self.fail("unexpected DBNotFoundError")
-
-        assert count == 1000
+            assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
+        
+        assert count == self._numKeys
 
 
         rec = c.last()
@@ -329,14 +338,20 @@
                 else:
                     self.fail("unexpected DBNotFoundError")
 
-        assert count == 1000
+        assert count == self._numKeys
 
         rec = c.set('0505')
         rec2 = c.current()
         assert rec == rec2
         assert rec[0] == '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:
             n = c.set('bad key')
         except db.DBNotFoundError, val:
@@ -575,23 +590,8 @@
 
 
     def populateDB(self):
-        d = self.d
         txn = self.env.txn_begin()
-        for x in range(500):
-            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
+        BasicTestCase.populateDB(self, _txn=txn)
 
         self.txn = self.env.txn_begin()
 
@@ -626,7 +626,7 @@
             if verbose and count % 100 == 0:
                 print rec
             rec = c.next()
-        assert count == 1001
+        assert count == self._numKeys+1
 
         c.close()                # Cursors *MUST* be closed before commit!
         self.txn.commit()
@@ -855,7 +855,7 @@
             if verbose and (count % 50) == 0:
                 print rec
             rec = c1.next()
-        assert count == 1000
+        assert count == self._numKeys
 
         count = 0
         rec = c2.first()
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index c6b569c..e705526 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -93,7 +93,7 @@
 /* 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 PY_BSDDB_VERSION "4.2.1"
+#define PY_BSDDB_VERSION "4.2.2"
 static char *rcs_id = "$Id$";
 
 
@@ -2981,6 +2981,39 @@
                 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*
 DBC_set_both(DBCursorObject* self, PyObject* args)
 {
@@ -4079,6 +4112,7 @@
     {"set",             (PyCFunction)DBC_set,           METH_VARARGS|METH_KEYWORDS},
     {"set_range",       (PyCFunction)DBC_set_range,     METH_VARARGS|METH_KEYWORDS},
     {"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_recno",       (PyCFunction)DBC_set_recno,     METH_VARARGS|METH_KEYWORDS},
     {"consume",         (PyCFunction)DBC_consume,       METH_VARARGS|METH_KEYWORDS},