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
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay

View File

@ -29,6 +29,7 @@ Provide merge capabilities for families.
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
from gen.display.name import displayer as name_displayer
import const
@ -308,7 +309,7 @@ class MergeFamilyQuery(object):
new_handle = self.phoenix.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)
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
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
@ -184,7 +185,7 @@ class MergeMediaQuery(object):
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():
if person.has_media_reference(old_handle):
person.replace_media_references(old_handle, new_handle)

View File

@ -29,6 +29,7 @@ Provide merge capabilities for notes.
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
@ -196,7 +197,7 @@ class MergeNoteQuery(object):
new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle()
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():
if person.has_note_reference(old_handle):

View File

@ -38,6 +38,7 @@ import pango
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
from gen.plug.report import utils as ReportUtils
from gen.display.name import displayer as name_displayer
@ -406,7 +407,7 @@ class MergePersonQuery(object):
Merges two persons into a single person.
"""
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)
else:
self.__execute(family_merger, trans)

View File

@ -37,6 +37,7 @@ import gtk
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
@ -210,7 +211,7 @@ class MergePlaceQuery(object):
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():
if person.has_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
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
@ -171,7 +172,7 @@ class MergeRepoQuery(object):
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():
if source.has_repo_reference(old_handle):
source.replace_repo_references(old_handle, new_handle)

View File

@ -30,6 +30,7 @@ Provide merge capabilities for sources.
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
@ -197,7 +198,7 @@ class MergeSourceQuery(object):
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():
if person.has_source_reference(old_handle):
person.replace_source_references(old_handle, new_handle)

View File

@ -29,6 +29,7 @@ from gen.ggettext import gettext as _
# gramps modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
from gen.display.name import displayer as name_displayer
import ListModel
import ManagedWindow
@ -136,7 +137,7 @@ class Reorder(ManagedWindow.ManagedWindow):
def ok_clicked(self, obj):
name = name_displayer.display(self.person)
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.close()

View File

@ -39,6 +39,7 @@ from gen.ggettext import gettext as _
#
#-------------------------------------------------------------------------
import gen.lib
from txn import DbTxn
class DbReadBase(object):
"""
@ -1344,6 +1345,12 @@ class DbWriteBase(object):
"""
raise NotImplementedError
def get_undodb(self):
"""
Return the database that keeps track of Undo/Redo operations.
"""
raise NotImplementedError
def need_upgrade(self):
"""
Return True if database needs to be upgraded
@ -1479,18 +1486,35 @@ class DbWriteBase(object):
"""
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
transaction_commit function of the this database object.
Two modes should be provided: transaction.batch=False for ordinary
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
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
@ -1525,7 +1549,7 @@ class DbWriteBase(object):
child.add_parent_family_handle(family.handle)
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_person(child, trans)
else:
@ -1538,8 +1562,7 @@ class DbWriteBase(object):
it becomes empty.
"""
if trans is None:
with self.transaction_begin(_("Remove child from family")
) as trans:
with DbTxn(_("Remove child from family"), self) as trans:
self.__remove_child_from_family(person_handle, family_handle,
trans)
else:
@ -1617,7 +1640,7 @@ class DbWriteBase(object):
Remove a family and its relationships.
"""
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)
else:
self.__remove_family_relationships(family_handle, trans)
@ -1642,7 +1665,7 @@ class DbWriteBase(object):
deleting the family if it becomes empty.
"""
if trans is None:
with self.transaction_begin() as trans:
with DbTxn('', self) as trans:
msg = self.__remove_parent_from_family(person_handle,
family_handle, trans)
trans.set_description(msg)

View File

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

View File

