summaryrefslogtreecommitdiffstats
path: root/Lib/bsddb
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/bsddb')
-rw-r--r--Lib/bsddb/__init__.py64
-rw-r--r--Lib/bsddb/dbrecio.py6
-rw-r--r--Lib/bsddb/dbtables.py6
-rw-r--r--Lib/bsddb/dbutils.py6
-rw-r--r--Lib/bsddb/test/test_basics.py37
5 files changed, 79 insertions, 40 deletions
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py
index 90ed362..cf32668 100644
--- a/Lib/bsddb/__init__.py
+++ b/Lib/bsddb/__init__.py
@@ -33,7 +33,10 @@
#----------------------------------------------------------------------
-"""Support for BerkeleyDB 3.2 through 4.2.
+"""Support for BerkeleyDB 3.3 through 4.4 with a simple interface.
+
+For the full featured object oriented interface use the bsddb.db module
+instead. It mirrors the Sleepycat BerkeleyDB C API.
"""
try:
@@ -43,8 +46,10 @@ try:
# python as bsddb._bsddb.
import _pybsddb
_bsddb = _pybsddb
+ from bsddb3.dbutils import DeadlockWrap as _DeadlockWrap
else:
import _bsddb
+ from bsddb.dbutils import DeadlockWrap as _DeadlockWrap
except ImportError:
# Remove ourselves from sys.modules
import sys
@@ -70,7 +75,7 @@ if sys.version >= '2.3':
exec """
class _iter_mixin(UserDict.DictMixin):
def _make_iter_cursor(self):
- cur = self.db.cursor()
+ cur = _DeadlockWrap(self.db.cursor)
key = id(cur)
self._cursor_refs[key] = ref(cur, self._gen_cref_cleaner(key))
return cur
@@ -90,19 +95,19 @@ class _iter_mixin(UserDict.DictMixin):
# since we're only returning keys, we call the cursor
# methods with flags=0, dlen=0, dofs=0
- key = cur.first(0,0,0)[0]
+ key = _DeadlockWrap(cur.first, 0,0,0)[0]
yield key
next = cur.next
while 1:
try:
- key = next(0,0,0)[0]
+ key = _DeadlockWrap(next, 0,0,0)[0]
yield key
except _bsddb.DBCursorClosedError:
cur = self._make_iter_cursor()
# FIXME-20031101-greg: race condition. cursor could
# be closed by another thread before this call.
- cur.set(key,0,0,0)
+ _DeadlockWrap(cur.set, key,0,0,0)
next = cur.next
except _bsddb.DBNotFoundError:
return
@@ -119,21 +124,21 @@ class _iter_mixin(UserDict.DictMixin):
# FIXME-20031102-greg: race condition. cursor could
# be closed by another thread before this call.
- kv = cur.first()
+ kv = _DeadlockWrap(cur.first)
key = kv[0]
yield kv
next = cur.next
while 1:
try:
- kv = next()
+ kv = _DeadlockWrap(next)
key = kv[0]
yield kv
except _bsddb.DBCursorClosedError:
cur = self._make_iter_cursor()
# FIXME-20031101-greg: race condition. cursor could
# be closed by another thread before this call.
- cur.set(key,0,0,0)
+ _DeadlockWrap(cur.set, key,0,0,0)
next = cur.next
except _bsddb.DBNotFoundError:
return
@@ -177,9 +182,9 @@ class _DBWithCursor(_iter_mixin):
def _checkCursor(self):
if self.dbc is None:
- self.dbc = self.db.cursor()
+ self.dbc = _DeadlockWrap(self.db.cursor)
if self.saved_dbc_key is not None:
- self.dbc.set(self.saved_dbc_key)
+ _DeadlockWrap(self.dbc.set, self.saved_dbc_key)
self.saved_dbc_key = None
# This method is needed for all non-cursor DB calls to avoid
@@ -192,15 +197,15 @@ class _DBWithCursor(_iter_mixin):
self.dbc = None
if save:
try:
- self.saved_dbc_key = c.current(0,0,0)[0]
+ self.saved_dbc_key = _DeadlockWrap(c.current, 0,0,0)[0]
except db.DBError:
pass
- c.close()
+ _DeadlockWrap(c.close)
del c
for cref in self._cursor_refs.values():
c = cref()
if c is not None:
- c.close()
+ _DeadlockWrap(c.close)
def _checkOpen(self):
if self.db is None:
@@ -211,73 +216,77 @@ class _DBWithCursor(_iter_mixin):
def __len__(self):
self._checkOpen()
- return len(self.db)
+ return _DeadlockWrap(lambda: len(self.db)) # len(self.db)
def __getitem__(self, key):
self._checkOpen()
- return self.db[key]
+ return _DeadlockWrap(lambda: self.db[key]) # self.db[key]
def __setitem__(self, key, value):
self._checkOpen()
self._closeCursors()
- self.db[key] = value
+ def wrapF():
+ self.db[key] = value
+ _DeadlockWrap(wrapF) # self.db[key] = value
def __delitem__(self, key):
self._checkOpen()
self._closeCursors()
- del self.db[key]
+ def wrapF():
+ del self.db[key]
+ _DeadlockWrap(wrapF) # del self.db[key]
def close(self):
self._closeCursors(save=0)
if self.dbc is not None:
- self.dbc.close()
+ _DeadlockWrap(self.dbc.close)
v = 0
if self.db is not None:
- v = self.db.close()
+ v = _DeadlockWrap(self.db.close)
self.dbc = None
self.db = None
return v
def keys(self):
self._checkOpen()
- return self.db.keys()
+ return _DeadlockWrap(self.db.keys)
def has_key(self, key):
self._checkOpen()
- return self.db.has_key(key)
+ return _DeadlockWrap(self.db.has_key, key)
def set_location(self, key):
self._checkOpen()
self._checkCursor()
- return self.dbc.set_range(key)
+ return _DeadlockWrap(self.dbc.set_range, key)
def next(self):
self._checkOpen()
self._checkCursor()
- rv = self.dbc.next()
+ rv = _DeadlockWrap(self.dbc.next)
return rv
def previous(self):
self._checkOpen()
self._checkCursor()
- rv = self.dbc.prev()
+ rv = _DeadlockWrap(self.dbc.prev)
return rv
def first(self):
self._checkOpen()
self._checkCursor()
- rv = self.dbc.first()
+ rv = _DeadlockWrap(self.dbc.first)
return rv
def last(self):
self._checkOpen()
self._checkCursor()
- rv = self.dbc.last()
+ rv = _DeadlockWrap(self.dbc.last)
return rv
def sync(self):
self._checkOpen()
- return self.db.sync()
+ return _DeadlockWrap(self.db.sync)
#----------------------------------------------------------------------
@@ -385,5 +394,4 @@ try:
except ImportError:
db.DB_THREAD = 0
-
#----------------------------------------------------------------------
diff --git a/Lib/bsddb/dbrecio.py b/Lib/bsddb/dbrecio.py
index 22e382a..d439f32 100644
--- a/Lib/bsddb/dbrecio.py
+++ b/Lib/bsddb/dbrecio.py
@@ -75,7 +75,7 @@ class DBRecIO:
dlen = newpos - self.pos
- r = self.db.get(key, txn=self.txn, dlen=dlen, doff=self.pos)
+ r = self.db.get(self.key, txn=self.txn, dlen=dlen, doff=self.pos)
self.pos = newpos
return r
@@ -121,7 +121,7 @@ class DBRecIO:
"Negative size not allowed")
elif size < self.pos:
self.pos = size
- self.db.put(key, "", txn=self.txn, dlen=self.len-size, doff=size)
+ self.db.put(self.key, "", txn=self.txn, dlen=self.len-size, doff=size)
def write(self, s):
if self.closed:
@@ -131,7 +131,7 @@ class DBRecIO:
self.buflist.append('\0'*(self.pos - self.len))
self.len = self.pos
newpos = self.pos + len(s)
- self.db.put(key, s, txn=self.txn, dlen=len(s), doff=self.pos)
+ self.db.put(self.key, s, txn=self.txn, dlen=len(s), doff=self.pos)
self.pos = newpos
def writelines(self, list):
diff --git a/Lib/bsddb/dbtables.py b/Lib/bsddb/dbtables.py
index 369db43..492d5fd 100644
--- a/Lib/bsddb/dbtables.py
+++ b/Lib/bsddb/dbtables.py
@@ -32,6 +32,12 @@ except ImportError:
# For Python 2.3
from bsddb.db import *
+# XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
+try:
+ DBIncompleteError
+except NameError:
+ class DBIncompleteError(Exception):
+ pass
class TableDBError(StandardError):
pass
diff --git a/Lib/bsddb/dbutils.py b/Lib/bsddb/dbutils.py
index 3f63842..6dcfdd5 100644
--- a/Lib/bsddb/dbutils.py
+++ b/Lib/bsddb/dbutils.py
@@ -22,14 +22,14 @@
#
# import the time.sleep function in a namespace safe way to allow
-# "from bsddb.db import *"
+# "from bsddb.dbutils import *"
#
from time import sleep as _sleep
import db
# always sleep at least N seconds between retrys
-_deadlock_MinSleepTime = 1.0/64
+_deadlock_MinSleepTime = 1.0/128
# never sleep more than N seconds between retrys
_deadlock_MaxSleepTime = 3.14159
@@ -57,7 +57,7 @@ def DeadlockWrap(function, *_args, **_kwargs):
max_retries = _kwargs.get('max_retries', -1)
if _kwargs.has_key('max_retries'):
del _kwargs['max_retries']
- while 1:
+ while True:
try:
return function(*_args, **_kwargs)
except db.DBLockDeadlockError:
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index bec5da3..d6d507f 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -562,6 +562,9 @@ class BasicTestCase(unittest.TestCase):
num = d.truncate()
assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
+ #----------------------------------------
+
+
#----------------------------------------------------------------------
@@ -583,18 +586,40 @@ class BasicHashWithThreadFlagTestCase(BasicTestCase):
dbopenflags = db.DB_THREAD
-class BasicBTreeWithEnvTestCase(BasicTestCase):
- dbtype = db.DB_BTREE
+class BasicWithEnvTestCase(BasicTestCase):
dbopenflags = db.DB_THREAD
useEnv = 1
envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
+ #----------------------------------------
+
+ def test07_EnvRemoveAndRename(self):
+ if not self.env:
+ return
+
+ if verbose:
+ print '\n', '-=' * 30
+ print "Running %s.test07_EnvRemoveAndRename..." % self.__class__.__name__
+
+ # can't rename or remove an open DB
+ self.d.close()
+
+ newname = self.filename + '.renamed'
+ self.env.dbrename(self.filename, None, newname)
+ self.env.dbremove(newname)
+
+ # dbremove and dbrename are in 4.1 and later
+ if db.version() < (4,1):
+ del test07_EnvRemoveAndRename
-class BasicHashWithEnvTestCase(BasicTestCase):
+ #----------------------------------------
+
+class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase):
+ dbtype = db.DB_BTREE
+
+
+class BasicHashWithEnvTestCase(BasicWithEnvTestCase):
dbtype = db.DB_HASH
- dbopenflags = db.DB_THREAD
- useEnv = 1
- envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
#----------------------------------------------------------------------