4198: Person view does not remove a row correctly when two people are merged.

This patch improves on the context changes:
 * avoid use of transaction_xx methods
 * force an abort in case of unclean transaction

Backward compatibility is broken to achieve this.


svn: r16680
This commit is contained in:
Benny Malengier 2011-02-20 10:52:06 +00:00
parent cce4013b44
commit 752d594571
47 changed files with 205 additions and 129 deletions

View File

@ -29,6 +29,7 @@ Provide merge capabilities for events.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay

View File

@ -29,6 +29,7 @@ Provide merge capabilities for families.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
import const import const
@ -308,7 +309,7 @@ class MergeFamilyQuery(object):
new_handle = self.phoenix.get_handle() new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle() old_handle = self.titanic.get_handle()
with self.database.transaction_begin(_('Merge Family')) as trans: with DbTxn(_('Merge Family'), self.database) as trans:
phoenix_father = self.database.get_person_from_handle(self.phoenix_fh) phoenix_father = self.database.get_person_from_handle(self.phoenix_fh)
titanic_father = self.database.get_person_from_handle(self.titanic_fh) titanic_father = self.database.get_person_from_handle(self.titanic_fh)

View File

@ -29,6 +29,7 @@ Provide merge capabilities for media objects.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
@ -184,7 +185,7 @@ class MergeMediaQuery(object):
self.phoenix.merge(self.titanic) self.phoenix.merge(self.titanic)
with self.database.transaction_begin(_("Merge Media Objects")) as trans: with DbTxn(_("Merge Media Objects"), self.database) as trans:
for person in self.database.iter_people(): for person in self.database.iter_people():
if person.has_media_reference(old_handle): if person.has_media_reference(old_handle):
person.replace_media_references(old_handle, new_handle) person.replace_media_references(old_handle, new_handle)

View File

@ -29,6 +29,7 @@ Provide merge capabilities for notes.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
@ -196,7 +197,7 @@ class MergeNoteQuery(object):
new_handle = self.phoenix.get_handle() new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle() old_handle = self.titanic.get_handle()
self.phoenix.merge(self.titanic) self.phoenix.merge(self.titanic)
with self.database.transaction_begin(_("Merge Notes")) as trans: with DbTxn(_("Merge Notes"), self.database) as trans:
for person in self.database.iter_people(): for person in self.database.iter_people():
if person.has_note_reference(old_handle): if person.has_note_reference(old_handle):

View File

@ -38,6 +38,7 @@ import pango
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
from gen.plug.report import utils as ReportUtils from gen.plug.report import utils as ReportUtils
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
@ -406,7 +407,7 @@ class MergePersonQuery(object):
Merges two persons into a single person. Merges two persons into a single person.
""" """
if trans is None: if trans is None:
with self.database.transaction_begin(_('Merge Person')) as trans: with DbTxn(_('Merge Person'), self.database) as trans:
self.__execute(family_merger, trans) self.__execute(family_merger, trans)
else: else:
self.__execute(family_merger, trans) self.__execute(family_merger, trans)

View File