@ -543,6 +543,12 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
except db.DBNoSuchFileError:
pass
def get_undodb(self):
"""
Return the database that keeps track of Undo/Redo operations.
"""
return self.undodb
def __load_metadata(self):
# name display formats
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
# 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:
callback(4)
@ -1019,6 +1025,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
def close(self):
if not self.db_is_open:
return
if self.txn:
self.transaction_abort(self.transaction)
self.env.txn_checkpoint()
self.__close_metadata()
@ -1234,7 +1242,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
old_data = data_map.get(handle, txn=self.txn)
data_map.delete(handle, txn=self.txn)
transaction.add(key, TXNDEL, handle, old_data, None)
#del_list.append(handle)
def remove_person(self, handle, transaction):
"""
@ -1257,7 +1264,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn=self.txn)
self.person_map.delete(str(handle), txn=self.txn)
transaction.add(PERSON_KEY, TXNDEL, handle, person.serialize(), None)
#transaction.person_del.append(str(handle))
def remove_source(self, handle, transaction):
"""
@ -1626,17 +1632,27 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return None
@catch_db_error
def transaction_begin(self, msg="", batch=False, no_magic=False):
"""
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.
def transaction_begin(self, transaction):
"""
Prepare the database for the start of a new Transaction.
transaction = DbTxn(msg, self.undodb, self, batch)
transaction.no_magic = no_magic
if batch:
Supported transaction parameters:
no_magic: Boolean, defaults to False, indicating if secondary indices
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
# Aborting the session completely will become impossible.
self.abort_possible = False
@ -1644,7 +1660,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.undodb.clear()
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
self.surnames.close()
_db = db.DB(self.env)
@ -1665,25 +1682,25 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return transaction
@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
transaction to the undo database.
"""
if not msg:
msg = transaction.get_description()
msg = transaction.get_description()
if self._LOG_ALL:
_LOG.debug("%s: Transaction commit '%s'\n"
% (self.__class__.__name__, str(msg)))
% (self.__class__.__name__, msg))
if self.readonly:
return
if self.txn is not None:
assert transaction.get_description() != ''
assert msg != ''
self.bsddbtxn.commit()
self.bsddbtxn = None
self.txn = None
self.transaction = None
self.env.log_flush()
if not transaction.batch:
emit = self.__emit
@ -1714,11 +1731,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
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:
_LOG.debug("%s: Transaction abort '%s'\n"
% (self.__class__.__name__, str(transaction.get_description())))
_LOG.debug("%s: Transaction abort '%s'\n" %
(self.__class__.__name__, transaction.get_description()))
if self.readonly:
return
@ -1727,6 +1744,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.bsddbtxn.abort()
self.bsddbtxn = None
self.txn = None
self.transaction = None
transaction.clear()
transaction.first = None
transaction.last = None
@ -1739,7 +1757,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if transaction.batch:
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
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.selectors import SelectorFactory
import gen.lib
from gen.db import DbTxn
import Utils
import ThumbNails
import Errors
@ -476,8 +477,8 @@ class GalleryTab(ButtonTab, DbGUIElement):
basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename)
photo.set_description(root)
with self.dbstate.db.transaction_begin(
_("Drag Media Object")) as trans:
with DbTxn(_("Drag Media Object"),
self.dbstate.db) as trans:
self.dbstate.db.add_object(photo, trans)
oref = gen.lib.MediaRef()
oref.set_reference_handle(photo.get_handle())

View File

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

View File

@ -34,6 +34,7 @@ from gen.ggettext import gettext as _
#
#-------------------------------------------------------------------------
import gen.lib
from gen.db import DbTxn
from glade import Glade
from displaytabs import (SourceEmbedList, NoteTab, GalleryTab,
EventBackRefList, AttrEmbedList)
@ -237,10 +238,10 @@ class EditEventRef(EditReference):
def ok_clicked(self, obj):
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)
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.source_ref.ref = self.source.handle

View File

@ -62,6 +62,7 @@ import Utils
import config
from gen.display.name import displayer as name_displayer
import gen.lib
from gen.db import DbTxn
import Errors
import DateHandler
from glade import Glade
@ -1060,7 +1061,7 @@ class EditFamily(EditPrimary):
self._cleanup_callbacks()
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
handle = self.obj.get_father_handle()
@ -1086,7 +1087,7 @@ class EditFamily(EditPrimary):
self.db.add_family(self.obj, trans)
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.obj.get_father_handle(), trans)

View File

@ -43,6 +43,7 @@ import gtk
#-------------------------------------------------------------------------
from gui.utils import open_file_with_default_application
import gen.lib
from gen.db import DbTxn
import gen.mime
import ThumbNails
import Utils
@ -288,7 +289,7 @@ class EditMedia(EditPrimary):
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():
self.db.add_object(self.obj, trans)
msg = _("Add Media Object (%s)") % self.obj.get_description()
@ -335,7 +336,7 @@ class DeleteMediaQuery(object):
self.the_lists = the_lists
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()
(person_list, family_list, event_list,

View File

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

View File

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

View File

@ -51,6 +51,7 @@ import pango
import Utils
from gui.utils import add_menuitem, open_file_with_default_application
import gen.lib
from gen.db import DbTxn
from gui import widgets
from gen.display.name import displayer as name_displayer
import Errors
@ -868,7 +869,7 @@ class EditPerson(EditPrimary):
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()
if not self.obj.get_handle():
self.db.add_person(self.obj, trans)

View File

@ -44,6 +44,7 @@ import gtk
#
#-------------------------------------------------------------------------
import gen.lib
from gen.db import DbTxn
from editprimary import EditPrimary
from displaytabs import (GrampsTab, LocationEmbedList, SourceEmbedList,
GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList)
@ -306,7 +307,7 @@ class EditPlace(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.transaction_begin() as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_place(self.obj, trans)
msg = _("Add Place (%s)") % self.obj.get_title()
@ -338,8 +339,8 @@ class DeletePlaceQuery(object):
self.event_list = event_list
def query_response(self):
with self.db.transaction_begin(_("Delete Place (%s)") %
self.obj.get_title()) as trans:
with DbTxn(_("Delete Place (%s)") % self.obj.get_title(),
self.db) as trans:
self.db.disable_signals()
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.db import DbTxn
from displaytabs import NoteTab,AddrEmbedList,WebEmbedList,SourceBackRefList
from gui.widgets import MonitoredEntry, PrivacyButton, MonitoredDataType
@ -190,10 +191,10 @@ class EditRepoRef(EditReference):
def ok_clicked(self, obj):
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)
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.source_ref.ref = self.source.handle

View File

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

View File

@ -43,6 +43,7 @@ import gtk
#
#-------------------------------------------------------------------------
import gen.lib
from gen.db import DbTxn
from editprimary import EditPrimary
from displaytabs import (NoteTab, GalleryTab, DataEmbedList,
@ -195,7 +196,7 @@ class EditSource(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.transaction_begin() as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_source(self.obj, trans)
msg = _("Add Source (%s)") % self.obj.get_title()
@ -216,8 +217,8 @@ class DeleteSrcQuery(object):
self.the_lists = the_lists
def query_response(self):
with self.db.transaction_begin(_("Delete Source (%s)") %
self.source.get_title()) as trans:
with DbTxn(_("Delete Source (%s)") % self.source.get_title(),
self.db) as trans:
self.db.disable_signals()
(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
from gen.db import DbTxn
from glade import Glade
from displaytabs import (NoteTab, GalleryTab, SourceBackRefList,
DataEmbedList, RepoEmbedList)
@ -206,10 +207,10 @@ class EditSourceRef(EditReference):
def ok_clicked(self, obj):
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)
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)
if self.update:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -53,6 +53,7 @@ import GrampsDisplay
import Assistant
import Errors
from gen.lib import MediaObject
from gen.db import DbTxn
from gen.updatecallback import UpdateCallback
from gui.plug import tool
from Utils import media_path_full, relative_path, media_path
@ -359,7 +360,7 @@ class BatchOp(UpdateCallback):
Should not be overridden without good reasons.
"""
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()
trans.set_description(self.title)
self.db.enable_signals()

