gramps/src/gen/db/bsddbtxn.py

211 lines
5.9 KiB
Python
Raw Normal View History

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2009 Gerald W. Britton
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id: bsddbtxn.py 12786 2009-07-11 15:32:37Z gbritton $
"""
BSDDBTxn class: Wrapper for BSDDB transaction-oriented methods
"""
#-------------------------------------------------------------------------
#
# BSDDBTxn
#
#-------------------------------------------------------------------------
class BSDDBTxn(object):
"""
Wrapper for BSDDB methods that set up and manage transactions. Implements
context management functionality allowing constructs like:
with BSDDBTxn(env) as txn:
DB.get(txn=txn)
DB.put(txn=txn)
DB.delete(txn=txn)
and other transaction-oriented DB access methods, where "env" is a
BSDDB DBEnv object and "DB" is a BSDDB database object.
Transactions are automatically begun when the "with" statement is executed
and automatically committed when control flows off the end of the "with"
statement context, either implicitly by reaching the end of the indentation
level or explicity if a "return" statement is encountered or an exception
is raised.
"""
__slots__ = ['env', 'db', 'txn', 'parent']
def __init__(self, env, db=None):
"""
Initialize transaction instance
"""
self.env = env
self.db = db
self.txn = None
# Context manager methods
def __enter__(self, parent=None, **kwargs):
"""
Context manager entry method
Begin the transaction
"""
self.txn = self.begin(parent, **kwargs)
self.parent = parent
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""
Context manager exit function
Commit the transaction if no exception occurred
"""
if exc_type is not None:
return False
if self.txn:
self.commit()
return True
# Methods implementing txn_ methods in DBEnv
def begin(self, *args, **kwargs):
"""
Create and begin a new transaction. A DBTxn object is returned
"""
self.txn = self.env.txn_begin(*args, **kwargs)
return self.txn
def checkpoint(self, *args, **kwargs):
"""
Flush the underlying memory pool, write a checkpoint record to the
log and then flush the log
"""
if self.env:
self.env.txn_checkpoint(*args, **kwargs)
def stat(self):
"""
Return a dictionary of transaction statistics
"""
if self.env:
return self.env.txn_stat()
def recover(self):
"""
Returns a list of tuples (GID, TXN) of transactions prepared but
still unresolved
"""
if self.env:
return self.env.txn_recover()
# Methods implementing DBTxn methods
def abort(self):
"""
Abort the transaction
"""
if self.txn:
self.txn.abort()
self.txn = None
def commit(self, flags=0):
"""
End the transaction, committing any changes to the databases
"""
if self.txn:
self.txn.commit(flags)
self.txn = None
def id(self):
"""
Return the unique transaction id associated with the specified
transaction
"""
if self.txn:
return self.txn.id()
def prepare(self, gid):
"""
Initiate the beginning of a two-phase commit
"""
if self.txn:
self.txn.prepare(gid)
def discard(self):
"""
Release all the per-process resources associated with the specified
transaction, neither committing nor aborting the transaction
"""
if self.txn:
self.txn.discard()
self.txn = None
# Methods implementing DB methods within the transaction context
def get(self, key, default=None, txn=None, **kwargs):
"""
Returns the data object associated with key
"""
if txn == None: txn = self.txn
return self.db.get(key, default, txn, **kwargs)
def pget(self, key, default=None, txn=None, **kwargs):
"""
Returns the primary key, given the secondary one, and associated data
"""
if txn == None: txn = self.txn
return self.db.pget(key, default, txn, **kwargs)
def put(self, key, data, txn=None, **kwargs):
"""
Stores the key/data pair in the database
"""
if txn == None: txn = self.txn
return self.db.put(key, data, txn, **kwargs)
def delete(self, key, txn=None, **kwargs):
"""
Removes a key/data pair from the database
"""
if txn == None: txn = self.txn
self.db.delete(key, txn, **kwargs)
# test code
if __name__ == "__main__":
print "1"
from bsddb import db, dbshelve
print "2"
x = db.DBEnv()
print "3"
x.open('/tmp', db.DB_CREATE | db.DB_PRIVATE |\
db.DB_INIT_MPOOL | db.DB_INIT_LOCK |\
db.DB_INIT_LOG | db.DB_INIT_TXN | db.DB_THREAD)
print "4"
d = dbshelve.DBShelf(x)
print "5"
#from tran import BSDDBTxn as T
print "6"
T = BSDDBTxn
with T(x) as tx:
print "stat", tx.stat()
print "id", tx.id()
tx.checkpoint()