@ -37,6 +37,7 @@ import gtk
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
@ -210,7 +211,7 @@ class MergePlaceQuery(object):
self.phoenix.merge(self.titanic) self.phoenix.merge(self.titanic)
with self.database.transaction_begin(_("Merge Places")) as trans: with DbTxn(_("Merge Places"), self.database) as trans:
for person in self.database.iter_people(): for person in self.database.iter_people():
if person.has_handle_reference('Place', old_handle): if person.has_handle_reference('Place', old_handle):
person.replace_handle_reference('Place', old_handle, person.replace_handle_reference('Place', old_handle,

View File

@ -29,6 +29,7 @@ Provide merge capabilities for repositories.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
@ -171,7 +172,7 @@ class MergeRepoQuery(object):
self.phoenix.merge(self.titanic) self.phoenix.merge(self.titanic)
with self.database.transaction_begin(_("Merge Repositories")) as trans: with DbTxn(_("Merge Repositories"), self.database) as trans:
for source in self.database.iter_sources(): for source in self.database.iter_sources():
if source.has_repo_reference(old_handle): if source.has_repo_reference(old_handle):
source.replace_repo_references(old_handle, new_handle) source.replace_repo_references(old_handle, new_handle)

View File

@ -30,6 +30,7 @@ Provide merge capabilities for sources.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
@ -197,7 +198,7 @@ class MergeSourceQuery(object):
self.phoenix.merge(self.titanic) self.phoenix.merge(self.titanic)
with self.database.transaction_begin(_("Merge Source")) as trans: with DbTxn(_("Merge Source"), self.database) as trans:
for person in self.database.iter_people(): for person in self.database.iter_people():
if person.has_source_reference(old_handle): if person.has_source_reference(old_handle):
person.replace_source_references(old_handle, new_handle) person.replace_source_references(old_handle, new_handle)

View File

@ -29,6 +29,7 @@ from gen.ggettext import gettext as _
# gramps modules # gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
import ListModel import ListModel
import ManagedWindow import ManagedWindow
@ -136,7 +137,7 @@ class Reorder(ManagedWindow.ManagedWindow):
def ok_clicked(self, obj): def ok_clicked(self, obj):
name = name_displayer.display(self.person) name = name_displayer.display(self.person)
msg = _("Reorder Relationships: %s") % name msg = _("Reorder Relationships: %s") % name
with self.dbstate.db.transaction_begin(msg) as trans: with DbTxn(msg, self.dbstate.db) as trans:
self.dbstate.db.commit_person(self.person, trans) self.dbstate.db.commit_person(self.person, trans)
self.close() self.close()

View File

@ -39,6 +39,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from txn import DbTxn
class DbReadBase(object): class DbReadBase(object):
""" """
@ -1344,6 +1345,12 @@ class DbWriteBase(object):
""" """
raise NotImplementedError raise NotImplementedError
def get_undodb(self):
"""
Return the database that keeps track of Undo/Redo operations.
"""
raise NotImplementedError
def need_upgrade(self): def need_upgrade(self):
""" """
Return True if database needs to be upgraded Return True if database needs to be upgraded
@ -1479,18 +1486,35 @@ class DbWriteBase(object):
""" """
raise NotImplementedError raise NotImplementedError
def transaction_begin(self, msg='', batch=False, no_magic=False): def transaction_begin(self, transaction):
""" """
Create a new Transaction tied to the current UNDO database. Prepare the database for the start of a new transaction.
The transaction has no effect until it is committed using the Two modes should be provided: transaction.batch=False for ordinary
transaction_commit function of the this database object. database operations that will be encapsulated in database transactions
to make them ACID and that are added to Gramps transactions so that
they can be undone. And transaction.batch=True for lengthy database
operations, that benefit from a speedup by making them none ACID, and
that can't be undone. The user is warned and is asked for permission
before the start of such database operations.
:param transaction: Gramps transaction ...
:type transaction: DbTxn
:returns: Returns the Gramps transaction.
:rtype: DbTxn
""" """
raise NotImplementedError raise NotImplementedError
def transaction_commit(self, transaction, msg): def transaction_commit(self, transaction):
""" """
Commit the transaction to the associated UNDO database. Make the changes to the database final and add the content of the
transaction to the undo database.
"""
raise NotImplementedError
def transaction_abort(self, transaction):
"""
Revert the changes made to the database so far during the transaction.
""" """
raise NotImplementedError raise NotImplementedError
@ -1525,7 +1549,7 @@ class DbWriteBase(object):
child.add_parent_family_handle(family.handle) child.add_parent_family_handle(family.handle)
if trans is None: if trans is None:
with self.transaction_begin(_('Add child to family')) as trans: with DbTxn(_('Add child to family'), self) as trans:
self.commit_family(family, trans) self.commit_family(family, trans)
self.commit_person(child, trans) self.commit_person(child, trans)
else: else:
@ -1538,8 +1562,7 @@ class DbWriteBase(object):
it becomes empty. it becomes empty.
""" """
if trans is None: if trans is None:
with self.transaction_begin(_("Remove child from family") with DbTxn(_("Remove child from family"), self) as trans:
) as trans:
self.__remove_child_from_family(person_handle, family_handle, self.__remove_child_from_family(person_handle, family_handle,
trans) trans)
else: else:
@ -1617,7 +1640,7 @@ class DbWriteBase(object):
Remove a family and its relationships. Remove a family and its relationships.
""" """
if trans is None: if trans is None:
with self.transaction_begin(_("Remove Family")) as trans: with DbTxn(_("Remove Family"), self) as trans:
self.__remove_family_relationships(family_handle, trans) self.__remove_family_relationships(family_handle, trans)
else: else:
self.__remove_family_relationships(family_handle, trans) self.__remove_family_relationships(family_handle, trans)
@ -1642,7 +1665,7 @@ class DbWriteBase(object):
deleting the family if it becomes empty. deleting the family if it becomes empty.
""" """
if trans is None: if trans is None:
with self.transaction_begin() as trans: with DbTxn('', self) as trans:
msg = self.__remove_parent_from_family(person_handle, msg = self.__remove_parent_from_family(person_handle,
family_handle, trans) family_handle, trans)
trans.set_description(msg) trans.set_description(msg)

View File

@ -54,8 +54,6 @@ _LOG = logging.getLogger(DBLOGNAME)
class DbTxn(defaultdict): class DbTxn(defaultdict):
""" """
Define a group of database commits that define a single logical operation. Define a group of database commits that define a single logical operation.
This class should not be used directly, but subclassed to reference a real
database
""" """
__slots__ = ('msg', 'commitdb', 'db', 'batch', 'first', __slots__ = ('msg', 'commitdb', 'db', 'batch', 'first',
@ -65,6 +63,7 @@ class DbTxn(defaultdict):
""" """
Context manager entry method Context manager entry method
""" """
self.db.transaction_begin(self)
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
@ -77,19 +76,25 @@ class DbTxn(defaultdict):
self.db.transaction_abort(self) self.db.transaction_abort(self)
return False return False
def __init__(self, msg, commitdb, grampsdb, batch): def __init__(self, msg, grampsdb, batch=False, **kwargs):
""" """
Create a new transaction. Create a new transaction.
A Transaction instance should not be created directly, but by the The grampsdb should have transaction_begin/commit/abort methods, and
DbBase class or classes derived from DbBase. The commitdb a get_undodb method to store undo actions.
parameter is a list-like interface that stores the commit data. This
could be a simple list, or a RECNO-style database object. The grampsdb A Transaction instance can be created directly, but it is advised to
parameter is a reference to the DbWrite object to which this use a context to do this. Like this the user must not worry about
transaction will be applied. calling the transaction_xx methods on the database.
The grampsdb parameter is a reference to the DbWrite object to which
this transaction will be applied.
grampsdb.get_undodb() should return a list-like interface that
stores the commit data. This could be a simple list, or a RECNO-style
database object.
The data structure used to handle the transactions is a Python The data structure used to handle the transactions (see the add method)
dictionary where: is a Python dictionary where:
key = (object type, transaction type) where: key = (object type, transaction type) where:
object type = the numeric type of an object. These are object type = the numeric type of an object. These are
@ -107,9 +112,11 @@ class DbTxn(defaultdict):
defaultdict.__init__(self, list, {}) defaultdict.__init__(self, list, {})
self.msg = msg self.msg = msg
self.commitdb = commitdb self.commitdb = grampsdb.get_undodb()
self.db = grampsdb self.db = grampsdb
self.batch = batch self.batch = batch
for key, value in kwargs.iteritems():
setattr(self, key, value)
self.first = None self.first = None
self.last = None self.last = None
self.timestamp = 0 self.timestamp = 0

View File

@ -543,6 +543,12 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
except db.DBNoSuchFileError: except db.DBNoSuchFileError:
pass pass
def get_undodb(self):
"""
Return the database that keeps track of Undo/Redo operations.
"""
return self.undodb
def __load_metadata(self): def __load_metadata(self):
# name display formats # name display formats
self.name_formats = self.metadata.get('name_formats', default=[]) self.name_formats = self.metadata.get('name_formats', default=[])
@ -919,7 +925,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
# Make a tuple of the functions and classes that we need for # Make a tuple of the functions and classes that we need for
# each of the primary object tables. # each of the primary object tables.
with self.transaction_begin(_("Rebuild reference map"), batch=True, with DbTxn(_("Rebuild reference map"), self, batch=True,
no_magic=True) as transaction: no_magic=True) as transaction:
callback(4) callback(4)
@ -1019,6 +1025,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
def close(self): def close(self):
if not self.db_is_open: if not self.db_is_open:
return return
if self.txn:
self.transaction_abort(self.transaction)
self.env.txn_checkpoint() self.env.txn_checkpoint()
self.__close_metadata() self.__close_metadata()
@ -1234,7 +1242,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
old_data = data_map.get(handle, txn=self.txn) old_data = data_map.get(handle, txn=self.txn)
data_map.delete(handle, txn=self.txn) data_map.delete(handle, txn=self.txn)
transaction.add(key, TXNDEL, handle, old_data, None) transaction.add(key, TXNDEL, handle, old_data, None)
#del_list.append(handle)
def remove_person(self, handle, transaction): def remove_person(self, handle, transaction):
""" """
@ -1257,7 +1264,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn=self.txn) txn=self.txn)
self.person_map.delete(str(handle), txn=self.txn) self.person_map.delete(str(handle), txn=self.txn)
transaction.add(PERSON_KEY, TXNDEL, handle, person.serialize(), None) transaction.add(PERSON_KEY, TXNDEL, handle, person.serialize(), None)
#transaction.person_del.append(str(handle))
def remove_source(self, handle, transaction): def remove_source(self, handle, transaction):
""" """
@ -1626,17 +1632,27 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return None return None
@catch_db_error @catch_db_error
def transaction_begin(self, msg="", batch=False, no_magic=False): def transaction_begin(self, transaction):
"""
Create a new Transaction tied to the current UNDO database.
The transaction has no effect until it is committed using the
transaction_commit function of the this database object.
""" """
Prepare the database for the start of a new Transaction.
transaction = DbTxn(msg, self.undodb, self, batch) Supported transaction parameters:
transaction.no_magic = no_magic no_magic: Boolean, defaults to False, indicating if secondary indices
if batch: should be disconnected.
"""
if self.txn is not None:
msg = self.transaction.get_description()
self.transaction_abort(self.transaction)
raise Errors.DbError(_('A second transaction is started while there'
' is still a transaction, "%s", active in the database.') % msg)
if not isinstance(transaction, DbTxn) or len(transaction) != 0:
raise TypeError("transaction_begin must be called with an empty "
"instance of DbTxn which typically happens by using the "
"DbTxn instance as a context manager.")
self.transaction = transaction #only used at the start of this method.
if transaction.batch:
# A batch transaction does not store the commits # A batch transaction does not store the commits
# Aborting the session completely will become impossible. # Aborting the session completely will become impossible.
self.abort_possible = False self.abort_possible = False
@ -1644,7 +1660,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.undodb.clear() self.undodb.clear()
self.env.txn_checkpoint() self.env.txn_checkpoint()
if self.secondary_connected and not no_magic: if (self.secondary_connected and
not getattr(transaction, 'no_magic', False)):
# Disconnect unneeded secondary indices # Disconnect unneeded secondary indices
self.surnames.close() self.surnames.close()
_db = db.DB(self.env) _db = db.DB(self.env)
@ -1665,25 +1682,25 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return transaction return transaction
@catch_db_error @catch_db_error
def transaction_commit(self, transaction, msg=''): def transaction_commit(self, transaction):
""" """
Make the changes to the database final and add the content of the Make the changes to the database final and add the content of the
transaction to the undo database. transaction to the undo database.
""" """
if not msg: msg = transaction.get_description()
msg = transaction.get_description()
if self._LOG_ALL: if self._LOG_ALL:
_LOG.debug("%s: Transaction commit '%s'\n" _LOG.debug("%s: Transaction commit '%s'\n"
% (self.__class__.__name__, str(msg))) % (self.__class__.__name__, msg))
if self.readonly: if self.readonly:
return return
if self.txn is not None: if self.txn is not None:
assert transaction.get_description() != '' assert msg != ''
self.bsddbtxn.commit() self.bsddbtxn.commit()
self.bsddbtxn = None self.bsddbtxn = None
self.txn = None self.txn = None
self.transaction = None
self.env.log_flush() self.env.log_flush()
if not transaction.batch: if not transaction.batch:
emit = self.__emit emit = self.__emit
@ -1714,11 +1731,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
def transaction_abort(self, transaction): def transaction_abort(self, transaction):
""" """
Revert the changes made to the database. Revert the changes made to the database so far during the transaction.
""" """
if self._LOG_ALL: if self._LOG_ALL:
_LOG.debug("%s: Transaction abort '%s'\n" _LOG.debug("%s: Transaction abort '%s'\n" %
% (self.__class__.__name__, str(transaction.get_description()))) (self.__class__.__name__, transaction.get_description()))
if self.readonly: if self.readonly:
return return
@ -1727,6 +1744,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.bsddbtxn.abort() self.bsddbtxn.abort()
self.bsddbtxn = None self.bsddbtxn = None
self.txn = None self.txn = None
self.transaction = None
transaction.clear() transaction.clear()
transaction.first = None transaction.first = None
transaction.last = None transaction.last = None
@ -1739,7 +1757,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if transaction.batch: if transaction.batch:
self.env.txn_checkpoint() self.env.txn_checkpoint()
if not transaction.no_magic: if not getattr(transaction, 'no_magic', False):
# create new secondary indices to replace the ones removed # create new secondary indices to replace the ones removed
self.surnames = self.__open_db(self.full_name, SURNAMES, self.surnames = self.__open_db(self.full_name, SURNAMES,

View File

@ -51,6 +51,7 @@ from gui.utils import open_file_with_default_application
from gui.dbguielement import DbGUIElement from gui.dbguielement import DbGUIElement
from gui.selectors import SelectorFactory from gui.selectors import SelectorFactory
import gen.lib import gen.lib
from gen.db import DbTxn
import Utils import Utils
import ThumbNails import ThumbNails
import Errors import Errors
@ -476,8 +477,8 @@ class GalleryTab(ButtonTab, DbGUIElement):
basename = os.path.basename(name) basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename) (root, ext) = os.path.splitext(basename)
photo.set_description(root) photo.set_description(root)
with self.dbstate.db.transaction_begin( with DbTxn(_("Drag Media Object"),
_("Drag Media Object")) as trans: self.dbstate.db) as trans:
self.dbstate.db.add_object(photo, trans) self.dbstate.db.add_object(photo, trans)
oref = gen.lib.MediaRef() oref = gen.lib.MediaRef()
oref.set_reference_handle(photo.get_handle()) oref.set_reference_handle(photo.get_handle())

View File

@ -42,6 +42,7 @@ import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
import gen.lib import gen.lib
from gen.db import DbTxn
import GrampsDisplay import GrampsDisplay
from editprimary import EditPrimary from editprimary import EditPrimary
from objectentries import PlaceEntry from objectentries import PlaceEntry
@ -253,14 +254,14 @@ class EditEvent(EditPrimary):
return return
if not self.obj.handle: if not self.obj.handle:
with self.db.transaction_begin(_("Add Event (%s)") % with DbTxn(_("Add Event (%s)") % self.obj.get_gramps_id(),
self.obj.get_gramps_id()) as trans: self.db) as trans:
self.db.add_event(self.obj, trans) self.db.add_event(self.obj, trans)
else: else:
orig = self.get_from_handle(self.obj.handle) orig = self.get_from_handle(self.obj.handle)
if cmp(self.obj.serialize(), orig.serialize()): if cmp(self.obj.serialize(), orig.serialize()):
with self.db.transaction_begin(_("Edit Event (%s)") % with DbTxn(_("Edit Event (%s)") % self.obj.get_gramps_id(),
self.obj.get_gramps_id()) as trans: self.db) as trans:
if not self.obj.get_gramps_id(): if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_event_gramps_id()) self.obj.set_gramps_id(self.db.find_next_event_gramps_id())
self.commit_event(self.obj, trans) self.commit_event(self.obj, trans)
@ -331,8 +332,8 @@ class DeleteEventQuery(object):
self.family_list = family_list self.family_list = family_list
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Delete Event (%s)") % with DbTxn(_("Delete Event (%s)") % self.event.get_gramps_id(),
self.event.get_gramps_id()) as trans: self.db) as trans:
self.db.disable_signals() self.db.disable_signals()
ev_handle_list = [self.event.get_handle()] ev_handle_list = [self.event.get_handle()]