View File

@ -56,6 +56,7 @@ import GrampsDisplay
from gen.ggettext import sgettext as _
from glade import Glade
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()
# 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)
if not tag:

View File

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

View File

@ -54,6 +54,7 @@ import gobject
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.db import DbTxn
import Errors
import ManagedWindow
from DateHandler import displayer as _dd
@ -279,8 +280,7 @@ class RemoveUnused(tool.Tool, ManagedWindow.ManagedWindow, UpdateCallback):
self.reset()
def do_remove(self, obj):
with self.db.transaction_begin(_("Remove unused objects"),
batch=False) as trans:
with DbTxn(_("Remove unused objects"), self.db, batch=False) as trans:
self.db.disable_signals()
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
import gen.lib
from gen.lib import DbTxn
from gui.plug import tool
_findint = re.compile('^[^\d]*(\d+)[^\d]*')
@ -67,8 +68,7 @@ class ReorderIds(tool.BatchTool):
else:
print "Reordering Gramps IDs..."
with db.transaction_begin(_("Reorder Gramps IDs"), batch=True
) as self.trans:
with DbTxn(_("Reorder Gramps IDs"), db, batch=True) as self.trans:
db.disable_signals()
if uistate:

View File

@ -37,6 +37,7 @@ from gen.ggettext import gettext as _
#-------------------------------------------------------------------------
import Sort
from gen.db import DbTxn
from gui.plug import MenuToolOptions, PluginWindows
from gen.plug.report import utils as ReportUtils
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_func = sort_functions[sort_func_num][1]
self.sort = Sort.Sort(self.db)
with self.db.transaction_begin(_("Sort event changes"), batch=True
) as trans:
with DbTxn(_("Sort event changes"), self.db, batch=True) as trans:
self.db.disable_signals()
family_handles = self.sort_person_events(trans)
if len(family_handles) > 0:

View File

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

View File

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

View File

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