aabc6c05c2
svn: r19809
128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
#
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
#
|
|
# Copyright (C) 2000-2007 Donald N. Allingham
|
|
#
|
|
# 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
|
|
#
|
|
# gen/db/cursor.py
|
|
# $Id$
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# Standard python modules
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
from cPickle import dumps, loads
|
|
|
|
from gen.config import config
|
|
if config.get('preferences.use-bsddb3'):
|
|
from bsddb3 import db
|
|
else:
|
|
from bsddb import db
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# BsddbBaseCursor class
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
|
|
class BsddbBaseCursor(object):
|
|
"""
|
|
Provide a basic iterator that allows the user to cycle through
|
|
the elements in a particular map.
|
|
|
|
A cursor should never be directly instantiated. Instead, in should be
|
|
created by the database class.
|
|
|
|
A cursor should only be used for a single pass through the
|
|
database. If multiple passes are needed, multiple cursors
|
|
should be used.
|
|
"""
|
|
|
|
def __init__(self, txn=None, update=False, commit=False):
|
|
"""
|
|
Instantiate the object. Note, this method should be overridden in
|
|
derived classes that properly set self.cursor and self.source
|
|
"""
|
|
self.cursor = self.source = None
|
|
self.txn = txn
|
|
self._update = update
|
|
self.commit = commit
|
|
|
|
def __getattr__(self, name):
|
|
"""
|
|
Return a method from the underlying cursor object, if it exists
|
|
"""
|
|
return getattr(self.cursor, name)
|
|
|
|
def __enter__(self):
|
|
"""
|
|
Context manager enter method
|
|
"""
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
"""
|
|
Context manager exit method
|
|
"""
|
|
self.close()
|
|
if self.txn and self.commit:
|
|
self.txn.commit()
|
|
return exc_type is None
|
|
|
|
def __iter__(self):
|
|
"""
|
|
Iterator
|
|
"""
|
|
|
|
data = self.first()
|
|
_n = self.next # Saved attribute lookup in the loop
|
|
while data:
|
|
yield data
|
|
data = _n()
|
|
|
|
def _get(_flags=0):
|
|
""" Closure that returns a cursor get function """
|
|
|
|
def get(self, flags=0, **kwargs):
|
|
"""
|
|
Issue DBCursor get call (with DB_RMW flag if update requested)
|
|
Return results to caller
|
|
"""
|
|
data = self.cursor.get(
|
|
_flags | flags | (db.DB_RMW if self._update else 0),
|
|
**kwargs)
|
|
|
|
return (data[0], loads(data[1])) if data else None
|
|
|
|
return get
|
|
|
|
# Use closure to define access methods
|
|
|
|
current = _get(db.DB_CURRENT)
|
|
first = _get(db.DB_FIRST)
|
|
next = _get(db.DB_NEXT)
|
|
last = _get(db.DB_LAST)
|
|
prev = _get(db.DB_PREV)
|
|
|
|
def update(self, key, data, flags=0, **kwargs):
|
|
"""
|
|
Write the current key, data pair to the database.
|
|
"""
|
|
self.cursor.put(key, dumps(data), flags=flags | db.DB_CURRENT,
|
|
**kwargs)
|