View File

@ -34,6 +34,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from glade import Glade from glade import Glade
from displaytabs import (SourceEmbedList, NoteTab, GalleryTab, from displaytabs import (SourceEmbedList, NoteTab, GalleryTab,
EventBackRefList, AttrEmbedList) EventBackRefList, AttrEmbedList)
@ -237,10 +238,10 @@ class EditEventRef(EditReference):
def ok_clicked(self, obj): def ok_clicked(self, obj):
if self.source.handle: if self.source.handle:
with self.db.transaction_begin(_("Modify Event")) as trans: with DbTxn(_("Modify Event"), self.db) as trans:
self.commit_event(self.source,trans) self.commit_event(self.source,trans)
else: else:
with self.db.transaction_begin(_("Add Event")) as trans: with DbTxn(_("Add Event"), self.db) as trans:
self.add_event(self.source,trans) self.add_event(self.source,trans)
self.source_ref.ref = self.source.handle self.source_ref.ref = self.source.handle

View File

@ -62,6 +62,7 @@ import Utils
import config import config
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
import gen.lib import gen.lib
from gen.db import DbTxn
import Errors import Errors
import DateHandler import DateHandler
from glade import Glade from glade import Glade
@ -1060,7 +1061,7 @@ class EditFamily(EditPrimary):
self._cleanup_callbacks() self._cleanup_callbacks()
if not original and not self.object_is_empty(): if not original and not self.object_is_empty():
with self.db.transaction_begin(_("Add Family")) as trans: with DbTxn(_("Add Family"), self.db) as trans:
# find the father, add the family handle to the father # find the father, add the family handle to the father
handle = self.obj.get_father_handle() handle = self.obj.get_father_handle()
@ -1086,7 +1087,7 @@ class EditFamily(EditPrimary):
self.db.add_family(self.obj, trans) self.db.add_family(self.obj, trans)
elif cmp(original.serialize(),self.obj.serialize()): elif cmp(original.serialize(),self.obj.serialize()):
with self.db.transaction_begin(_("Edit Family")) as trans: with DbTxn(_("Edit Family"), self.db) as trans:
self.fix_parent_handles(original.get_father_handle(), self.fix_parent_handles(original.get_father_handle(),
self.obj.get_father_handle(), trans) self.obj.get_father_handle(), trans)

View File

@ -43,6 +43,7 @@ import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gui.utils import open_file_with_default_application from gui.utils import open_file_with_default_application
import gen.lib import gen.lib
from gen.db import DbTxn
import gen.mime import gen.mime
import ThumbNails import ThumbNails
import Utils import Utils
@ -288,7 +289,7 @@ class EditMedia(EditPrimary):
self.obj.set_path(Utils.get_unicode_path_from_file_chooser(path)) self.obj.set_path(Utils.get_unicode_path_from_file_chooser(path))
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_object(self.obj, trans) self.db.add_object(self.obj, trans)
msg = _("Add Media Object (%s)") % self.obj.get_description() msg = _("Add Media Object (%s)") % self.obj.get_description()
@ -335,7 +336,7 @@ class DeleteMediaQuery(object):
self.the_lists = the_lists self.the_lists = the_lists
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Remove Media Object")) as trans: with DbTxn(_("Remove Media Object"), self.db) as trans:
self.db.disable_signals() self.db.disable_signals()
(person_list, family_list, event_list, (person_list, family_list, event_list,

View File

@ -47,6 +47,7 @@ import gen.mime
import ThumbNails import ThumbNails
import Utils import Utils
from gen.lib import NoteType from gen.lib import NoteType
from gen.db import DbTxn
from glade import Glade from glade import Glade
from displaytabs import (SourceEmbedList, AttrEmbedList, MediaBackRefList, from displaytabs import (SourceEmbedList, AttrEmbedList, MediaBackRefList,
NoteTab) NoteTab)
@ -587,12 +588,12 @@ class EditMediaRef(EditReference):
def save(self,*obj): def save(self,*obj):
#first save primary object #first save primary object
if self.source.handle: if self.source.handle:
with self.db.transaction_begin(_("Edit Media Object (%s)" with DbTxn(_("Edit Media Object (%s)") %
) % self.source.get_description()) as trans: self.source.get_description(), self.db) as trans:
self.db.commit_media_object(self.source, trans) self.db.commit_media_object(self.source, trans)
else: else:
with self.db.transaction_begin(_("Add Media Object (%s)" with DbTxn(_("Add Media Object (%s)") %
) % self.source.get_description()) as trans: self.source.get_description(), self.db) as trans:
self.db.add_object(self.source, trans) self.db.add_object(self.source, trans)
#save reference object in memory #save reference object in memory

View File

@ -53,6 +53,7 @@ from displaytabs import GrampsTab, NoteBackRefList
from gui.widgets import (MonitoredDataType, MonitoredCheckbox, from gui.widgets import (MonitoredDataType, MonitoredCheckbox,
MonitoredEntry, PrivacyButton, MonitoredTagList) MonitoredEntry, PrivacyButton, MonitoredTagList)
from gen.lib import Note from gen.lib import Note
from gen.db import DbTxn
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from glade import Glade from glade import Glade
@ -317,7 +318,7 @@ class EditNote(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_note(self.obj, trans) self.db.add_note(self.obj, trans)
msg = _("Add Note") msg = _("Add Note")
@ -340,8 +341,8 @@ class DeleteNoteQuery(object):
self.the_lists = the_lists self.the_lists = the_lists
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Delete Note (%s)") % with DbTxn(_("Delete Note (%s)") % self.note.get_gramps_id(),
self.note.get_gramps_id()) as trans: self.db) as trans:
self.db.disable_signals() self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list, (person_list, family_list, event_list, place_list, source_list,

View File

@ -51,6 +51,7 @@ import pango
import Utils import Utils
from gui.utils import add_menuitem, open_file_with_default_application from gui.utils import add_menuitem, open_file_with_default_application
import gen.lib import gen.lib
from gen.db import DbTxn
from gui import widgets from gui import widgets
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
import Errors import Errors
@ -868,7 +869,7 @@ class EditPerson(EditPrimary):
self.db.set_birth_death_index(self.obj) self.db.set_birth_death_index(self.obj)
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
self._update_family_ids() self._update_family_ids()
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_person(self.obj, trans) self.db.add_person(self.obj, trans)

View File

@ -44,6 +44,7 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from editprimary import EditPrimary from editprimary import EditPrimary
from displaytabs import (GrampsTab, LocationEmbedList, SourceEmbedList, from displaytabs import (GrampsTab, LocationEmbedList, SourceEmbedList,
GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList) GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList)
@ -306,7 +307,7 @@ class EditPlace(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_place(self.obj, trans) self.db.add_place(self.obj, trans)
msg = _("Add Place (%s)") % self.obj.get_title() msg = _("Add Place (%s)") % self.obj.get_title()
@ -338,8 +339,8 @@ class DeletePlaceQuery(object):
self.event_list = event_list self.event_list = event_list
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Delete Place (%s)") % with DbTxn(_("Delete Place (%s)") % self.obj.get_title(),
self.obj.get_title()) as trans: self.db) as trans:
self.db.disable_signals() self.db.disable_signals()
place_handle = self.obj.get_handle() place_handle = self.obj.get_handle()

View File

@ -34,6 +34,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.lib import NoteType from gen.lib import NoteType
from gen.db import DbTxn
from displaytabs import NoteTab,AddrEmbedList,WebEmbedList,SourceBackRefList from displaytabs import NoteTab,AddrEmbedList,WebEmbedList,SourceBackRefList
from gui.widgets import MonitoredEntry, PrivacyButton, MonitoredDataType from gui.widgets import MonitoredEntry, PrivacyButton, MonitoredDataType
@ -190,10 +191,10 @@ class EditRepoRef(EditReference):
def ok_clicked(self, obj): def ok_clicked(self, obj):
if self.source.handle: if self.source.handle:
with self.db.transaction_begin(_("Modify Repository")) as trans: with DbTxn(_("Modify Repository"), self.db) as trans:
self.db.commit_repository(self.source,trans) self.db.commit_repository(self.source,trans)
else: else:
with self.db.transaction_begin(_("Add Repository")) as trans: with DbTxn(_("Add Repository"), self.db) as trans:
self.db.add_repository(self.source,trans) self.db.add_repository(self.source,trans)
self.source_ref.ref = self.source.handle self.source_ref.ref = self.source.handle

View File

@ -41,6 +41,7 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from gui.widgets import MonitoredEntry, MonitoredDataType, PrivacyButton from gui.widgets import MonitoredEntry, MonitoredDataType, PrivacyButton
from displaytabs import AddrEmbedList, WebEmbedList, NoteTab, SourceBackRefList from displaytabs import AddrEmbedList, WebEmbedList, NoteTab, SourceBackRefList
@ -177,7 +178,7 @@ class EditRepository(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_repository(self.obj, trans) self.db.add_repository(self.obj, trans)
msg = _("Add Repository (%s)") % self.obj.get_name() msg = _("Add Repository (%s)") % self.obj.get_name()
@ -198,8 +199,8 @@ class DeleteRepositoryQuery(object):
self.sources = sources self.sources = sources
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Delete Repository (%s)") % with DbTxn(_("Delete Repository (%s)") % self.obj.get_name(),
self.obj.get_name()) as trans: self.db) as trans:
repos_handle_list = [self.obj.get_handle()] repos_handle_list = [self.obj.get_handle()]

View File

@ -43,6 +43,7 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from editprimary import EditPrimary from editprimary import EditPrimary
from displaytabs import (NoteTab, GalleryTab, DataEmbedList, from displaytabs import (NoteTab, GalleryTab, DataEmbedList,
@ -195,7 +196,7 @@ class EditSource(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
with self.db.transaction_begin() as trans: with DbTxn('', self.db) as trans:
if not self.obj.get_handle(): if not self.obj.get_handle():
self.db.add_source(self.obj, trans) self.db.add_source(self.obj, trans)
msg = _("Add Source (%s)") % self.obj.get_title() msg = _("Add Source (%s)") % self.obj.get_title()
@ -216,8 +217,8 @@ class DeleteSrcQuery(object):
self.the_lists = the_lists self.the_lists = the_lists
def query_response(self): def query_response(self):
with self.db.transaction_begin(_("Delete Source (%s)") % with DbTxn(_("Delete Source (%s)") % self.source.get_title(),
self.source.get_title()) as trans: self.db) as trans:
self.db.disable_signals() self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list, (person_list, family_list, event_list, place_list, source_list,

View File

@ -34,6 +34,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from glade import Glade from glade import Glade
from displaytabs import (NoteTab, GalleryTab, SourceBackRefList, from displaytabs import (NoteTab, GalleryTab, SourceBackRefList,
DataEmbedList, RepoEmbedList) DataEmbedList, RepoEmbedList)
@ -206,10 +207,10 @@ class EditSourceRef(EditReference):
def ok_clicked(self, obj): def ok_clicked(self, obj):
if self.source.handle: if self.source.handle:
with self.db.transaction_begin(_("Modify Source")) as trans: with DbTxn(_("Modify Source"), self.db) as trans:
self.db.commit_source(self.source,trans) self.db.commit_source(self.source,trans)
else: else:
with self.db.transaction_begin(_("Add Source")) as trans: with DbTxn(_("Add Source"), self.db) as trans:
self.db.add_source(self.source,trans) self.db.add_source(self.source,trans)
if self.update: if self.update:

View File

@ -50,6 +50,7 @@ LOG = logging.getLogger(".ImportCSV")
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
from gen.ggettext import ngettext from gen.ggettext import ngettext
import gen.lib import gen.lib
from gen.db import DbTxn
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from DateHandler import parser as _dp from DateHandler import parser as _dp
from Utils import gender as gender_map from Utils import gender as gender_map
@ -438,8 +439,7 @@ class CSVParser(object):
progress.set_pass(_('Reading data...'), 1) progress.set_pass(_('Reading data...'), 1)
data = self.readCSV() data = self.readCSV()
progress.set_pass(_('Importing data...'), len(data)) progress.set_pass(_('Importing data...'), len(data))
with self.db.transaction_begin(_("CSV import"), batch=True with DbTxn(_("CSV import"), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
t = time.time() t = time.time()
self.lineno = 0 self.lineno = 0

View File

@ -48,6 +48,7 @@ LOG = logging.getLogger(".ImportGeneWeb")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Errors import Errors
import gen.lib import gen.lib
from gen.db import DbTxn
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from htmlentitydefs import name2codepoint from htmlentitydefs import name2codepoint
@ -112,8 +113,7 @@ class GeneWebParser(object):
return line return line
def parse_geneweb_file(self): def parse_geneweb_file(self):
with self.db.transaction_begin(_("GeneWeb import"), batch=True with DbTxn(_("GeneWeb import"), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
t = time.time() t = time.time()
self.lineno = 0 self.lineno = 0

View File

@ -50,6 +50,7 @@ log = logging.getLogger('.ImportProGen')
import Utils import Utils
from gui.utils import ProgressMeter from gui.utils import ProgressMeter
import gen.lib import gen.lib
from gen.db import DbTxn
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
class ProgenError(Exception): class ProgenError(Exception):
@ -495,8 +496,7 @@ class ProgenParser(object):
self.pers = _read_recs(self.def_['Table_1'], self.bname) self.pers = _read_recs(self.def_['Table_1'], self.bname)
self.rels = _read_recs(self.def_['Table_2'], self.bname) self.rels = _read_recs(self.def_['Table_2'], self.bname)
with self.db.transaction_begin(_("Pro-Gen import"), batch=True with DbTxn(_("Pro-Gen import"), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
self.create_persons() self.create_persons()

View File

@ -48,6 +48,7 @@ LOG = logging.getLogger(".ImportVCard")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Errors import Errors
import gen.lib import gen.lib
from gen.db import DbTxn
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -90,8 +91,7 @@ class VCardParser(object):
return line return line
def parse_vCard_file(self): def parse_vCard_file(self):
with self.db.transaction_begin(_("vCard import"), batch=True with DbTxn(_("vCard import"), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
t = time.time() t = time.time()
self.person = None self.person = None

View File

@ -43,6 +43,7 @@ LOG = logging.getLogger(".ImportXML")
from QuestionDialog import ErrorDialog, WarningDialog from QuestionDialog import ErrorDialog, WarningDialog
import gen.mime import gen.mime
import gen.lib import gen.lib
from gen.db import DbTxn
import Utils import Utils
import DateHandler import DateHandler
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
@ -771,8 +772,8 @@ class GrampsParser(UpdateCallback):
no_magic = True no_magic = True
else: else:
no_magic = False no_magic = False
with self.db.transaction_begin(_("Gramps XML import"), batch=True, with DbTxn(_("Gramps XML import"), self.db, batch=True,
no_magic=no_magic) as self.trans: no_magic=no_magic) as self.trans:
self.set_total(linecount) self.set_total(linecount)
self.db.disable_signals() self.db.disable_signals()

View File

@ -113,6 +113,7 @@ LOG = logging.getLogger(".libgedcom")
import Errors import Errors
import const import const
import gen.lib import gen.lib
from gen.db import DbTxn
from gen.updatecallback import UpdateCallback from gen.updatecallback import UpdateCallback
import gen.mime import gen.mime
import LdsUtils import LdsUtils
@ -2281,8 +2282,8 @@ class GedcomParser(UpdateCallback):
Parses the opened GEDCOM file. Parses the opened GEDCOM file.
""" """
no_magic = self.maxpeople < 1000 no_magic = self.maxpeople < 1000
with self.dbase.transaction_begin(_("GEDCOM import"), not use_trans, with DbTxn(_("GEDCOM import"), self.dbase, not use_trans, no_magic
no_magic) as self.trans: ) as self.trans:
self.dbase.disable_signals() self.dbase.disable_signals()
self.__parse_header_head() self.__parse_header_head()

View File

@ -47,6 +47,7 @@ _LOG = logging.getLogger(".gui.personview")
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from gui.views.listview import ListView from gui.views.listview import ListView
import Utils import Utils
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
@ -305,7 +306,7 @@ class BasePersonView(ListView):
self.uistate.set_busy_cursor(True) self.uistate.set_busy_cursor(True)
# create the transaction # create the transaction
with self.dbstate.db.transaction_begin() as trans: with DbTxn('', self.dbstate.db) as trans:
# create name to save # create name to save
person = self.active_person person = self.active_person

View File

@ -37,7 +37,7 @@ import gtk
# gramps modules # gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import find_surname_name from gen.db import find_surname_name, DbTxn
import const import const
from gui.utils import ProgressMeter from gui.utils import ProgressMeter
import GrampsDisplay import GrampsDisplay
@ -231,8 +231,8 @@ class ChangeNames(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC) GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def on_ok_clicked(self, obj): def on_ok_clicked(self, obj):
with self.db.transaction_begin(_("Capitalization changes"),batch=True with DbTxn(_("Capitalization changes"), self.db, batch=True
) as self.trans: ) as self.trans:
self.db.disable_signals() self.db.disable_signals()
changelist = set(self.model.get_value(node,1) changelist = set(self.model.get_value(node,1)
for node in self.iter_list for node in self.iter_list

View File

@ -42,6 +42,7 @@ import locale
import ManagedWindow import ManagedWindow
import AutoComp import AutoComp
from gen.lib import EventType from gen.lib import EventType
from gen.db import DbTxn
from QuestionDialog import OkDialog from QuestionDialog import OkDialog
from gui.plug import tool from gui.plug import tool
from glade import Glade from glade import Glade
@ -110,8 +111,7 @@ class ChangeTypes(tool.BatchTool, ManagedWindow.ManagedWindow):
modified = 0 modified = 0
with self.db.transaction_begin(_('Change types'), batch=True with DbTxn(_('Change types'), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
if not cli: if not cli:
progress = ProgressMeter(_('Analyzing Events'),'') progress = ProgressMeter(_('Analyzing Events'),'')

View File

@ -59,6 +59,7 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
import Utils import Utils
from gui.utils import ProgressMeter from gui.utils import ProgressMeter
import ManagedWindow import ManagedWindow
@ -174,8 +175,7 @@ class Check(tool.BatchTool):
if self.db.__class__.__name__ == 'DbBsddb': if self.db.__class__.__name__ == 'DbBsddb':
low_level(self.db) low_level(self.db)
with self.db.transaction_begin(_("Check Integrity"), batch=True with DbTxn(_("Check Integrity"), self.db, batch=True) as trans:
) as trans:
self.db.disable_signals() self.db.disable_signals()
checker = CheckIntegrity(dbstate, uistate, trans) checker = CheckIntegrity(dbstate, uistate, trans)
checker.fix_encoding() checker.fix_encoding()

View File

@ -44,6 +44,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from gui.plug import tool from gui.plug import tool
from gui.utils import ProgressMeter from gui.utils import ProgressMeter
from QuestionDialog import QuestionDialog from QuestionDialog import QuestionDialog
@ -155,8 +156,7 @@ class DateParserDisplayTest(tool.Tool):
# (4,7,1789,False,5,88,1876,False),"Text comment") # (4,7,1789,False,5,88,1876,False),"Text comment")
#dates.append( d) #dates.append( d)
with self.db.transaction_begin(_("Date Test Plugin"),batch=True with DbTxn(_("Date Test Plugin"), self.db, batch=True) as trans:
) as trans:
self.db.disable_signals() self.db.disable_signals()
self.progress.set_pass(_('Generating dates'), self.progress.set_pass(_('Generating dates'),
len(dates)) len(dates))

View File

@ -45,6 +45,7 @@ from gen.ggettext import ngettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import ManagedWindow import ManagedWindow
import gen.lib import gen.lib
from gen.db import DbTxn
import Utils import Utils
from gui.plug import tool from gui.plug import tool
@ -78,8 +79,7 @@ class EventNames(tool.BatchTool, ManagedWindow.ManagedWindow):
""" """
Perform the actual extraction of information. Perform the actual extraction of information.
""" """
with self.db.transaction_begin(_("Event name changes"), batch=True with DbTxn(_("Event name changes"), self.db, batch=True) as trans:
) as trans:
self.db.disable_signals() self.db.disable_signals()
self.change = False self.change = False
counter = 0 counter = 0

View File

@ -46,6 +46,7 @@ import gobject
# gramps modules # gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
import ManagedWindow import ManagedWindow
import GrampsDisplay import GrampsDisplay
@ -591,8 +592,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help() GrampsDisplay.help()
def on_ok_clicked(self, obj): def on_ok_clicked(self, obj):
with self.db.transaction_begin(_("Extract Place data"), batch=True with DbTxn(_("Extract Place data"), self.db, batch=True) as self.trans:
) as self.trans:
self.db.disable_signals() self.db.disable_signals()
changelist = [node for node in self.iter_list changelist = [node for node in self.iter_list
if self.model.get_value(node, 0)] if self.model.get_value(node, 0)]

View File

@ -53,6 +53,7 @@ import GrampsDisplay
import Assistant import Assistant
import Errors import Errors
from gen.lib import MediaObject from gen.lib import MediaObject
from gen.db import DbTxn
from gen.updatecallback import UpdateCallback from gen.updatecallback import UpdateCallback
from gui.plug import tool from gui.plug import tool
from Utils import media_path_full, relative_path, media_path from Utils import media_path_full, relative_path, media_path
@ -359,7 +360,7 @@ class BatchOp(UpdateCallback):
Should not be overridden without good reasons. Should not be overridden without good reasons.
""" """
self.db.disable_signals() self.db.disable_signals()
with self.db.transaction_begin("", batch=True) as self.trans: with DbTxn("", self.db, batch=True) as self.trans:
success = self._run() success = self._run()
trans.set_description(self.title) trans.set_description(self.title)
self.db.enable_signals() self.db.enable_signals()

View File

@ -56,6 +56,7 @@ import GrampsDisplay
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
from glade import Glade from glade import Glade
from gen.lib import Tag from gen.lib import Tag
from gen.db import DbTxn
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -242,7 +243,7 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow.ManagedWindow) :
tag_name = self.tagcombo.get_active_text() tag_name = self.tagcombo.get_active_text()
# start the db transaction # start the db transaction
with self.db.transaction_begin("Tag not related") as transaction: with DbTxn("Tag not related", self.db) as transaction:
tag = self.db.get_tag_from_name(tag_name) tag = self.db.get_tag_from_name(tag_name)
if not tag: if not tag:

View File

@ -51,6 +51,7 @@ from QuestionDialog import OkDialog
import ManagedWindow import ManagedWindow
import GrampsDisplay import GrampsDisplay
import gen.lib import gen.lib
from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
from glade import Glade from glade import Glade
@ -481,8 +482,8 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC) GrampsDisplay.help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)
def on_ok_clicked(self, obj): def on_ok_clicked(self, obj):
with self.db.transaction_begin(_("Extract information from names"), with DbTxn(_("Extract information from names"), self.db, batch=True
batch=True) as trans: ) as trans:
self.db.disable_signals() self.db.disable_signals()
for key, data in self.handle_to_action.items(): for key, data in self.handle_to_action.items():

View File

@ -54,6 +54,7 @@ import gobject
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.db import DbTxn
import Errors import Errors
import ManagedWindow import ManagedWindow
from DateHandler import displayer as _dd from DateHandler import displayer as _dd
@ -279,8 +280,7 @@ class RemoveUnused(tool.Tool, ManagedWindow.ManagedWindow, UpdateCallback):
self.reset() self.reset()
def do_remove(self, obj): def do_remove(self, obj):
with self.db.transaction_begin(_("Remove unused objects"), with DbTxn(_("Remove unused objects"), self.db, batch=False) as trans:
batch=False) as trans:
self.db.disable_signals() self.db.disable_signals()
for row_num in range(len(self.real_model)-1, -1, -1): for row_num in range(len(self.real_model)-1, -1, -1):

View File

@ -42,6 +42,7 @@ from gen.ggettext import gettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gui.utils import ProgressMeter from gui.utils import ProgressMeter
import gen.lib import gen.lib
from gen.lib import DbTxn
from gui.plug import tool from gui.plug import tool
_findint = re.compile('^[^\d]*(\d+)[^\d]*') _findint = re.compile('^[^\d]*(\d+)[^\d]*')
@ -67,8 +68,7 @@ class ReorderIds(tool.BatchTool):
else: else:
print "Reordering Gramps IDs..." print "Reordering Gramps IDs..."
with db.transaction_begin(_("Reorder Gramps IDs"), batch=True with DbTxn(_("Reorder Gramps IDs"), db, batch=True) as self.trans:
) as self.trans:
db.disable_signals() db.disable_signals()
if uistate: if uistate:

View File

@ -37,6 +37,7 @@ from gen.ggettext import gettext as _
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Sort import Sort
from gen.db import DbTxn
from gui.plug import MenuToolOptions, PluginWindows from gui.plug import MenuToolOptions, PluginWindows
from gen.plug.report import utils as ReportUtils from gen.plug.report import utils as ReportUtils
from gen.plug.menu import FilterOption, PersonOption, \ from gen.plug.menu import FilterOption, PersonOption, \
@ -95,8 +96,7 @@ class SortEvents(PluginWindows.ToolManagedWindowBatch):
self.sort_name = sort_functions[sort_func_num][0] self.sort_name = sort_functions[sort_func_num][0]
self.sort_func = sort_functions[sort_func_num][1] self.sort_func = sort_functions[sort_func_num][1]
self.sort = Sort.Sort(self.db) self.sort = Sort.Sort(self.db)
with self.db.transaction_begin(_("Sort event changes"), batch=True with DbTxn(_("Sort event changes"), self.db, batch=True) as trans:
) as trans:
self.db.disable_signals() self.db.disable_signals()
family_handles = self.sort_person_events(trans) family_handles = self.sort_person_events(trans)
if len(family_handles) > 0: if len(family_handles) > 0:

View File

@ -59,6 +59,7 @@ import Utils
import Bookmarks import Bookmarks
import gen.mime import gen.mime
import gen.lib import gen.lib
from gen.db import DbTxn
from gui.editors import EditMedia, DeleteMediaQuery from gui.editors import EditMedia, DeleteMediaQuery
import Errors import Errors
from Filters.SideBar import MediaSidebarFilter from Filters.SideBar import MediaSidebarFilter
@ -206,8 +207,7 @@ class MediaView(ListView):
basename = os.path.basename(name) basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename) (root, ext) = os.path.splitext(basename)
photo.set_description(root) photo.set_description(root)
with self.dbstate.db.transaction_begin(_("Drag Media Object") with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans:
) as trans:
self.dbstate.db.add_object(photo, trans) self.dbstate.db.add_object(photo, trans)
widget.emit_stop_by_name('drag_data_received') widget.emit_stop_by_name('drag_data_received')

View File

@ -47,6 +47,7 @@ import pango
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from gen.db import DbTxn
from gui.views.navigationview import NavigationView from gui.views.navigationview import NavigationView
from gui.editors import EditPerson, EditFamily from gui.editors import EditPerson, EditFamily
from gui.filtereditor import FilterEditor from gui.filtereditor import FilterEditor
@ -1500,8 +1501,7 @@ class RelationshipView(NavigationView):
family = self.dbstate.db.get_family_from_handle(family_handle) family = self.dbstate.db.get_family_from_handle(family_handle)
family.add_child_ref(ref) family.add_child_ref(ref)
with self.dbstate.db.transaction_begin(_("Add Child to Family") with DbTxn(_("Add Child to Family"), self.dbstate.db) as trans:
) as trans:
#add parentref to child #add parentref to child
person.add_parent_family_handle(family_handle) person.add_parent_family_handle(family_handle)
#default relationship is used #default relationship is used

View File

@ -425,7 +425,7 @@ class DbDjango(DbReadBase, DbWriteBase):
print "object key:", obj_key print "object key:", obj_key
return [] return []
def transaction_begin(self, msg, batch, no_magic): def transaction_begin(self, transaction):
return return
def disable_signals(self): def disable_signals(self):