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

This is a major patch by Michael Nauta. It means all writes happen immediately to bsddb, and the bsddb 
rollback is used on a crash. Transaction is no longer used to store changes and do them on commit.
Undo database is set on end. 
At the same time with statement is used throughout for transactions
At the same time, the original bug in merge code should be fixed
Still some issues, that will be ironed out


svn: r16523
This commit is contained in:
Benny Malengier 2011-01-31 21:54:58 +00:00
parent 28610b1ae3
commit 6d596ad987
49 changed files with 1842 additions and 1854 deletions

View File

@ -210,37 +210,37 @@ class MergeEventQuery(object):
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
for person in self.database.iter_people():
if person.has_handle_reference("Event", old_handle):
bri = person.birth_ref_index
dri = person.death_ref_index
person.replace_handle_reference("Event", old_handle, new_handle)
if person.birth_ref_index != bri and person.birth_ref_index==-1:
for index, ref in enumerate(person.get_event_ref_list()):
if ref.ref == new_handle:
event = self.phoenix
else:
event = self.database.get_event_from_handle(ref.ref)
if event.type.is_birth() and ref.role.is_primary():
person.birth_ref_index = index
break
if person.death_ref_index != dri and person.death_ref_index==-1:
for index, ref in enumerate(person.get_event_ref_list()):
if ref.ref == new_handle:
event = self.phoenix
else:
event = self.database.get_event_from_handle(ref.ref)
if event.type.is_death() and ref.role.is_primary():
person.death_ref_index = index
break
self.database.commit_person(person, trans)
trans = self.database.transaction_begin(_("Merge Event Objects"))
with self.database.transaction_begin() as trans:
for person in self.database.iter_people():
if person.has_handle_reference("Event", old_handle):
bri = person.birth_ref_index
dri = person.death_ref_index
person.replace_handle_reference("Event", old_handle, new_handle)
if person.birth_ref_index != bri and person.birth_ref_index==-1:
for index, ref in enumerate(person.get_event_ref_list()):
if ref.ref == new_handle:
event = self.phoenix
else:
event = self.database.get_event_from_handle(ref.ref)
if event.type.is_birth() and ref.role.is_primary():
person.birth_ref_index = index
break
if person.death_ref_index != dri and person.death_ref_index==-1:
for index, ref in enumerate(person.get_event_ref_list()):
if ref.ref == new_handle:
event = self.phoenix
else:
event = self.database.get_event_from_handle(ref.ref)
if event.type.is_death() and ref.role.is_primary():
person.death_ref_index = index
break
self.database.commit_person(person, trans)
for family in self.database.iter_families():
if family.has_handle_reference("Event", old_handle):
family.replace_handle_reference("Event", old_handle, new_handle)
self.database.commit_family(family, trans)
self.database.remove_event(old_handle, trans)
self.database.commit_event(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Event Objects"))
for family in self.database.iter_families():
if family.has_handle_reference("Event", old_handle):
family.replace_handle_reference("Event", old_handle, new_handle)
self.database.commit_family(family, trans)
self.database.remove_event(old_handle, trans)
self.database.commit_event(self.phoenix, trans)

View File

@ -60,10 +60,9 @@ class MergeFamilies(ManagedWindow.ManagedWindow):
"""
def __init__(self, dbstate, uistate, handle1, handle2):
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
self.dbstate = dbstate
database = dbstate.db
self.fy1 = database.get_family_from_handle(handle1)
self.fy2 = database.get_family_from_handle(handle2)
self.database = dbstate.db
self.fy1 = self.database.get_family_from_handle(handle1)
self.fy2 = self.database.get_family_from_handle(handle2)
self.define_glade('mergefamily', _GLADE_FILE)
self.set_window(self._gladeobj.toplevel,
@ -73,34 +72,56 @@ class MergeFamilies(ManagedWindow.ManagedWindow):
# Detailed selection widgets
father1 = self.fy1.get_father_handle()
father2 = self.fy2.get_father_handle()
father1 = database.get_person_from_handle(father1)
father2 = database.get_person_from_handle(father2)
father_id1 = father1.get_gramps_id()
father_id2 = father2.get_gramps_id()
father1 = self.database.get_person_from_handle(father1)
father2 = self.database.get_person_from_handle(father2)
father_id1 = father1.get_gramps_id() if father1 else ""
father_id2 = father2.get_gramps_id() if father2 else ""
father1 = name_displayer.display(father1) if father1 else ""
father2 = name_displayer.display(father2) if father2 else ""
entry1 = self.get_widget("father1")
entry2 = self.get_widget("father2")
entry1.set_text("%s [%s]" % (father1, father_id1))
entry2.set_text("%s [%s]" % (father2, father_id2))
if entry1.get_text() == entry2.get_text():
deactivate = False
if father_id1 == "" and father_id2 == "":
deactivate = True
elif father_id2 == "":
self.get_widget("father_btn1").set_active(True)
deactivate = True
elif father_id1 == "":
self.get_widget("father_btn2").set_active(True)
deactivate = True
elif entry1.get_text() == entry2.get_text():
deactivate = True
if deactivate:
for widget_name in ('father1', 'father2', 'father_btn1',
'father_btn2'):
self.get_widget(widget_name).set_sensitive(False)
mother1 = self.fy1.get_mother_handle()
mother2 = self.fy2.get_mother_handle()
mother1 = database.get_person_from_handle(mother1)
mother2 = database.get_person_from_handle(mother2)
mother_id1 = mother1.get_gramps_id()
mother_id2 = mother2.get_gramps_id()
mother1 = self.database.get_person_from_handle(mother1)
mother2 = self.database.get_person_from_handle(mother2)
mother_id1 = mother1.get_gramps_id() if mother1 else ""
mother_id2 = mother2.get_gramps_id() if mother2 else ""
mother1 = name_displayer.display(mother1) if mother1 else ""
mother2 = name_displayer.display(mother2) if mother2 else ""
entry1 = self.get_widget("mother1")
entry2 = self.get_widget("mother2")
entry1.set_text("%s [%s]" % (mother1, mother_id1))
entry2.set_text("%s [%s]" % (mother2, mother_id2))
if entry1.get_text() == entry2.get_text():
deactivate = False
if mother_id1 == "" and mother_id2 == "":
deactivate = True
elif mother_id1 == "":
self.get_widget("mother_btn2").set_active(True)
deactivate = True
elif mother_id2 == "":
self.get_widget("mother_btn1").set_active(True)
deactivate = True
elif entry1.get_text() == entry2.get_text():
deactivate = True
if deactivate:
for widget_name in ('mother1', 'mother2', 'mother_btn1',
'mother_btn2'):
self.get_widget(widget_name).set_sensitive(False)
@ -140,13 +161,25 @@ class MergeFamilies(ManagedWindow.ManagedWindow):
def on_handle1_toggled(self, obj):
"""Preferred family changes"""
if obj.get_active():
self.get_widget("father_btn1").set_active(True)
self.get_widget("mother_btn1").set_active(True)
father1_text = self.get_widget("father1").get_text()
if father1_text != " []" or (father1_text == " []" and
self.get_widget("father2").get_text() == " []"):
self.get_widget("father_btn1").set_active(True)
mother1_text = self.get_widget("mother1").get_text()
if mother1_text != " []" or (mother1_text == " []" and
self.get_widget("mother2").get_text() == " []"):
self.get_widget("mother_btn1").set_active(True)
self.get_widget("rel_btn1").set_active(True)
self.get_widget("gramps_btn1").set_active(True)
else:
self.get_widget("father_btn2").set_active(True)
self.get_widget("mother_btn2").set_active(True)
father2_text = self.get_widget("father2").get_text()
if father2_text != " []" or (father2_text == " []" and
self.get_widget("father1").get_text() == " []"):
self.get_widget("father_btn2").set_active(True)
mother2_text = self.get_widget("mother2").get_text()
if mother2_text != " []" or (mother2_text == " []" and
self.get_widget("mother1").get_text() == " []"):
self.get_widget("mother_btn2").set_active(True)
self.get_widget("rel_btn2").set_active(True)
self.get_widget("gramps_btn2").set_active(True)
@ -159,8 +192,6 @@ class MergeFamilies(ManagedWindow.ManagedWindow):
Perform the merge of the families when the merge button is clicked.
"""
self.uistate.set_busy_cursor(True)
need_commit = False
database = self.dbstate.db
use_handle1 = self.get_widget("handle_btn1").get_active()
if use_handle1:
phoenix = self.fy1
@ -171,78 +202,141 @@ class MergeFamilies(ManagedWindow.ManagedWindow):
titanic = self.fy1
unselect_path = (0,)
phoenix_father = database.get_person_from_handle(
phoenix.get_father_handle())
phoenix_mother = database.get_person_from_handle(
phoenix.get_mother_handle())
titanic_father = database.get_person_from_handle(
titanic.get_father_handle())
titanic_mother = database.get_person_from_handle(
titanic.get_mother_handle())
phoenix_fh = phoenix.get_father_handle()
phoenix_mh = phoenix.get_mother_handle()
trans = database.transaction_begin("", True)
# Use merge persons on father and mother to merge a family; The merge
# person routine also merges families if necessary. Merging is not
# an equal operation, there is one preferred family over the other.
# The preferred family is the first listed in a persons
# family_handle_list. Since the GUI allows users to chose the
# preferred father, mother and family independent of each other, while
# the merge person routine fixes preferred family with respect to
# father and mother, the father and mother need first to be swapped
# into the right family, before the merge person routines can be called.
if self.get_widget("father_btn1").get_active() ^ use_handle1:
father_handle = phoenix.get_father_handle()
phoenix.set_father_handle(titanic.get_father_handle())
titanic.set_father_handle(father_handle)
phoenix_father.replace_handle_reference('Family',
phoenix.get_handle(), titanic.get_handle())
titanic_father.replace_handle_reference('Family',
titanic.get_handle(), phoenix.get_handle())
phoenix_father, titanic_father = titanic_father, phoenix_father
database.commit_person(phoenix_father, trans)
database.commit_person(titanic_father, trans)
database.commit_family(phoenix, trans)
database.commit_family(titanic, trans)
phoenix_fh = titanic.get_father_handle()
if self.get_widget("mother_btn1").get_active() ^ use_handle1:
mother_handle = phoenix.get_mother_handle()
phoenix.set_mother_handle(titanic.get_mother_handle())
titanic.set_mother_handle(mother_handle)
phoenix_mother.replace_handle_reference('Family',
phoenix.get_handle(), titanic.get_handle())
titanic_mother.replace_handle_reference('Family',
titanic.get_handle(), phoenix.get_handle())
phoenix_mother, titanic_mother = titanic_mother, phoenix_mother
database.commit_person(phoenix_mother, trans)
database.commit_person(titanic_mother, trans)
database.commit_family(phoenix, trans)
database.commit_family(titanic, trans)
phoenix_mh = titanic.get_mother_handle()
if self.get_widget("rel_btn1").get_active() ^ use_handle1:
phoenix.set_relationship(titanic.get_relationship())
need_commit = True
if self.get_widget("gramps_btn1").get_active() ^ use_handle1:
phoenix.set_gramps_id(titanic.get_gramps_id())
need_commit = True
if need_commit:
database.commit_family(phoenix, trans)
try:
if phoenix_father != titanic_father:
query = MergePersonQuery(self.dbstate, phoenix_father,
titanic_father)
query.execute(trans)
if phoenix_mother != titanic_mother:
query = MergePersonQuery(self.dbstate, phoenix_mother,
titanic_mother)
query.execute(trans)
except MergeError, e:
ErrorDialog( _("Cannot merge people"), str(e))
# TODO: rollback
else:
database.transaction_commit(trans, _('Merge family'))
database.emit('family-rebuild')
query = MergeFamilyQuery(self.database, phoenix, titanic,
phoenix_fh, phoenix_mh)
query.execute()
except MergeError, err:
ErrorDialog( _("Cannot merge people"), str(err))
self.uistate.viewmanager.active_page.selection.unselect_path(
unselect_path)
self.uistate.set_busy_cursor(False)
self.close()
class MergeFamilyQuery(object):
"""
Create database query to merge two families.
"""
def __init__(self, database, phoenix, titanic, phoenix_fh, phoenix_mh):
self.database = database
self.phoenix = phoenix
self.titanic = titanic
self.phoenix_fh = phoenix_fh
if self.phoenix.get_father_handle() == self.phoenix_fh:
self.titanic_fh = self.titanic.get_father_handle()
self.father_swapped = False
else:
assert self.phoenix_fh == self.titanic.get_father_handle()
self.titanic_fh = self.phoenix.get_father_handle()
self.father_swapped = True
self.phoenix_mh = phoenix_mh
if self.phoenix.get_mother_handle() == self.phoenix_mh:
self.titanic_mh = self.titanic.get_mother_handle()
self.mother_swapped = False
else:
assert self.phoenix_mh == self.titanic.get_mother_handle()
self.titanic_mh = self.phoenix.get_mother_handle()
self.mother_swapped = True
def merge_person(self, phoenix_person, titanic_person, parent, trans):
"""
Merge two persons even if they are None; no families are merged!
"""
new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle()
if parent == 'father':
swapped = self.father_swapped
adjust_family_parent_handle = 'set_father_handle'
elif parent == 'mother':
swapped = self.mother_swapped
adjust_family_parent_handle = 'set_mother_handle'
else:
raise ValueError(_("A parent should be a father or mother."))
if phoenix_person is None:
if titanic_person is not None:
raise MergeError(_("""When merging people where one person """
"""doesn't exist, that "person" must be the person that """
"""will be deleted from the database."""))
return
elif titanic_person is None:
if swapped:
if [childref for childref in self.phoenix.get_child_ref_list()
if childref.get_reference_handle() ==
phoenix_person.get_handle()]:
raise MergeError(_("A parent and child cannot be merged. "
"To merge these people, you must first break the "
"relationship between them."))
phoenix_person.add_family_handle(new_handle)
getattr(self.phoenix, adjust_family_parent_handle)(
phoenix_person.get_handle())
self.database.commit_family(self.phoenix, trans)
else:
if [childref for childref in self.titanic.get_child_ref_list()
if childref.get_reference_handle() ==
phoenix_person.get_handle()]:
raise MergeError(_("A parent and child cannot be merged. "
"To merge these people, you must first break the "
"relationship between them."))
phoenix_person.add_family_handle(old_handle)
getattr(self.titanic, adjust_family_parent_handle)(
phoenix_person.get_handle())
self.database.commit_family(self.titanic, trans)
self.database.commit_person(phoenix_person, trans)
else:
query = MergePersonQuery(self.database, phoenix_person, titanic_person)
query.execute(family_merger=False, trans=trans)
def execute(self):
"""
Merges two families into a single family.
"""
new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle()
with self.database.transaction_begin(_('Merge Family')) as trans:
phoenix_father = self.database.get_person_from_handle(self.phoenix_fh)
titanic_father = self.database.get_person_from_handle(self.titanic_fh)
self.merge_person(phoenix_father, titanic_father, 'father', trans)
phoenix_mother = self.database.get_person_from_handle(self.phoenix_mh)
titanic_mother = self.database.get_person_from_handle(self.titanic_mh)
self.phoenix = self.database.get_family_from_handle(new_handle)
self.titanic = self.database.get_family_from_handle(old_handle)
self.merge_person(phoenix_mother, titanic_mother, 'mother', trans)
phoenix_father = self.database.get_person_from_handle(self.phoenix_fh)
phoenix_mother = self.database.get_person_from_handle(self.phoenix_mh)
self.phoenix = self.database.get_family_from_handle(new_handle)
self.titanic = self.database.get_family_from_handle(old_handle)
self.phoenix.merge(self.titanic)
for childref in self.titanic.get_child_ref_list():
child = self.database.get_person_from_handle(
childref.get_reference_handle())
if new_handle in child.parent_family_list:
child.remove_handle_references('Family', [old_handle])
else:
child.replace_handle_reference('Family', old_handle, new_handle)
self.database.commit_person(child, trans)
if phoenix_father:
phoenix_father.remove_family_handle(old_handle)
self.database.commit_person(phoenix_father, trans)
if phoenix_mother:
phoenix_mother.remove_family_handle(old_handle)
self.database.commit_person(phoenix_mother, trans)
self.database.remove_family(old_handle, trans)
self.database.commit_family(self.phoenix, trans)

View File

@ -184,32 +184,31 @@ class MergeMediaQuery(object):
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
for person in self.database.iter_people():
if person.has_media_reference(old_handle):
person.replace_media_references(old_handle, new_handle)
self.database.commit_person(person, trans)
with self.database.transaction_begin(_("Merge Media Ojbects")) as trans:
for person in self.database.iter_people():
if person.has_media_reference(old_handle):
person.replace_media_references(old_handle, new_handle)
self.database.commit_person(person, trans)
for family in self.database.iter_families():
if family.has_media_reference(old_handle):
family.replace_media_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for family in self.database.iter_families():
if family.has_media_reference(old_handle):
family.replace_media_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for event in self.database.iter_events():
if event.has_media_reference(old_handle):
event.replace_media_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for event in self.database.iter_events():
if event.has_media_reference(old_handle):
event.replace_media_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for source in self.database.iter_sources():
if source.has_media_reference(old_handle):
source.replace_media_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for source in self.database.iter_sources():
if source.has_media_reference(old_handle):
source.replace_media_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for place in self.database.iter_places():
if place.has_media_reference(old_handle):
place.replace_media_references(old_handle, new_handle)
self.database.commit_place(place, trans)
for place in self.database.iter_places():
if place.has_media_reference(old_handle):
place.replace_media_references(old_handle, new_handle)
self.database.commit_place(place, trans)
self.database.remove_object(old_handle, trans)
self.database.commit_media_object(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Media Objects"))
self.database.remove_object(old_handle, trans)
self.database.commit_media_object(self.phoenix, trans)

View File

@ -196,43 +196,42 @@ class MergeNoteQuery(object):
new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle()
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
with self.database.transaction_begin(_("Merge Notes")) as trans:
for person in self.database.iter_people():
if person.has_note_reference(old_handle):
person.replace_note_references(old_handle, new_handle)
self.database.commit_person(person, trans)
for person in self.database.iter_people():
if person.has_note_reference(old_handle):
person.replace_note_references(old_handle, new_handle)
self.database.commit_person(person, trans)
for family in self.database.iter_families():
if family.has_note_reference(old_handle):
family.replace_note_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for family in self.database.iter_families():
if family.has_note_reference(old_handle):
family.replace_note_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for event in self.database.iter_events():
if event.has_note_reference(old_handle):
event.replace_note_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for event in self.database.iter_events():
if event.has_note_reference(old_handle):
event.replace_note_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for source in self.database.iter_sources():
if source.has_note_reference(old_handle):
source.replace_note_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for source in self.database.iter_sources():
if source.has_note_reference(old_handle):
source.replace_note_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for place in self.database.iter_places():
if place.has_note_reference(old_handle):
place.replace_note_references(old_handle, new_handle)
self.database.commit_place(place, trans)
for place in self.database.iter_places():
if place.has_note_reference(old_handle):
place.replace_note_references(old_handle, new_handle)
self.database.commit_place(place, trans)
for obj in self.database.iter_media_objects():
if obj.has_note_reference(old_handle):
obj.replace_note_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
for obj in self.database.iter_media_objects():
if obj.has_note_reference(old_handle):
obj.replace_note_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
for repo in self.database.iter_repositories():
if repo.has_note_reference(old_handle):
repo.replace_note_references(old_handle, new_handle)
self.database.commit_repository(repo, trans)
for repo in self.database.iter_repositories():
if repo.has_note_reference(old_handle):
repo.replace_note_references(old_handle, new_handle)
self.database.commit_repository(repo, trans)
self.database.remove_note(old_handle, trans)
self.database.commit_note(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Notes"))
self.database.remove_note(old_handle, trans)
self.database.commit_note(self.phoenix, trans)

View File

@ -73,10 +73,9 @@ class MergePeople(ManagedWindow.ManagedWindow):
def __init__(self, dbstate, uistate, handle1, handle2, cb_update=None,
expand_context_info=False):
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
self.dbstate = dbstate
database = dbstate.db
self.pr1 = database.get_person_from_handle(handle1)
self.pr2 = database.get_person_from_handle(handle2)
self.database = dbstate.db
self.pr1 = self.database.get_person_from_handle(handle1)
self.pr2 = self.database.get_person_from_handle(handle2)
self.update = cb_update
self.define_glade('mergeperson', _GLADE_FILE)
@ -159,7 +158,6 @@ class MergePeople(ManagedWindow.ManagedWindow):
def display(self, tobj, person):
"""Fill text buffer tobj with detailed info on person person."""
database = self.dbstate.db
normal = tobj.create_tag()
normal.set_property('indent', 10)
normal.set_property('pixels-above-lines', 1)
@ -198,7 +196,7 @@ class MergePeople(ManagedWindow.ManagedWindow):
for event_ref in person.get_event_ref_list():
event_handle = event_ref.ref
name = str(
database.get_event_from_handle(event_handle).get_type())
self.database.get_event_from_handle(event_handle).get_type())
self.add(tobj, normal, "%s:\t%s" %
(name, self.get_event_info(event_handle)))
plist = person.get_parent_family_handle_list()
@ -220,22 +218,22 @@ class MergePeople(ManagedWindow.ManagedWindow):
if len(slist) > 0:
for fid in slist:
(fname, mname, pid) = self.get_parent_info(fid)
family = database.get_family_from_handle(fid)
family = self.database.get_family_from_handle(fid)
self.add(tobj, normal, "%s:\t%s" % (_('Family ID'), pid))
spouse_id = ReportUtils.find_spouse(person, family)
if spouse_id:
spouse = database.get_person_from_handle(spouse_id)
spouse = self.database.get_person_from_handle(spouse_id)
self.add(tobj, indent, "%s:\t%s" % (_('Spouse'),
name_of(spouse)))
relstr = str(family.get_relationship())
self.add(tobj, indent, "%s:\t%s" % (_('Type'), relstr))
event = ReportUtils.find_marriage(database, family)
event = ReportUtils.find_marriage(self.database, family)
if event:
self.add(tobj, indent, "%s:\t%s" % (
_('Marriage'),
self.get_event_info(event.get_handle())))
for child_ref in family.get_child_ref_list():
child = database.get_person_from_handle(child_ref.ref)
child = self.database.get_person_from_handle(child_ref.ref)
self.add(tobj, indent, "%s:\t%s" % (_('Child'),
name_of(child)))
else:
@ -252,17 +250,16 @@ class MergePeople(ManagedWindow.ManagedWindow):
def get_parent_info(self, fid):
"""Return tuple of father name, mother name and family ID"""
database = self.dbstate.db
family = database.get_family_from_handle(fid)
family = self.database.get_family_from_handle(fid)
father_id = family.get_father_handle()
mother_id = family.get_mother_handle()
if father_id:
father = database.get_person_from_handle(father_id)
father = self.database.get_person_from_handle(father_id)
fname = name_of(father)
else:
fname = u""
if mother_id:
mother = database.get_person_from_handle(mother_id)
mother = self.database.get_person_from_handle(mother_id)
mname = name_of(mother)
else:
mname = u""
@ -273,7 +270,7 @@ class MergePeople(ManagedWindow.ManagedWindow):
date = ""
place = ""
if handle:
event = self.dbstate.db.get_event_from_handle(handle)
event = self.database.db.get_event_from_handle(handle)
date = DateHandler.get_date(event)
place = self.place_name(event)
if date:
@ -287,7 +284,7 @@ class MergePeople(ManagedWindow.ManagedWindow):
"""Return place name of an event as string."""
place_id = event.get_place_handle()
if place_id:
place = self.dbstate.db.get_place_from_handle(place_id)
place = self.database.db.get_place_from_handle(place_id)
return place.get_title()
else:
return ""
@ -323,7 +320,7 @@ class MergePeople(ManagedWindow.ManagedWindow):
titanic.set_gramps_id(swapid)
try:
query = MergePersonQuery(self.dbstate, phoenix, titanic)
query = MergePersonQuery(self.database, phoenix, titanic)
query.execute()
except MergeError, err:
ErrorDialog( _("Cannot merge people"), str(err))
@ -338,8 +335,8 @@ class MergePersonQuery(object):
"""
Create database query to merge two persons.
"""
def __init__(self, dbstate, phoenix, titanic):
self.database = dbstate.db
def __init__(self, database, phoenix, titanic):
self.database = database
self.phoenix = phoenix
self.titanic = titanic
if self.check_for_spouse(self.phoenix, self.titanic):
@ -365,7 +362,7 @@ class MergePersonQuery(object):
return len(fs1.intersection(fp2)) != 0 or len(fs2.intersection(fp1))
def merge_families(self, main_family_handle, family, trans):
new_handle = self.phoenix.get_handle()
new_handle = self.phoenix.get_handle() if self.phoenix else None
family_handle = family.get_handle()
main_family = self.database.get_family_from_handle(main_family_handle)
main_family.merge(family)
@ -378,17 +375,26 @@ class MergePersonQuery(object):
child.replace_handle_reference('Family', family_handle,
main_family_handle)
self.database.commit_person(child, trans)
self.phoenix.remove_family_handle(family_handle)
if self.phoenix:
self.phoenix.remove_family_handle(family_handle)
family_father_handle = family.get_father_handle()
spouse_handle = family.get_mother_handle() if \
new_handle == family_father_handle else family_father_handle
spouse = self.database.get_person_from_handle(spouse_handle)
spouse.remove_family_handle(family_handle)
self.database.commit_person(spouse, trans)
if spouse:
spouse.remove_family_handle(family_handle)
self.database.commit_person(spouse, trans)
self.database.remove_family(family_handle, trans)
self.database.commit_family(main_family, trans)
def execute(self, trans=None):
def execute(self, family_merger=True, trans=None):
if trans is None:
with self.database.transaction_begin(_('Merge Person')) as trans:
self.__execute(family_merger, trans)
else:
self.__execute(family_merger, trans)
def __execute(self, family_merger, trans):
"""
Merges two persons into a single person.
"""
@ -397,32 +403,15 @@ class MergePersonQuery(object):
self.phoenix.merge(self.titanic)
# For now use a batch transaction, because merger of persons is
# complicated, thus is done in several steps and the database should
# be updated after each step for the calculation of the next step.
# Normal Gramps transactions only touch the database upon
# transaction_commit, not after each commit_person/commit_family.
# Unfortunately batch transactions are no transactions at all, so there
# is not possibility of rollback in case of trouble.
if trans is None:
need_commit = True
trans = self.database.transaction_begin("", True)
else:
need_commit = False
commit_persons = []
for person in self.database.iter_people():
if person.has_handle_reference('Person', old_handle):
person.replace_handle_reference('Person', old_handle,new_handle)
#self.database.commit_person(person, trans) # DEADLOCK
person_handle = person.get_handle()
if person_handle == new_handle:
self.phoenix.replace_handle_reference('Person', old_handle,
new_handle)
elif person_handle != old_handle:
commit_persons.append(person)
for person in commit_persons:
self.database.commit_person(person, trans)
for (p_dummy, person_handle) in self.database.find_backlink_handles(
old_handle, ['Person']):
person = self.database.get_person_from_handle(person_handle)
assert person.has_handle_reference('Person', old_handle)
person.replace_handle_reference('Person', old_handle, new_handle)
if person_handle != new_handle and person_handle != old_handle:
self.database.commit_person(person, trans)
# phoenix changed and can't be determined from database nor transaction
self.phoenix.replace_handle_reference('Person', old_handle, new_handle)
for family_handle in self.phoenix.get_parent_family_handle_list():
family = self.database.get_family_from_handle(family_handle)
@ -430,27 +419,36 @@ class MergePersonQuery(object):
family.replace_handle_reference('Person', old_handle,new_handle)
self.database.commit_family(family, trans)
family_merge_guard = False
parent_list = []
parent_list_orig = []
family_handle_list = self.phoenix.get_family_handle_list()[:]
for family_handle in family_handle_list:
family = self.database.get_family_from_handle(family_handle)
parents = (family.get_father_handle(), family.get_mother_handle())
parent_list_orig.append(parents)
if family.has_handle_reference('Person', old_handle):
if family_merger and parent_list_orig.count(parents) > 1:
raise MergeError(_("A person with multiple relations with "
"the same spouse is about to be merged. This is beyond "
"the capabilities of the merge routine. The merge is "
"aborted."))
family.replace_handle_reference('Person', old_handle,new_handle)
parents = (family.get_father_handle(),
family.get_mother_handle())
# prune means merging families in this case.
if parents in parent_list:
if family_merger and parents in parent_list:
# also merge when father_handle or mother_handle == None!
if family_merge_guard:
raise MergeError(_("Multiple families get merged. "
"This is unusual, the merge is aborted."))
idx = parent_list.index(parents)
main_family_handle = family_handle_list[idx]
self.merge_families(main_family_handle, family, trans)
family_merge_guard = True
continue
self.database.commit_family(family, trans)
parent_list.append(parents)
self.database.remove_person(old_handle, trans)
self.database.commit_person(self.phoenix, trans)
if need_commit:
self.database.transaction_commit(trans, _('Merge Person'))
self.database.emit('person-rebuild')

View File

@ -210,22 +210,24 @@ class MergePlaceQuery(object):
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
for person in self.database.iter_people():
if person.has_handle_reference('Place', old_handle):
person.replace_handle_reference('Place', old_handle, new_handle)
self.database.commit_person(person, trans)
with self.database.transaction_begin(_("Merge Places")) as trans:
for person in self.database.iter_people():
if person.has_handle_reference('Place', old_handle):
person.replace_handle_reference('Place', old_handle,
new_handle)
self.database.commit_person(person, trans)
for family in self.database.iter_families():
if family.has_handle_reference('Place', old_handle):
family.replace_handle_reference('Place', old_handle, new_handle)
self.database.commit_family(family, trans)
for family in self.database.iter_families():
if family.has_handle_reference('Place', old_handle):
family.replace_handle_reference('Place', old_handle,
new_handle)
self.database.commit_family(family, trans)
for event in self.database.iter_events():
if event.has_handle_reference('Place', old_handle):
event.replace_handle_reference('Place', old_handle, new_handle)
self.database.commit_event(event, trans)
for event in self.database.iter_events():
if event.has_handle_reference('Place', old_handle):
event.replace_handle_reference('Place', old_handle,
new_handle)
self.database.commit_event(event, trans)
self.database.remove_place(old_handle, trans)
self.database.commit_place(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Places"))
self.database.remove_place(old_handle, trans)
self.database.commit_place(self.phoenix, trans)

View File

@ -171,11 +171,10 @@ class MergeRepoQuery(object):
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
for source in self.database.iter_sources():
if source.has_repo_reference(old_handle):
source.replace_repo_references(old_handle, new_handle)
self.database.commit_source(source, trans)
self.database.remove_repository(old_handle, trans)
self.database.commit_repository(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Repositories"))
with self.database.transaction_begin(_("Merge Repositories")) as trans:
for source in self.database.iter_sources():
if source.has_repo_reference(old_handle):
source.replace_repo_references(old_handle, new_handle)
self.database.commit_source(source, trans)
self.database.remove_repository(old_handle, trans)
self.database.commit_repository(self.phoenix, trans)

View File

@ -197,42 +197,41 @@ class MergeSourceQuery(object):
self.phoenix.merge(self.titanic)
trans = self.database.transaction_begin()
for person in self.database.iter_people():
if person.has_source_reference(old_handle):
person.replace_source_references(old_handle, new_handle)
self.database.commit_person(person, trans)
with self.database.transaction_begin(_("Merge Source")) as trans:
for person in self.database.iter_people():
if person.has_source_reference(old_handle):
person.replace_source_references(old_handle, new_handle)
self.database.commit_person(person, trans)
for family in self.database.iter_families():
if family.has_source_reference(old_handle):
family.replace_source_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for family in self.database.iter_families():
if family.has_source_reference(old_handle):
family.replace_source_references(old_handle, new_handle)
self.database.commit_family(family, trans)
for event in self.database.iter_events():
if event.has_source_reference(old_handle):
event.replace_source_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for event in self.database.iter_events():
if event.has_source_reference(old_handle):
event.replace_source_references(old_handle, new_handle)
self.database.commit_event(event, trans)
for source in self.database.iter_sources():
if source.has_source_reference(old_handle):
source.replace_source_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for source in self.database.iter_sources():
if source.has_source_reference(old_handle):
source.replace_source_references(old_handle, new_handle)
self.database.commit_source(source, trans)
for place in self.database.iter_places():
if place.has_source_reference(old_handle):
place.replace_source_references(old_handle, new_handle)
self.database.commit_place(place, trans)
for place in self.database.iter_places():
if place.has_source_reference(old_handle):
place.replace_source_references(old_handle, new_handle)
self.database.commit_place(place, trans)
for obj in self.database.iter_media_objects():
if obj.has_source_reference(old_handle):
obj.replace_source_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
for obj in self.database.iter_media_objects():
if obj.has_source_reference(old_handle):
obj.replace_source_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
for repo in self.database.iter_repositories():
if repo.has_source_reference(old_handle):
repo.replace_source_references(old_handle, new_handle)
self.database.commit_repository(repo, trans)
for repo in self.database.iter_repositories():
if repo.has_source_reference(old_handle):
repo.replace_source_references(old_handle, new_handle)
self.database.commit_repository(repo, trans)
self.database.remove_source(old_handle, trans)
self.database.commit_source(self.phoenix, trans)
self.database.transaction_commit(trans, _("Merge Sources"))
self.database.remove_source(old_handle, trans)
self.database.commit_source(self.phoenix, trans)

View File

@ -134,11 +134,10 @@ class Reorder(ManagedWindow.ManagedWindow):
self.close()
def ok_clicked(self, obj):
trans = self.dbstate.db.transaction_begin()
self.dbstate.db.commit_person(self.person, trans)
name = name_displayer.display(self.person)
msg = _("Reorder Relationships: %s") % name
self.dbstate.db.transaction_commit(trans, msg)
with self.dbstate.db.transaction_begin(msg) as trans:
self.dbstate.db.commit_person(self.person, trans)
self.close()

View File

@ -1525,33 +1525,37 @@ class DbWriteBase(object):
child.add_parent_family_handle(family.handle)
if trans is None:
need_commit = True
trans = self.transaction_begin()
with self.transaction_begin(_('Add child to family')) as trans:
self.commit_family(family, trans)
self.commit_person(child, trans)
else:
need_commit = False
self.commit_family(family,trans)
self.commit_person(child,trans)
if need_commit:
self.transaction_commit(trans, _('Add child to family') )
self.commit_family(family, trans)
self.commit_person(child, trans)
def remove_child_from_family(self, person_handle, family_handle, trans=None):
"""
Remove a person as a child of the family, deleting the family if
it becomes empty.
"""
if trans is None:
with self.transaction_begin(_("Remove child from family")
) as trans:
self.__remove_child_from_family(person_handle, family_handle,
trans)
else:
self.__remove_child_from_family(person_handle, family_handle, trans)
trans.set_description(_("Remove child from family"))
def __remove_child_from_family(self, person_handle, family_handle, trans):
"""
Remove a person as a child of the family, deleting the family if
it becomes empty; trans is compulsory.
"""
person = self.get_person_from_handle(person_handle)
family = self.get_family_from_handle(family_handle)
person.remove_parent_family_handle(family_handle)
family.remove_child_handle(person_handle)
if trans is None:
need_commit = True
trans = self.transaction_begin()
else:
need_commit = False
child_list = family.get_child_ref_list()
if (not family.get_father_handle() and not family.get_mother_handle() and
len(child_list) <= 1):
@ -1564,9 +1568,6 @@ class DbWriteBase(object):
self.commit_family(family, trans)
self.commit_person(person, trans)
if need_commit:
self.transaction_commit(trans,_("Remove child from family"))
def delete_person_from_database(self, person, trans):
"""
Deletes a person from the database, cleaning up all associated references.
@ -1615,13 +1616,18 @@ class DbWriteBase(object):
"""
Remove a family and its relationships.
"""
family = self.get_family_from_handle(family_handle)
if trans is None:
need_commit = True
trans = self.transaction_begin()
with self.transaction_begin(_("Remove Family")) as trans:
self.__remove_family_relationships(family_handle, trans)
else:
need_commit = False
self.__remove_family_relationships(family_handle, trans)
trans.set_description(_("Remove Family"))
def __remove_family_relationships(self, family_handle, trans):
"""
Remove a family and its relationships; trans is compulsory.
"""
family = self.get_family_from_handle(family_handle)
for phandle in [ family.get_father_handle(),
family.get_mother_handle()]:
@ -1638,23 +1644,30 @@ class DbWriteBase(object):
self.remove_family(family_handle, trans)
if need_commit:
self.transaction_commit(trans, _("Remove Family"))
def remove_parent_from_family(self, person_handle, family_handle, trans=None):
def remove_parent_from_family(self, person_handle, family_handle,
trans=None):
"""
Remove a person as either the father or mother of a family,
deleting the family if it becomes empty.
"""
if trans is None:
with self.transaction_begin() as trans:
msg = self.__remove_parent_from_family(person_handle,
family_handle, trans)
trans.set_description(msg)
else:
msg = self.__remove_parent_from_family(person_handle,
family_handle, trans)
trans.set_description(msg)
def __remove_parent_from_family(self, person_handle, family_handle, trans):
"""
Remove a person as either the father or mother of a family,
deleting the family if it becomes empty; trans is compulsory.
"""
person = self.get_person_from_handle(person_handle)
family = self.get_family_from_handle(family_handle)
if trans is None:
need_commit = True
trans = self.transaction_begin()
else:
need_commit = False
person.remove_family_handle(family_handle)
if family.get_father_handle() == person_handle:
family.set_father_handle(None)
@ -1674,10 +1687,8 @@ class DbWriteBase(object):
else:
self.commit_family(family, trans)
self.commit_person(person, trans)
if need_commit:
self.transaction_commit(trans,msg)
return msg
def marriage_from_eventref_list(self, eventref_list):
"""
Get the marriage event from an eventref list.

View File

@ -475,13 +475,12 @@ class DbBsddbRead(DbReadBase, Callback):
self.emit('note-rebuild')
self.emit('tag-rebuild')
@staticmethod
def __find_next_gramps_id(prefix, map_index, trans):
def __find_next_gramps_id(self, prefix, map_index, trans):
"""
Helper function for find_next_<object>_gramps_id methods
"""
index = prefix % map_index
while trans.has_key(str(index)):
while trans.get(str(index), txn=self.txn) is not None:
map_index += 1
index = prefix % map_index
map_index += 1
@ -670,8 +669,8 @@ class DbBsddbRead(DbReadBase, Callback):
def __get_obj_from_gramps_id(self, val, tbl, class_, prim_tbl):
try:
if tbl.has_key(str(val)):
data = tbl.get(str(val), txn=self.txn)
data = tbl.get(str(val), txn=self.txn)
if data is not None:
obj = class_()
### FIXME: this is a dirty hack that works without no
### sensible explanation. For some reason, for a readonly
@ -786,6 +785,8 @@ class DbBsddbRead(DbReadBase, Callback):
"""
Return if a key exists in the name_group table.
"""
# The use of has_key seems allright because there is no write lock
# on the name_group table when this is called.
return self.name_group.has_key(str(name))
def get_number_of_records(self, table):
@ -1037,7 +1038,7 @@ class DbBsddbRead(DbReadBase, Callback):
table = key2table[obj_key]
#return str(gramps_id) in table
return table.has_key(str(gramps_id))
return table.get(str(gramps_id), txn=self.txn) is not None
def find_initial_person(self):
person = self.get_default_person()

View File

@ -32,12 +32,6 @@ database.
#-------------------------------------------------------------------------
from __future__ import with_statement
import cPickle as pickle
import config
if config.get('preferences.use-bsddb3'):
from bsddb3 import dbshelve, db
else:
from bsddb import dbshelve, db
import logging
from collections import defaultdict
@ -47,12 +41,11 @@ from collections import defaultdict
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.db.dbconst import *
from gen.db import BSDDBTxn
import Errors
from gen.db.dbconst import (DBLOGNAME, TXNADD, TXNUPD, TXNDEL)
_LOG = logging.getLogger(DBLOGNAME)
#-------------------------------------------------------------------------
#
# Gramps transaction class
@ -65,14 +58,8 @@ class DbTxn(defaultdict):
database
"""
__slots__ = ('msg', 'commitdb', 'db', 'first',
'last', 'timestamp', 'db_maps')
def get_db_txn(self, value):
"""
Return a transaction object from the database
"""
raise NotImplementedError
__slots__ = ('msg', 'commitdb', 'db', 'batch', 'first',
'last', 'timestamp', '__dict__')
def __enter__(self):
"""
@ -85,10 +72,12 @@ class DbTxn(defaultdict):
Context manager exit method
"""
if exc_type is None:
self.commit()
return exc_type is None
self.db.transaction_commit(self)
else:
self.db.transaction_abort(self)
return False
def __init__(self, msg, commitdb, grampsdb):
def __init__(self, msg, commitdb, grampsdb, batch):
"""
Create a new transaction.
@ -120,24 +109,11 @@ class DbTxn(defaultdict):
self.msg = msg
self.commitdb = commitdb
self.db = grampsdb
self.batch = batch
self.first = None
self.last = None
self.timestamp = 0
# Dictionary to enable table-driven logic in the class
self.db_maps = {
PERSON_KEY: (self.db.person_map, 'person'),
FAMILY_KEY: (self.db.family_map, 'family'),
EVENT_KEY: (self.db.event_map, 'event'),
SOURCE_KEY: (self.db.source_map, 'source'),
PLACE_KEY: (self.db.place_map, 'place'),
MEDIA_KEY: (self.db.media_map, 'media'),
REPOSITORY_KEY: (self.db.repository_map, 'repository'),
#REFERENCE_KEY: (self.db.reference_map, 'reference'),
NOTE_KEY: (self.db.note_map, 'note'),
TAG_KEY: (self.db.tag_map, 'tag'),
}
def get_description(self):
"""
Return the text string that describes the logical operation performed
@ -166,6 +142,7 @@ class DbTxn(defaultdict):
self.last = len(self.commitdb) -1
if self.first is None:
self.first = self.last
_LOG.debug('added to trans: %d %d %s' % (obj_type, trans_type, handle))
self[(obj_type, trans_type)] += [(handle, new_data)]
return
@ -200,133 +177,58 @@ class DbTxn(defaultdict):
return 0
return self.last - self.first + 1
def commit(self, msg=None):
"""
Commit the transaction to the assocated commit database.
"""
if msg is not None:
self.msg = msg
if not len(self) or self.db.readonly:
return
# Begin new database transaction
txn = self.get_db_txn(self.db.env)
self.db.txn = txn.begin()
# Commit all add transactions to the database
db_map = lambda key: self.db_maps[key][0]
for (obj_type, trans_type), data in self.iteritems():
if trans_type == TXNADD and obj_type in self.db_maps:
for handle, new_data in data:
assert handle == str(handle)
db_map(obj_type).put(handle, new_data, txn=txn.txn)
# Commit all update transactions to the database
for (obj_type, trans_type), data in self.iteritems():
if trans_type == TXNUPD and obj_type in self.db_maps:
for handle, new_data in data:
assert handle == str(handle)
db_map(obj_type).put(handle, new_data, txn=txn.txn)
# Before we commit delete transactions, emit signals as required
# Loop through the data maps, emitting signals as required
emit = self.__emit
for obj_type, (m_, obj_name) in self.db_maps.iteritems():
# Do an emit for each object and transaction type as required
emit(obj_type, TXNADD, obj_name, '-add')
emit(obj_type, TXNUPD, obj_name, '-update')
emit(obj_type, TXNDEL, obj_name, '-delete')
# Commit all delete transactions to the database
for (obj_type, trans_type), data in self.iteritems():
if trans_type == TXNDEL and obj_type in self.db_maps:
for handle, n_ in data:
assert handle == str(handle)
db_map(obj_type).delete(handle, txn=txn.txn)
# Add new reference keys as required
db_map = self.db.reference_map
if (REFERENCE_KEY, TXNADD) in self:
for handle, new_data in self[(REFERENCE_KEY, TXNADD)]:
assert handle == str(handle)
db_map.put(handle, new_data, txn=txn.txn)
# Delete old reference keys as required
if (REFERENCE_KEY, TXNDEL) in self:
for handle, none_ in self[(REFERENCE_KEY, TXNDEL)]:
assert handle == str(handle)
db_map.delete(handle, txn=txn.txn)
# Commit database transaction
txn.commit()
self.db.txn = None
self.clear()
return
# Define helper function to do the actual emits
def __emit(self,obj_type, trans_type, obj, suffix):
if (obj_type, trans_type) in self:
handles = [handle for handle, data in
self[(obj_type, trans_type)]]
if handles:
self.db.emit(obj + suffix, (handles, ))
# Test functions
def testtxn():
"""
Test suite
"""
class M(dict):
class FakeMap(dict):
"""Fake database map with just two methods"""
def put(self, key, data, txn=None):
super(M, self).__setitem__(key, data)
def delete(self, key, txn=None):
super(M, self).__delitem__(key)
def put(self, key, data):
"""Set a property"""
super(FakeMap, self).__setitem__(key, data)
def delete(self, key):
"""Delete a proptery"""
super(FakeMap, self).__delitem__(key)
class D:
class FakeDb:
"""Fake gramps database"""
def __init__(self):
self.person_map = M()
self.family_map = M()
self.source_map = M()
self.event_map = M()
self.media_map = M()
self.place_map = M()
self.note_map = M()
self.repository_map = M()
self.reference_map = M()
self.person_map = FakeMap()
self.family_map = FakeMap()
self.event_map = FakeMap()
self.reference_map = FakeMap()
self.readonly = False
self.env = None
self.undodb = FakeCommitDb()
def transaction_commit(self, transaction):
"""Commit the transaction to the undo database and cleanup."""
transaction.clear()
self.undodb.commit(transaction)
def emit(self, obj, value):
"""send signal"""
pass
class C(list):
class FakeCommitDb(list):
""" Fake commit database"""
pass
class G(DbTxn):
"""Derived transacton class"""
def get_db_txn(self, env):
return T()
class T():
"""Fake DBMS transaction class"""
def __init__(self):
self.txn = None
def begin(self):
return self
def commit(self):
def commit(self, transaction):
"""commit transaction to undo db"""
pass
def undo(self):
"""undo last transaction"""
pass
commitdb = C()
grampsdb = D()
trans = G("Test Transaction", commitdb, grampsdb)
grampsdb = FakeDb()
commitdb = grampsdb.undodb
trans = DbTxn("Test Transaction", commitdb, grampsdb, batch=False)
grampsdb.person_map.put('1', "data1")
trans.add(0, TXNADD, '1', None, "data1")
grampsdb.person_map.put('2', "data2")
trans.add(0, TXNADD, '2', None, "data2")
grampsdb.person_map.put('2', "data3")
trans.add(0, TXNUPD, '2', None, "data3")
grampsdb.person_map.delete('1')
trans.add(0, TXNDEL, '1', None, None)
print trans
@ -337,7 +239,6 @@ def testtxn():
print trans.get_record(i)
print list(trans.get_recnos())
print list(trans.get_recnos(reverse=True))
trans.commit("test")
print grampsdb.person_map
if __name__ == '__main__':

View File

@ -125,6 +125,16 @@ KEY_TO_CLASS_MAP = {PERSON_KEY: Person.__name__,
NOTE_KEY: Note.__name__,
TAG_KEY: Tag.__name__}
KEY_TO_NAME_MAP = {PERSON_KEY: 'person',
FAMILY_KEY: 'family',
EVENT_KEY: 'event',
SOURCE_KEY: 'source',
PLACE_KEY: 'place',
MEDIA_KEY: 'media',
REPOSITORY_KEY: 'repository',
#REFERENCE_KEY: 'reference',
NOTE_KEY: 'note',
TAG_KEY: 'tag'}
#-------------------------------------------------------------------------
#
# Helper functions
@ -795,27 +805,15 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
# Add references to the reference_map for all primary object referenced
# from the primary object 'obj' or any of its secondary objects.
handle = obj.handle
update = self.reference_map_primary_map.has_key(str(handle))
if update:
# First thing to do is get hold of all rows in the reference_map
# table that hold a reference from this primary obj. This means
# finding all the rows that have this handle somewhere in the
# list of (class_name, handle) pairs.
# The primary_map sec index allows us to look this up quickly.
existing_references = set()
primary_cur = self.get_reference_map_primary_cursor()
try:
ret = primary_cur.set(handle)
except:
ret = None
while (ret is not None):
(key, data) = ret
existing_references = set()
primary_cur = self.get_reference_map_primary_cursor()
try:
ret = primary_cur.set(handle)
except:
ret = None
while (ret is not None):
(key, data) = ret
# data values are of the form:
# ((primary_object_class_name, primary_object_handle),
# (referenced_object_class_name, referenced_object_handle))
@ -824,31 +822,20 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
# get_referenced_handles_recursively
# secondary DBs are not DBShelf's, so we need to do pickling
# and unpicking ourselves here
existing_reference = pickle.loads(data)[1]
existing_references.add(
(KEY_TO_CLASS_MAP[existing_reference[0]],
# and unpickling ourselves here
existing_reference = pickle.loads(data)[1]
existing_references.add((KEY_TO_CLASS_MAP[existing_reference[0]],
existing_reference[1]))
ret = primary_cur.next_dup()
ret = primary_cur.next_dup()
primary_cur.close()
primary_cur.close()
# Once we have the list of rows that already have a reference
# we need to compare it with the list of objects that are
# still references from the primary object.
current_references = set(obj.get_referenced_handles_recursively())
no_longer_required_references = existing_references.difference(
# Once we have the list of rows that already have a reference
# we need to compare it with the list of objects that are
# still references from the primary object.
current_references = set(obj.get_referenced_handles_recursively())
no_longer_required_references = existing_references.difference(
current_references)
new_references = current_references.difference(existing_references)
else:
# No existing refs are found:
# all we have is new, nothing to remove
no_longer_required_references = set()
new_references = set(obj.get_referenced_handles_recursively())
new_references = current_references.difference(existing_references)
# handle addition of new references
for (ref_class_name, ref_handle) in new_references:
@ -864,20 +851,19 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
# ignore missing old reference
pass
def __remove_reference(self, key, transaction, txn=None):
def __remove_reference(self, key, transaction, txn):
"""
Remove the reference specified by the key, preserving the change in
the passed transaction.
"""
if not self.readonly:
if transaction.batch:
self.reference_map.delete(str(key), txn=txn)
else:
old_data = self.reference_map.get(str(key), txn=self.txn)
if not transaction.batch:
old_data = self.reference_map.get(str(key), txn=txn)
transaction.add(REFERENCE_KEY, TXNDEL, str(key), old_data, None)
#transaction.reference_del.append(str(key))
self.reference_map.delete(str(key), txn=txn)
def __add_reference(self, key, data, transaction, txn=None):
def __add_reference(self, key, data, transaction, txn):
"""
Add the reference specified by the key and the data, preserving the
change in the passed transaction.
@ -886,9 +872,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if self.readonly or not key:
return
if transaction.batch:
self.reference_map.put(str(key), data, txn=txn)
else:
self.reference_map.put(str(key), data, txn=txn)
if not transaction.batch:
transaction.add(REFERENCE_KEY, TXNADD, str(key), None, data)
#transaction.reference_add.append((str(key), data))
@ -930,34 +915,34 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
# Make a tuple of the functions and classes that we need for
# each of the primary object tables.
transaction = self.transaction_begin(batch=True, no_magic=True)
callback(4)
with self.transaction_begin(_("Rebuild reference map"), batch=True,
no_magic=True) as transaction:
callback(4)
primary_table = (
(self.get_person_cursor, Person),
(self.get_family_cursor, Family),
(self.get_event_cursor, Event),
(self.get_place_cursor, Place),
(self.get_source_cursor, Source),
(self.get_media_cursor, MediaObject),
(self.get_repository_cursor, Repository),
(self.get_note_cursor, Note),
(self.get_tag_cursor, Tag),
)
primary_table = (
(self.get_person_cursor, Person),
(self.get_family_cursor, Family),
(self.get_event_cursor, Event),
(self.get_place_cursor, Place),
(self.get_source_cursor, Source),
(self.get_media_cursor, MediaObject),
(self.get_repository_cursor, Repository),
(self.get_note_cursor, Note),
(self.get_tag_cursor, Tag),
)
# Now we use the functions and classes defined above
# to loop through each of the primary object tables.
# Now we use the functions and classes defined above
# to loop through each of the primary object tables.
for cursor_func, class_func in primary_table:
with cursor_func() as cursor:
for found_handle, val in cursor:
obj = class_func()
obj.unserialize(val)
with BSDDBTxn(self.env) as txn:
self.update_reference_map(obj, transaction, txn.txn)
for cursor_func, class_func in primary_table:
with cursor_func() as cursor:
for found_handle, val in cursor:
obj = class_func()
obj.unserialize(val)
with BSDDBTxn(self.env) as txn:
self.update_reference_map(obj, transaction, txn.txn)
callback(5)
self.transaction_commit(transaction, _("Rebuild reference map"))
callback(5)
self.reference_map_referenced_map = self.__open_db(self.full_name,
REF_REF, db.DB_BTREE, db.DB_DUP|db.DB_DUPSORT)
@ -1239,8 +1224,10 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn=txn.txn)
txn.delete(handle)
else:
self.delete_primary_from_reference_map(handle, transaction)
self.delete_primary_from_reference_map(handle, transaction,
txn=self.txn)
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)
@ -1252,14 +1239,18 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if self.readonly or not handle:
return
self.delete_primary_from_reference_map(handle, transaction)
person = self.get_person_from_handle(handle)
self.genderStats.uncount_person (person)
self.remove_from_surname_list(person)
if transaction.batch:
with BSDDBTxn(self.env, self.person_map) as txn:
self.delete_primary_from_reference_map(handle, transaction,
txn=txn.txn)
txn.delete(handle)
else:
self.delete_primary_from_reference_map(handle, transaction,
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))
@ -1405,19 +1396,15 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
obj.change = int(change_time or time.time())
handle = str(obj.handle)
self.update_reference_map(obj, transaction)
self.update_reference_map(obj, transaction, self.txn)
# If this is a batch operation, just write the data
if transaction.batch:
data_map.put(handle, obj.serialize())
old_data = None
# Otherwise, this is a non-batch operation, so queue the transaction
else:
new_data = obj.serialize()
old_data = None
if not transaction.batch:
old_data = data_map.get(handle, txn=self.txn)
new_data = obj.serialize()
op = TXNUPD if old_data else TXNADD
transaction.add(key, op, handle, old_data, new_data)
data_map.put(handle, new_data, txn=self.txn)
return old_data
def commit_person(self, person, transaction, change_time=None):
@ -1639,7 +1626,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
transaction_commit function of the this database object.
"""
transaction = BdbTransaction(msg, self.undodb, self, batch, no_magic)
transaction = DbTxn(msg, self.undodb, self, batch)
transaction.no_magic = no_magic
if batch:
# A batch transaction does not store the commits
# Aborting the session completely will become impossible.
@ -1663,10 +1651,19 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
_db.remove(_mkname(self.full_name, REF_REF), REF_REF)
except db.DBNoSuchFileError:
pass
else:
self.bsddbtxn = BSDDBTxn(self.env)
self.txn = self.bsddbtxn.begin()
return transaction
@catch_db_error
def transaction_commit(self, transaction, msg):
def transaction_commit(self, transaction, msg=''):
"""
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()
if self._LOG_ALL:
_LOG.debug("%s: Transaction commit '%s'\n"
% (self.__class__.__name__, str(msg)))
@ -1674,12 +1671,60 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if self.readonly:
return
transaction.commit(msg)
if self.txn is not None:
assert transaction.get_description() != ''
self.bsddbtxn.commit()
self.bsddbtxn = None
self.txn = None
self.env.log_flush()
if not transaction.batch:
emit = self.__emit
for obj_type, obj_name in KEY_TO_NAME_MAP.iteritems():
emit(transaction, obj_type, TXNADD, obj_name, '-add')
emit(transaction, obj_type, TXNUPD, obj_name, '-update')
emit(transaction, obj_type, TXNDEL, obj_name, '-delete')
transaction.clear()
self.undodb.commit(transaction, msg)
self.__after_commit(transaction, msg)
self.__after_commit(transaction)
self.has_changed = True
def __after_commit(self, transaction, msg):
def __emit(self, transaction, obj_type, trans_type, obj, suffix):
"""
Define helper function to do the actual emits
"""
if (obj_type, trans_type) in transaction:
if trans_type == TXNDEL:
handles = [handle for handle, data in
transaction[(obj_type, trans_type)]]
else:
handles = [handle for handle, data in
transaction[(obj_type, trans_type)]
if (handle, None) not in transaction[(obj_type,
TXNDEL)]]
if handles:
self.emit(obj + suffix, (handles, ))
def transaction_abort(self, transaction):
"""
Revert the changes made to the database.
"""
if self._LOG_ALL:
_LOG.debug("%s: Transaction abort '%s'\n"
% (self.__class__.__name__, str(transaction.get_description())))
if self.readonly:
return
if self.txn is not None:
self.bsddbtxn.abort()
self.bsddbtxn = None
self.txn = None
transaction.clear()
transaction.first = None
transaction.last = None
self.__after_commit(transaction)
def __after_commit(self, transaction):
"""
Post-transaction commit processing
"""
@ -1800,34 +1845,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return self.brief_name
#-------------------------------------------------------------------------
#
# BdbTransaction
#
#-------------------------------------------------------------------------
class BdbTransaction(DbTxn):
"""
The batch parameter is set to True for large transactions. For such
transactions, the list of changes is not maintained, and no undo
is possible.
The no_magic parameter is ignored for non-batch transactions, and
is also of no importance for DB backends other than BSD DB. For
the BSDDB, when this paramter is set to True, some secondary
indices will be removed at the beginning and then rebuilt at
the end of such transaction (only if it is batch).
"""
__slots__ = ('batch', 'no_magic')
def __init__(self, msg, undodb, grampsdb, batch=False, no_magic=False):
DbTxn.__init__(self, msg, undodb, grampsdb)
self.batch = batch
self.no_magic = no_magic
def get_db_txn(self, value):
return BSDDBTxn(value)
def _mkname(path, name):
return os.path.join(path, name + DBEXT)

View File

@ -476,14 +476,13 @@ class GalleryTab(ButtonTab, DbGUIElement):
basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename)
photo.set_description(root)
trans = self.dbstate.db.transaction_begin()
self.dbstate.db.add_object(photo, trans)
oref = gen.lib.MediaRef()
oref.set_reference_handle(photo.get_handle())
self.get_data().append(oref)
self.changed = True
self.dbstate.db.transaction_commit(trans,
_("Drag Media Object"))
with self.dbstate.db.transaction_begin(
_("Drag Media Object")) as trans:
self.dbstate.db.add_object(photo, trans)
oref = gen.lib.MediaRef()
oref.set_reference_handle(photo.get_handle())
self.get_data().append(oref)
self.changed = True
self.rebuild()
def handle_extra_type(self, objtype, obj):

View File

@ -253,19 +253,17 @@ class EditEvent(EditPrimary):
return
if not self.obj.handle:
trans = self.db.transaction_begin()
self.db.add_event(self.obj, trans)
self.db.transaction_commit(trans,
_("Add Event (%s)") % self.obj.get_gramps_id())
with self.db.transaction_begin(_("Add Event (%s)") %
self.obj.get_gramps_id()) 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()):
trans = self.db.transaction_begin()
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)
self.db.transaction_commit(trans,
_("Edit Event (%s)") % self.obj.get_gramps_id())
with self.db.transaction_begin(_("Edit Event (%s)") %
self.obj.get_gramps_id()) 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)
if self.callback:
self.callback(self.obj)
@ -333,22 +331,21 @@ class DeleteEventQuery(object):
self.family_list = family_list
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
with self.db.transaction_begin(_("Delete Event (%s)") %
self.event.get_gramps_id()) as trans:
self.db.disable_signals()
ev_handle_list = [self.event.get_handle()]
ev_handle_list = [self.event.get_handle()]
for handle in self.person_list:
person = self.db.get_person_from_handle(handle)
person.remove_handle_references('Event', ev_handle_list)
self.db.commit_person(person, trans)
for handle in self.person_list:
person = self.db.get_person_from_handle(handle)
person.remove_handle_references('Event', ev_handle_list)
self.db.commit_person(person, trans)
for handle in self.family_list:
family = self.db.get_family_from_handle(handle)
family.remove_handle_references('Event', ev_handle_list)
self.db.commit_family(family, trans)
for handle in self.family_list:
family = self.db.get_family_from_handle(handle)
family.remove_handle_references('Event', ev_handle_list)
self.db.commit_family(family, trans)
self.db.enable_signals()
self.db.remove_event(self.event.get_handle(), trans)
self.db.transaction_commit(trans,
_("Delete Event (%s)") % self.event.get_gramps_id())
self.db.enable_signals()
self.db.remove_event(self.event.get_handle(), trans)

View File

@ -236,13 +236,12 @@ class EditEventRef(EditReference):
def ok_clicked(self, obj):
trans = self.db.transaction_begin()
if self.source.handle:
self.commit_event(self.source,trans)
self.db.transaction_commit(trans,_("Modify Event"))
with self.db.transaction_begin(_("Modify Event")) as trans:
self.commit_event(self.source,trans)
else:
self.add_event(self.source,trans)
self.db.transaction_commit(trans,_("Add Event"))
with self.db.transaction_begin(_("Add Event")) as trans:
self.add_event(self.source,trans)
self.source_ref.ref = self.source.handle
if self.update:

View File

@ -1060,62 +1060,61 @@ class EditFamily(EditPrimary):
self._cleanup_callbacks()
if not original and not self.object_is_empty():
trans = self.db.transaction_begin()
with self.db.transaction_begin(_("Add Family")) as trans:
# find the father, add the family handle to the father
handle = self.obj.get_father_handle()
if handle:
parent = self.db.get_person_from_handle(handle)
parent.add_family_handle(self.obj.handle)
self.db.commit_person(parent, trans)
# find the father, add the family handle to the father
handle = self.obj.get_father_handle()
if handle:
parent = self.db.get_person_from_handle(handle)
parent.add_family_handle(self.obj.handle)
self.db.commit_person(parent, trans)
# find the mother, add the family handle to the mother
handle = self.obj.get_mother_handle()
if handle:
parent = self.db.get_person_from_handle(handle)
parent.add_family_handle(self.obj.handle)
self.db.commit_person(parent, trans)
# find the mother, add the family handle to the mother
handle = self.obj.get_mother_handle()
if handle:
parent = self.db.get_person_from_handle(handle)
parent.add_family_handle(self.obj.handle)
self.db.commit_person(parent, trans)
# for each child, add the family handle to the child
for ref in self.obj.get_child_ref_list():
child = self.db.get_person_from_handle(ref.ref)
# fix - relationships need to be extracted from the list
child.add_parent_family_handle(self.obj.handle)
self.db.commit_person(child, trans)
# for each child, add the family handle to the child
for ref in self.obj.get_child_ref_list():
child = self.db.get_person_from_handle(ref.ref)
# fix - relationships need to be extracted from the list
child.add_parent_family_handle(self.obj.handle)
self.db.commit_person(child, trans)
self.db.add_family(self.obj, trans)
self.db.transaction_commit(trans, _("Add Family"))
self.db.add_family(self.obj, trans)
elif cmp(original.serialize(),self.obj.serialize()):
trans = self.db.transaction_begin()
with self.db.transaction_begin(_("Edit Family")) as trans:
self.fix_parent_handles(original.get_father_handle(),
self.obj.get_father_handle(), trans)
self.fix_parent_handles(original.get_mother_handle(),
self.obj.get_mother_handle(), trans)
self.fix_parent_handles(original.get_father_handle(),
self.obj.get_father_handle(), trans)
self.fix_parent_handles(original.get_mother_handle(),
self.obj.get_mother_handle(), trans)
orig_set = set(original.get_child_ref_list())
new_set = set(self.obj.get_child_ref_list())
orig_set = set(original.get_child_ref_list())
new_set = set(self.obj.get_child_ref_list())
# remove the family from children which have been removed
for ref in orig_set.difference(new_set):
person = self.db.get_person_from_handle(ref.ref)
person.remove_parent_family_handle(self.obj.handle)
self.db.commit_person(person, trans)
# remove the family from children which have been removed
for ref in orig_set.difference(new_set):
person = self.db.get_person_from_handle(ref.ref)
person.remove_parent_family_handle(self.obj.handle)
self.db.commit_person(person, trans)
# add the family to children which have been added
for ref in new_set.difference(orig_set):
person = self.db.get_person_from_handle(ref.ref)
person.add_parent_family_handle(self.obj.handle)
self.db.commit_person(person, trans)
# add the family to children which have been added
for ref in new_set.difference(orig_set):
person = self.db.get_person_from_handle(ref.ref)
person.add_parent_family_handle(self.obj.handle)
self.db.commit_person(person, trans)
if self.object_is_empty():
self.db.remove_family(self.obj.handle, trans)
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_family_gramps_id())
self.db.commit_family(self.obj, trans)
self.db.transaction_commit(trans, _("Edit Family"))
if self.object_is_empty():
self.db.remove_family(self.obj.handle, trans)
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(
self.db.find_next_family_gramps_id())
self.db.commit_family(self.obj, trans)
self._do_close()

View File

@ -288,18 +288,17 @@ class EditMedia(EditPrimary):
self.obj.set_path(Utils.get_unicode_path_from_file_chooser(path))
trans = self.db.transaction_begin()
if not self.obj.get_handle():
self.db.add_object(self.obj, trans)
msg = _("Add Media Object (%s)") % self.obj.get_description()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_object_gramps_id())
self.db.commit_media_object(self.obj, trans)
msg = _("Edit Media Object (%s)") % self.obj.get_description()
self.db.transaction_commit(trans, msg)
with self.db.transaction_begin() as trans:
if not self.obj.get_handle():
self.db.add_object(self.obj, trans)
msg = _("Add Media Object (%s)") % self.obj.get_description()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_object_gramps_id())
self.db.commit_media_object(self.obj, trans)
msg = _("Edit Media Object (%s)") % self.obj.get_description()
trans.set_description(msg)
if self.callback:
self.callback(self.obj)
self.close()
@ -336,47 +335,46 @@ class DeleteMediaQuery(object):
self.the_lists = the_lists
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
with self.db.transaction_begin(_("Remove Media Object")) as trans:
self.db.disable_signals()
(person_list, family_list, event_list,
place_list,source_list) = self.the_lists
(person_list, family_list, event_list,
place_list, source_list) = self.the_lists
for handle in person_list:
person = self.db.get_person_from_handle(handle)
new_list = [photo for photo in person.get_media_list()
if photo.get_reference_handle() != self.media_handle]
person.set_media_list(new_list)
self.db.commit_person(person, trans)
for handle in person_list:
person = self.db.get_person_from_handle(handle)
new_list = [photo for photo in person.get_media_list()
if photo.get_reference_handle() != self.media_handle]
person.set_media_list(new_list)
self.db.commit_person(person, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
new_list = [photo for photo in family.get_media_list()
if photo.get_reference_handle() != self.media_handle]
family.set_media_list(new_list)
self.db.commit_family(family, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
new_list = [photo for photo in family.get_media_list()
if photo.get_reference_handle() != self.media_handle]
family.set_media_list(new_list)
self.db.commit_family(family, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
new_list = [photo for photo in event.get_media_list()
if photo.get_reference_handle() != self.media_handle]
event.set_media_list(new_list)
self.db.commit_event(event, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
new_list = [photo for photo in event.get_media_list()
if photo.get_reference_handle() != self.media_handle]
event.set_media_list(new_list)
self.db.commit_event(event, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
new_list = [photo for photo in place.get_media_list()
if photo.get_reference_handle() != self.media_handle]
place.set_media_list(new_list)
self.db.commit_place(place, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
new_list = [photo for photo in place.get_media_list()
if photo.get_reference_handle() != self.media_handle]
place.set_media_list(new_list)
self.db.commit_place(place, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
new_list = [photo for photo in source.get_media_list()
if photo.get_reference_handle() != self.media_handle]
source.set_media_list(new_list)
self.db.commit_source(source, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
new_list = [photo for photo in source.get_media_list()
if photo.get_reference_handle() != self.media_handle]
source.set_media_list(new_list)
self.db.commit_source(source, trans)
self.db.enable_signals()
self.db.remove_object(self.media_handle, trans)
self.db.transaction_commit(trans, _("Remove Media Object"))
self.db.enable_signals()
self.db.remove_object(self.media_handle, trans)

View File

@ -586,15 +586,14 @@ class EditMediaRef(EditReference):
def save(self,*obj):
#first save primary object
trans = self.db.transaction_begin()
if self.source.handle:
self.db.commit_media_object(self.source, trans)
self.db.transaction_commit(trans, _("Edit Media Object (%s)"
) % self.source.get_description())
with self.db.transaction_begin(_("Edit Media Object (%s)"
) % self.source.get_description()) as trans:
self.db.commit_media_object(self.source, trans)
else:
self.db.add_object(self.source, trans)
self.db.transaction_commit(trans,_("Add Media Object (%s)"
) % self.source.get_description())
with self.db.transaction_begin(_("Add Media Object (%s)"
) % self.source.get_description()) as trans:
self.db.add_object(self.source, trans)
#save reference object in memory
coord = (

View File

@ -317,19 +317,17 @@ class EditNote(EditPrimary):
self.ok_button.set_sensitive(True)
return
trans = self.db.transaction_begin()
if not self.obj.get_handle():
self.db.add_note(self.obj, trans)
msg = _("Add Note")
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_note_gramps_id())
self.db.commit_note(self.obj, trans)
msg = _("Edit Note")
with self.db.transaction_begin() as trans:
if not self.obj.get_handle():
self.db.add_note(self.obj, trans)
msg = _("Add Note")
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_note_gramps_id())
self.db.commit_note(self.obj, trans)
msg = _("Edit Note")
trans.set_description(msg)
self.db.transaction_commit(trans, msg)
if self.callback:
self.callback(self.obj.get_handle())
self.close()
@ -342,50 +340,49 @@ class DeleteNoteQuery(object):
self.the_lists = the_lists
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
with self.db.transaction_begin(_("Delete Note (%s)") %
self.note.get_gramps_id()) as trans:
self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists
note_handle = self.note.get_handle()
note_handle = self.note.get_handle()
for handle in person_list:
person = self.db.get_person_from_handle(handle)
person.remove_note(note_handle)
self.db.commit_person(person, trans)
for handle in person_list:
person = self.db.get_person_from_handle(handle)
person.remove_note(note_handle)
self.db.commit_person(person, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
family.remove_note(note_handle)
self.db.commit_family(family, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
family.remove_note(note_handle)
self.db.commit_family(family, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
event.remove_note(note_handle)
self.db.commit_event(event, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
event.remove_note(note_handle)
self.db.commit_event(event, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
place.remove_note(note_handle)
self.db.commit_place(place, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
place.remove_note(note_handle)
self.db.commit_place(place, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
source.remove_note(note_handle)
self.db.commit_source(source, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
source.remove_note(note_handle)
self.db.commit_source(source, trans)
for handle in media_list:
media = self.db.get_object_from_handle(handle)
media.remove_note(note_handle)
self.db.commit_media_object(media, trans)
for handle in media_list:
media = self.db.get_object_from_handle(handle)
media.remove_note(note_handle)
self.db.commit_media_object(media, trans)
for handle in repo_list:
repo = self.db.get_repository_from_handle(handle)
repo.remove_note(note_handle)
self.db.commit_repository(repo, trans)
for handle in repo_list:
repo = self.db.get_repository_from_handle(handle)
repo.remove_note(note_handle)
self.db.commit_repository(repo, trans)
self.db.enable_signals()
self.db.remove_note(note_handle, trans)
self.db.transaction_commit(
trans,_("Delete Note (%s)") % self.note.get_gramps_id())
self.db.enable_signals()
self.db.remove_note(note_handle, trans)

View File

@ -868,21 +868,20 @@ class EditPerson(EditPrimary):
self.db.set_birth_death_index(self.obj)
trans = self.db.transaction_begin()
with self.db.transaction_begin() as trans:
self._update_family_ids()
if not self.obj.get_handle():
self.db.add_person(self.obj, trans)
msg = _("Add Person (%s)") % \
self.name_displayer.display(self.obj)
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_person_gramps_id())
self.db.commit_person(self.obj, trans)
msg = _("Edit Person (%s)") % \
self.name_displayer.display(self.obj)
trans.set_description(msg)
self._update_family_ids()
if not self.obj.get_handle():
self.db.add_person(self.obj, trans)
msg = _("Add Person (%s)") % self.name_displayer.display(self.obj)
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_person_gramps_id())
self.db.commit_person(self.obj, trans)
msg = _("Edit Person (%s)") % self.name_displayer.display(self.obj)
self.db.transaction_commit(trans, msg)
self.close()
if self.callback:
self.callback(self.obj)

View File

@ -306,16 +306,16 @@ class EditPlace(EditPrimary):
self.ok_button.set_sensitive(True)
return
trans = self.db.transaction_begin()
if not self.obj.get_handle():
self.db.add_place(self.obj, trans)
msg = _("Add Place (%s)") % self.obj.get_title()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_place_gramps_id())
self.db.commit_place(self.obj, trans)
msg = _("Edit Place (%s)") % self.obj.get_title()
self.db.transaction_commit(trans, msg)
with self.db.transaction_begin() as trans:
if not self.obj.get_handle():
self.db.add_place(self.obj, trans)
msg = _("Add Place (%s)") % self.obj.get_title()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_place_gramps_id())
self.db.commit_place(self.obj, trans)
msg = _("Edit Place (%s)") % self.obj.get_title()
trans.set_description(msg)
self.close()
if self.callback:
@ -338,27 +338,26 @@ class DeletePlaceQuery(object):
self.event_list = event_list
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
with self.db.transaction_begin(_("Delete Place (%s)") %
self.obj.get_title()) as trans:
self.db.disable_signals()
place_handle = self.obj.get_handle()
place_handle = self.obj.get_handle()
for handle in self.person_list:
person = self.db.get_person_from_handle(handle)
person.remove_handle_references('Place', place_handle)
self.db.commit_person(person, trans)
for handle in self.person_list:
person = self.db.get_person_from_handle(handle)
person.remove_handle_references('Place', place_handle)
self.db.commit_person(person, trans)
for handle in self.family_list:
family = self.db.get_family_from_handle(handle)
family.remove_handle_references('Place', place_handle)
self.db.commit_family(family, trans)
for handle in self.family_list:
family = self.db.get_family_from_handle(handle)
family.remove_handle_references('Place', place_handle)
self.db.commit_family(family, trans)
for handle in self.event_list:
event = self.db.get_event_from_handle(handle)
event.remove_handle_references('Place', place_handle)
self.db.commit_event(event, trans)
for handle in self.event_list:
event = self.db.get_event_from_handle(handle)
event.remove_handle_references('Place', place_handle)
self.db.commit_event(event, trans)
self.db.enable_signals()
self.db.remove_place(place_handle, trans)
self.db.transaction_commit(
trans,_("Delete Place (%s)") % self.obj.get_title())
self.db.enable_signals()
self.db.remove_place(place_handle, trans)

View File

@ -189,13 +189,12 @@ class EditRepoRef(EditReference):
def ok_clicked(self, obj):
trans = self.db.transaction_begin()
if self.source.handle:
self.db.commit_repository(self.source,trans)
self.db.transaction_commit(trans,_("Modify Repository"))
with self.db.transaction_begin(_("Modify Repository")) as trans:
self.db.commit_repository(self.source,trans)
else:
self.db.add_repository(self.source,trans)
self.db.transaction_commit(trans,_("Add Repository"))
with self.db.transaction_begin(_("Add Repository")) as trans:
self.db.add_repository(self.source,trans)
self.source_ref.ref = self.source.handle
if self.update:

View File

@ -177,17 +177,17 @@ class EditRepository(EditPrimary):
self.ok_button.set_sensitive(True)
return
trans = self.db.transaction_begin()
if not self.obj.get_handle():
self.db.add_repository(self.obj, trans)
msg = _("Add Repository (%s)") % self.obj.get_name()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_repository_gramps_id())
self.db.commit_repository(self.obj, trans)
msg = _("Edit Repository (%s)") % self.obj.get_name()
with self.db.transaction_begin() as trans:
if not self.obj.get_handle():
self.db.add_repository(self.obj, trans)
msg = _("Add Repository (%s)") % self.obj.get_name()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_repository_gramps_id())
self.db.commit_repository(self.obj, trans)
msg = _("Edit Repository (%s)") % self.obj.get_name()
trans.set_description(msg)
self.db.transaction_commit(trans, msg)
self.close()
class DeleteRepositoryQuery(object):
@ -198,15 +198,14 @@ class DeleteRepositoryQuery(object):
self.sources = sources
def query_response(self):
trans = self.db.transaction_begin()
with self.db.transaction_begin(_("Delete Repository (%s)") %
self.obj.get_name()) as trans:
repos_handle_list = [self.obj.get_handle()]
repos_handle_list = [self.obj.get_handle()]
for handle in self.sources:
source = self.db.get_source_from_handle(handle)
source.remove_repo_references(repos_handle_list)
self.db.commit_source(source, trans)
for handle in self.sources:
source = self.db.get_source_from_handle(handle)
source.remove_repo_references(repos_handle_list)
self.db.commit_source(source, trans)
self.db.remove_repository(self.obj.get_handle(), trans)
self.db.transaction_commit(
trans, _("Delete Repository (%s)") % self.obj.get_name())
self.db.remove_repository(self.obj.get_handle(), trans)

View File

@ -195,17 +195,17 @@ class EditSource(EditPrimary):
self.ok_button.set_sensitive(True)
return
trans = self.db.transaction_begin()
if not self.obj.get_handle():
self.db.add_source(self.obj, trans)
msg = _("Add Source (%s)") % self.obj.get_title()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_source_gramps_id())
self.db.commit_source(self.obj, trans)
msg = _("Edit Source (%s)") % self.obj.get_title()
with self.db.transaction_begin() as trans:
if not self.obj.get_handle():
self.db.add_source(self.obj, trans)
msg = _("Add Source (%s)") % self.obj.get_title()
else:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_source_gramps_id())
self.db.commit_source(self.obj, trans)
msg = _("Edit Source (%s)") % self.obj.get_title()
trans.set_description(msg)
self.db.transaction_commit(trans, msg)
self.close()
class DeleteSrcQuery(object):
@ -216,50 +216,49 @@ class DeleteSrcQuery(object):
self.the_lists = the_lists
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
with self.db.transaction_begin(_("Delete Source (%s)") %
self.source.get_title()) as trans:
self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists
src_handle_list = [self.source.get_handle()]
src_handle_list = [self.source.get_handle()]
for handle in person_list:
person = self.db.get_person_from_handle(handle)
person.remove_source_references(src_handle_list)
self.db.commit_person(person, trans)
for handle in person_list:
person = self.db.get_person_from_handle(handle)
person.remove_source_references(src_handle_list)
self.db.commit_person(person, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
family.remove_source_references(src_handle_list)
self.db.commit_family(family, trans)
for handle in family_list:
family = self.db.get_family_from_handle(handle)
family.remove_source_references(src_handle_list)
self.db.commit_family(family, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
event.remove_source_references(src_handle_list)
self.db.commit_event(event, trans)
for handle in event_list:
event = self.db.get_event_from_handle(handle)
event.remove_source_references(src_handle_list)
self.db.commit_event(event, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
place.remove_source_references(src_handle_list)
self.db.commit_place(place, trans)
for handle in place_list:
place = self.db.get_place_from_handle(handle)
place.remove_source_references(src_handle_list)
self.db.commit_place(place, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
source.remove_source_references(src_handle_list)
self.db.commit_source(source, trans)
for handle in source_list:
source = self.db.get_source_from_handle(handle)
source.remove_source_references(src_handle_list)
self.db.commit_source(source, trans)
for handle in media_list:
media = self.db.get_object_from_handle(handle)
media.remove_source_references(src_handle_list)
self.db.commit_media_object(media, trans)
for handle in media_list:
media = self.db.get_object_from_handle(handle)
media.remove_source_references(src_handle_list)
self.db.commit_media_object(media, trans)
for handle in repo_list:
repo = self.db.get_repository_from_handle(handle)
repo.remove_source_references(src_handle_list)
self.db.commit_repository(repo, trans)
for handle in repo_list:
repo = self.db.get_repository_from_handle(handle)
repo.remove_source_references(src_handle_list)
self.db.commit_repository(repo, trans)
self.db.enable_signals()
self.db.remove_source(self.source.get_handle(), trans)
self.db.transaction_commit(
trans, _("Delete Source (%s)") % self.source.get_title())
self.db.enable_signals()
self.db.remove_source(self.source.get_handle(), trans)

View File

@ -205,13 +205,12 @@ class EditSourceRef(EditReference):
def ok_clicked(self, obj):
trans = self.db.transaction_begin()
if self.source.handle:
self.db.commit_source(self.source,trans)
self.db.transaction_commit(trans,_("Modify Source"))
with self.db.transaction_begin(_("Modify Source")) as trans:
self.db.commit_source(self.source,trans)
else:
self.db.add_source(self.source,trans)
self.db.transaction_commit(trans,_("Add Source"))
with self.db.transaction_begin(_("Add Source")) as trans:
self.db.add_source(self.source,trans)
if self.update:
self.update(self.source_ref,self.source)

View File

@ -438,88 +438,166 @@ class CSVParser(object):
progress.set_pass(_('Reading data...'), 1)
data = self.readCSV()
progress.set_pass(_('Importing data...'), len(data))
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
t = time.time()
self.lineno = 0
self.index = 0
self.fam_count = 0
self.indi_count = 0
self.pref = {} # person ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
header = None
line_number = 0
for row in data:
progress.step()
line_number += 1
if "".join(row) == "": # no blanks are allowed inside a table
header = None # clear headers, ready for next "table"
continue
######################################
if header is None:
header = [cleanup_column_name(r) for r in row]
col = {}
count = 0
for key in header:
col[key] = count
count += 1
continue
# three different kinds of data: person, family, and marriage
if (("marriage" in header) or
("husband" in header) or
("wife" in header)):
# marriage, husband, wife
marriage_ref = rd(line_number, row, col, "marriage")
husband = rd(line_number, row, col, "husband")
wife = rd(line_number, row, col, "wife")
marriagedate = rd(line_number, row, col, "date")
marriageplace = rd(line_number, row, col, "place")
marriagesource = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
wife = self.lookup("person", wife)
husband = self.lookup("person", husband)
if husband is None and wife is None:
# might have children, so go ahead and add
LOG.warn("no parents on line %d; adding family anyway" % line_number)
family = self.get_or_create_family(marriage_ref, husband, wife)
# adjust gender, if not already provided
if husband:
# this is just a guess, if unknown
if husband.get_gender() == gen.lib.Person.UNKNOWN:
husband.set_gender(gen.lib.Person.MALE)
self.db.commit_person(husband, self.trans)
if wife:
# this is just a guess, if unknown
if wife.get_gender() == gen.lib.Person.UNKNOWN:
wife.set_gender(gen.lib.Person.FEMALE)
self.db.commit_person(wife, self.trans)
if marriage_ref:
self.storeup("family", marriage_ref.lower(), family)
if marriagesource:
# add, if new
new, marriagesource = self.get_or_create_source(marriagesource)
if marriageplace:
# add, if new
new, marriageplace = self.get_or_create_place(marriageplace)
if marriagedate:
marriagedate = _dp.parse(marriagedate)
if marriagedate or marriageplace or marriagesource or note:
# add, if new; replace, if different
new, marriage = self.get_or_create_event(family, gen.lib.EventType.MARRIAGE,
marriagedate, marriageplace, marriagesource)
if new:
mar_ref = gen.lib.EventRef()
mar_ref.set_reference_handle(marriage.get_handle())
family.add_event_ref(mar_ref)
with self.db.transaction_begin(_("CSV import"), batch=True
) as self.trans:
self.db.disable_signals()
t = time.time()
self.lineno = 0
self.index = 0
self.fam_count = 0
self.indi_count = 0
self.pref = {} # person ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
header = None
line_number = 0
for row in data:
progress.step()
line_number += 1
if "".join(row) == "": # no blanks are allowed inside a table
header = None # clear headers, ready for next "table"
continue
######################################
if header is None:
header = [cleanup_column_name(r) for r in row]
col = {}
count = 0
for key in header:
col[key] = count
count += 1
continue
# three different kinds of data: person, family, and marriage
if (("marriage" in header) or
("husband" in header) or
("wife" in header)):
# marriage, husband, wife
marriage_ref = rd(line_number, row, col, "marriage")
husband = rd(line_number, row, col, "husband")
wife = rd(line_number, row, col, "wife")
marriagedate = rd(line_number, row, col, "date")
marriageplace = rd(line_number, row, col, "place")
marriagesource = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
wife = self.lookup("person", wife)
husband = self.lookup("person", husband)
if husband is None and wife is None:
# might have children, so go ahead and add
LOG.warn("no parents on line %d; adding family anyway" % line_number)
family = self.get_or_create_family(marriage_ref, husband, wife)
# adjust gender, if not already provided
if husband:
# this is just a guess, if unknown
if husband.get_gender() == gen.lib.Person.UNKNOWN:
husband.set_gender(gen.lib.Person.MALE)
self.db.commit_person(husband, self.trans)
if wife:
# this is just a guess, if unknown
if wife.get_gender() == gen.lib.Person.UNKNOWN:
wife.set_gender(gen.lib.Person.FEMALE)
self.db.commit_person(wife, self.trans)
if marriage_ref:
self.storeup("family", marriage_ref.lower(), family)
if marriagesource:
# add, if new
new, marriagesource = self.get_or_create_source(marriagesource)
if marriageplace:
# add, if new
new, marriageplace = self.get_or_create_place(marriageplace)
if marriagedate:
marriagedate = _dp.parse(marriagedate)
if marriagedate or marriageplace or marriagesource or note:
# add, if new; replace, if different
new, marriage = self.get_or_create_event(family, gen.lib.EventType.MARRIAGE,
marriagedate, marriageplace, marriagesource)
if new:
mar_ref = gen.lib.EventRef()
mar_ref.set_reference_handle(marriage.get_handle())
family.add_event_ref(mar_ref)
self.db.commit_family(family, self.trans)
# only add note to event:
# append notes, if previous notes
if note:
previous_notes_list = marriage.get_note_list()
updated_note = False
for note_handle in previous_notes_list:
previous_note = self.db.get_note_from_handle(note_handle)
if previous_note.type == gen.lib.NoteType.EVENT:
previous_text = previous_note.get()
if note not in previous_text:
note = previous_text + "\n" + note
previous_note.set(note)
self.db.commit_note(previous_note, self.trans)
updated_note = True
break
if not updated_note:
# add new note here
new_note = gen.lib.Note()
new_note.handle = create_id()
new_note.type.set(gen.lib.NoteType.EVENT)
new_note.set(note)
self.db.add_note(new_note, self.trans)
marriage.add_note(new_note.handle)
self.db.commit_event(marriage, self.trans)
elif "family" in header:
# family, child
family_ref = rd(line_number, row, col, "family")
if family_ref is None:
LOG.warn("no family reference found for family on line %d" % line_number)
continue # required
child = rd(line_number, row, col, "child")
source = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
gender = rd(line_number, row, col, "gender")
child = self.lookup("person", child)
family = self.lookup("family", family_ref)
if family is None:
LOG.warn("no matching family reference found for family on line %d" % line_number)
continue
if child is None:
LOG.warn("no matching child reference found for family on line %d" % line_number)
continue
# is this child already in this family? If so, don't add
LOG.debug("children: %s", [ref.ref for ref in family.get_child_ref_list()])
LOG.debug("looking for: %s", child.get_handle())
if child.get_handle() not in [ref.ref for ref in family.get_child_ref_list()]:
# add child to family
LOG.debug(" adding child [%s] to family [%s]", child.get_gramps_id(),
family.get_gramps_id())
childref = gen.lib.ChildRef()
childref.set_reference_handle(child.get_handle())
family.add_child_ref( childref)
self.db.commit_family(family, self.trans)
# only add note to event:
# append notes, if previous notes
child.add_parent_family_handle(family.get_handle())
if gender:
# replace
gender = gender.lower()
if gender == gender_map[gen.lib.Person.MALE].lower():
gender = gen.lib.Person.MALE
elif gender == gender_map[gen.lib.Person.FEMALE].lower():
gender = gen.lib.Person.FEMALE
else:
gender = gen.lib.Person.UNKNOWN
child.set_gender(gender)
if source:
# add, if new
new, source = self.get_or_create_source(source)
source_refs = child.get_source_references()
found = 0
for ref in source_refs:
LOG.debug("child: %s looking for ref: %s", ref.ref, source.get_handle())
if ref.ref == source.get_handle():
found = 1
if not found:
sref = gen.lib.SourceRef()
sref.set_reference_handle(source.get_handle())
child.add_source_reference(sref)
# put note on child
if note:
previous_notes_list = marriage.get_note_list()
# append notes, if previous notes
previous_notes_list = child.get_note_list()
updated_note = False
for note_handle in previous_notes_list:
previous_note = self.db.get_note_from_handle(note_handle)
if previous_note.type == gen.lib.NoteType.EVENT:
if previous_note.type == gen.lib.NoteType.PERSON:
previous_text = previous_note.get()
if note not in previous_text:
note = previous_text + "\n" + note
@ -531,276 +609,199 @@ class CSVParser(object):
# add new note here
new_note = gen.lib.Note()
new_note.handle = create_id()
new_note.type.set(gen.lib.NoteType.EVENT)
new_note.type.set(gen.lib.NoteType.PERSON)
new_note.set(note)
self.db.add_note(new_note, self.trans)
marriage.add_note(new_note.handle)
self.db.commit_event(marriage, self.trans)
elif "family" in header:
# family, child
family_ref = rd(line_number, row, col, "family")
if family_ref is None:
LOG.warn("no family reference found for family on line %d" % line_number)
continue # required
child = rd(line_number, row, col, "child")
source = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
gender = rd(line_number, row, col, "gender")
child = self.lookup("person", child)
family = self.lookup("family", family_ref)
if family is None:
LOG.warn("no matching family reference found for family on line %d" % line_number)
continue
if child is None:
LOG.warn("no matching child reference found for family on line %d" % line_number)
continue
# is this child already in this family? If so, don't add
LOG.debug("children: %s", [ref.ref for ref in family.get_child_ref_list()])
LOG.debug("looking for: %s", child.get_handle())
if child.get_handle() not in [ref.ref for ref in family.get_child_ref_list()]:
# add child to family
LOG.debug(" adding child [%s] to family [%s]", child.get_gramps_id(),
family.get_gramps_id())
childref = gen.lib.ChildRef()
childref.set_reference_handle(child.get_handle())
family.add_child_ref( childref)
self.db.commit_family(family, self.trans)
child.add_parent_family_handle(family.get_handle())
if gender:
child.add_note(new_note.handle)
self.db.commit_person(child, self.trans)
elif "surname" in header: # person data
# surname, and any of the following
surname = rd(line_number, row, col, "surname")
firstname = rd(line_number, row, col, "firstname", "")
callname = rd(line_number, row, col, "callname")
title = rd(line_number, row, col, "title")
prefix = rd(line_number, row, col, "prefix")
suffix = rd(line_number, row, col, "suffix")
gender = rd(line_number, row, col, "gender")
source = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
birthplace = rd(line_number, row, col, "birthplace")
birthdate = rd(line_number, row, col, "birthdate")
birthsource = rd(line_number, row, col, "birthsource")
baptismplace = rd(line_number, row, col, "baptismplace")
baptismdate = rd(line_number, row, col, "baptismdate")
baptismsource = rd(line_number, row, col, "baptismsource")
burialplace = rd(line_number, row, col, "burialplace")
burialdate = rd(line_number, row, col, "burialdate")
burialsource = rd(line_number, row, col, "burialsource")
deathplace = rd(line_number, row, col, "deathplace")
deathdate = rd(line_number, row, col, "deathdate")
deathsource = rd(line_number, row, col, "deathsource")
deathcause = rd(line_number, row, col, "deathcause")
grampsid = rd(line_number, row, col, "grampsid")
person_ref = rd(line_number, row, col, "person")
#########################################################
# if this person already exists, don't create them
person = self.lookup("person", person_ref)
if person is None:
if surname is None:
LOG.warn("empty surname for new person on line %d" % line_number)
surname = ""
# new person
person = self.create_person()
name = gen.lib.Name()
name.set_type(gen.lib.NameType(gen.lib.NameType.BIRTH))
name.set_first_name(firstname)
surname_obj = gen.lib.Surname()
surname_obj.set_surname(surname)
name.add_surname(surname_obj)
person.set_primary_name(name)
else:
name = person.get_primary_name()
#########################################################
if person_ref is not None:
self.storeup("person", person_ref, person)
# replace
gender = gender.lower()
if gender == gender_map[gen.lib.Person.MALE].lower():
gender = gen.lib.Person.MALE
elif gender == gender_map[gen.lib.Person.FEMALE].lower():
gender = gen.lib.Person.FEMALE
else:
gender = gen.lib.Person.UNKNOWN
child.set_gender(gender)
if source:
# add, if new
new, source = self.get_or_create_source(source)
source_refs = child.get_source_references()
found = 0
for ref in source_refs:
LOG.debug("child: %s looking for ref: %s", ref.ref, source.get_handle())
if ref.ref == source.get_handle():
found = 1
if not found:
sref = gen.lib.SourceRef()
sref.set_reference_handle(source.get_handle())
child.add_source_reference(sref)
# put note on child
if note:
# append notes, if previous notes
previous_notes_list = child.get_note_list()
updated_note = False
for note_handle in previous_notes_list:
previous_note = self.db.get_note_from_handle(note_handle)
if previous_note.type == gen.lib.NoteType.PERSON:
previous_text = previous_note.get()
if note not in previous_text:
note = previous_text + "\n" + note
previous_note.set(note)
self.db.commit_note(previous_note, self.trans)
updated_note = True
break
if not updated_note:
# add new note here
new_note = gen.lib.Note()
new_note.handle = create_id()
new_note.type.set(gen.lib.NoteType.PERSON)
new_note.set(note)
self.db.add_note(new_note, self.trans)
child.add_note(new_note.handle)
self.db.commit_person(child, self.trans)
elif "surname" in header: # person data
# surname, and any of the following
surname = rd(line_number, row, col, "surname")
firstname = rd(line_number, row, col, "firstname", "")
callname = rd(line_number, row, col, "callname")
title = rd(line_number, row, col, "title")
prefix = rd(line_number, row, col, "prefix")
suffix = rd(line_number, row, col, "suffix")
gender = rd(line_number, row, col, "gender")
source = rd(line_number, row, col, "source")
note = rd(line_number, row, col, "note")
birthplace = rd(line_number, row, col, "birthplace")
birthdate = rd(line_number, row, col, "birthdate")
birthsource = rd(line_number, row, col, "birthsource")
baptismplace = rd(line_number, row, col, "baptismplace")
baptismdate = rd(line_number, row, col, "baptismdate")
baptismsource = rd(line_number, row, col, "baptismsource")
burialplace = rd(line_number, row, col, "burialplace")
burialdate = rd(line_number, row, col, "burialdate")
burialsource = rd(line_number, row, col, "burialsource")
deathplace = rd(line_number, row, col, "deathplace")
deathdate = rd(line_number, row, col, "deathdate")
deathsource = rd(line_number, row, col, "deathsource")
deathcause = rd(line_number, row, col, "deathcause")
grampsid = rd(line_number, row, col, "grampsid")
person_ref = rd(line_number, row, col, "person")
#########################################################
# if this person already exists, don't create them
person = self.lookup("person", person_ref)
if person is None:
if surname is None:
LOG.warn("empty surname for new person on line %d" % line_number)
surname = ""
# new person
person = self.create_person()
name = gen.lib.Name()
name.set_type(gen.lib.NameType(gen.lib.NameType.BIRTH))
name.set_first_name(firstname)
surname_obj = gen.lib.Surname()
surname_obj.set_surname(surname)
name.add_surname(surname_obj)
person.set_primary_name(name)
if surname is not None:
name.get_primary_surname().set_surname(surname)
if firstname is not None:
name.set_first_name(firstname)
if callname is not None:
name.set_call_name(callname)
if title is not None:
name.set_title(title)
if prefix is not None:
name.get_primary_surname().set_prefix(prefix)
name.group_as = '' # HELP? what should I do here?
if suffix is not None:
name.set_suffix(suffix)
if note is not None:
# append notes, if previous notes
previous_notes_list = person.get_note_list()
updated_note = False
for note_handle in previous_notes_list:
previous_note = self.db.get_note_from_handle(note_handle)
if previous_note.type == gen.lib.NoteType.PERSON:
previous_text = previous_note.get()
if note not in previous_text:
note = previous_text + "\n" + note
previous_note.set(note)
self.db.commit_note(previous_note, self.trans)
updated_note = True
break
if not updated_note:
# add new note here
new_note = gen.lib.Note()
new_note.handle = create_id()
new_note.type.set(gen.lib.NoteType.PERSON)
new_note.set(note)
self.db.add_note(new_note, self.trans)
person.add_note(new_note.handle)
if grampsid is not None:
person.gramps_id = grampsid
elif person_ref is not None:
if person_ref.startswith("[") and person_ref.endswith("]"):
person.gramps_id = person_ref[1:-1]
if person.get_gender() == gen.lib.Person.UNKNOWN and gender is not None:
gender = gender.lower()
if gender == gender_map[gen.lib.Person.MALE].lower():
gender = gen.lib.Person.MALE
elif gender == gender_map[gen.lib.Person.FEMALE].lower():
gender = gen.lib.Person.FEMALE
else:
gender = gen.lib.Person.UNKNOWN
person.set_gender(gender)
#########################################################
# add if new, replace if different
# Birth:
if birthdate is not None:
birthdate = _dp.parse(birthdate)
if birthplace is not None:
new, birthplace = self.get_or_create_place(birthplace)
if birthsource is not None:
new, birthsource = self.get_or_create_source(birthsource)
if birthdate or birthplace or birthsource:
new, birth = self.get_or_create_event(person,
gen.lib.EventType.BIRTH, birthdate,
birthplace, birthsource)
birth_ref = person.get_birth_ref()
if birth_ref is None:
# new
birth_ref = gen.lib.EventRef()
birth_ref.set_reference_handle( birth.get_handle())
person.set_birth_ref( birth_ref)
# Baptism:
if baptismdate is not None:
baptismdate = _dp.parse(baptismdate)
if baptismplace is not None:
new, baptismplace = self.get_or_create_place(baptismplace)
if baptismsource is not None:
new, baptismsource = self.get_or_create_source(baptismsource)
if baptismdate or baptismplace or baptismsource:
new, baptism = self.get_or_create_event(person,
gen.lib.EventType.BAPTISM, baptismdate,
baptismplace, baptismsource)
baptism_ref = get_primary_event_ref_from_type(self.db, person, "Baptism")
if baptism_ref is None:
# new
baptism_ref = gen.lib.EventRef()
baptism_ref.set_reference_handle( baptism.get_handle())
person.add_event_ref( baptism_ref)
# Death:
if deathdate is not None:
deathdate = _dp.parse(deathdate)
if deathplace is not None:
new, deathplace = self.get_or_create_place(deathplace)
if deathsource is not None:
new, deathsource = self.get_or_create_source(deathsource)
if deathdate or deathplace or deathsource or deathcause:
new, death = self.get_or_create_event(person, gen.lib.EventType.DEATH,
deathdate, deathplace, deathsource)
if deathcause:
death.set_description(deathcause)
self.db.commit_event(death, self.trans)
death_ref = person.get_death_ref()
if death_ref is None:
# new
death_ref = gen.lib.EventRef()
death_ref.set_reference_handle(death.get_handle())
person.set_death_ref(death_ref)
# Burial:
if burialdate is not None:
burialdate = _dp.parse(burialdate)
if burialplace is not None:
new, burialplace = self.get_or_create_place(burialplace)
if burialsource is not None:
new, burialsource = self.get_or_create_source(burialsource)
if burialdate or burialplace or burialsource:
new, burial = self.get_or_create_event(person,
gen.lib.EventType.BURIAL, burialdate,
burialplace, burialsource)
burial_ref = get_primary_event_ref_from_type(self.db, person, "Burial")
if burial_ref is None:
# new
burial_ref = gen.lib.EventRef()
burial_ref.set_reference_handle( burial.get_handle())
person.add_event_ref( burial_ref)
if source:
# add, if new
new, source = self.get_or_create_source(source)
source_refs = person.get_source_references()
found = 0
for ref in source_refs:
LOG.debug("person: %s looking for ref: %s", ref.ref, source.get_handle())
if ref.ref == source.get_handle():
found = 1
if not found:
sref = gen.lib.SourceRef()
sref.set_reference_handle(source.get_handle())
person.add_source_reference(sref)
self.db.commit_person(person, self.trans)
else:
name = person.get_primary_name()
#########################################################
if person_ref is not None:
self.storeup("person", person_ref, person)
# replace
if surname is not None:
name.get_primary_surname().set_surname(surname)
if firstname is not None:
name.set_first_name(firstname)
if callname is not None:
name.set_call_name(callname)
if title is not None:
name.set_title(title)
if prefix is not None:
name.get_primary_surname().set_prefix(prefix)
name.group_as = '' # HELP? what should I do here?
if suffix is not None:
name.set_suffix(suffix)
if note is not None:
# append notes, if previous notes
previous_notes_list = person.get_note_list()
updated_note = False
for note_handle in previous_notes_list:
previous_note = self.db.get_note_from_handle(note_handle)
if previous_note.type == gen.lib.NoteType.PERSON:
previous_text = previous_note.get()
if note not in previous_text:
note = previous_text + "\n" + note
previous_note.set(note)
self.db.commit_note(previous_note, self.trans)
updated_note = True
break
if not updated_note:
# add new note here
new_note = gen.lib.Note()
new_note.handle = create_id()
new_note.type.set(gen.lib.NoteType.PERSON)
new_note.set(note)
self.db.add_note(new_note, self.trans)
person.add_note(new_note.handle)
if grampsid is not None:
person.gramps_id = grampsid
elif person_ref is not None:
if person_ref.startswith("[") and person_ref.endswith("]"):
person.gramps_id = person_ref[1:-1]
if person.get_gender() == gen.lib.Person.UNKNOWN and gender is not None:
gender = gender.lower()
if gender == gender_map[gen.lib.Person.MALE].lower():
gender = gen.lib.Person.MALE
elif gender == gender_map[gen.lib.Person.FEMALE].lower():
gender = gen.lib.Person.FEMALE
else:
gender = gen.lib.Person.UNKNOWN
person.set_gender(gender)
#########################################################
# add if new, replace if different
# Birth:
if birthdate is not None:
birthdate = _dp.parse(birthdate)
if birthplace is not None:
new, birthplace = self.get_or_create_place(birthplace)
if birthsource is not None:
new, birthsource = self.get_or_create_source(birthsource)
if birthdate or birthplace or birthsource:
new, birth = self.get_or_create_event(person,
gen.lib.EventType.BIRTH, birthdate,
birthplace, birthsource)
birth_ref = person.get_birth_ref()
if birth_ref is None:
# new
birth_ref = gen.lib.EventRef()
birth_ref.set_reference_handle( birth.get_handle())
person.set_birth_ref( birth_ref)
# Baptism:
if baptismdate is not None:
baptismdate = _dp.parse(baptismdate)
if baptismplace is not None:
new, baptismplace = self.get_or_create_place(baptismplace)
if baptismsource is not None:
new, baptismsource = self.get_or_create_source(baptismsource)
if baptismdate or baptismplace or baptismsource:
new, baptism = self.get_or_create_event(person,
gen.lib.EventType.BAPTISM, baptismdate,
baptismplace, baptismsource)
baptism_ref = get_primary_event_ref_from_type(self.db, person, "Baptism")
if baptism_ref is None:
# new
baptism_ref = gen.lib.EventRef()
baptism_ref.set_reference_handle( baptism.get_handle())
person.add_event_ref( baptism_ref)
# Death:
if deathdate is not None:
deathdate = _dp.parse(deathdate)
if deathplace is not None:
new, deathplace = self.get_or_create_place(deathplace)
if deathsource is not None:
new, deathsource = self.get_or_create_source(deathsource)
if deathdate or deathplace or deathsource or deathcause:
new, death = self.get_or_create_event(person, gen.lib.EventType.DEATH,
deathdate, deathplace, deathsource)
if deathcause:
death.set_description(deathcause)
self.db.commit_event(death, self.trans)
death_ref = person.get_death_ref()
if death_ref is None:
# new
death_ref = gen.lib.EventRef()
death_ref.set_reference_handle(death.get_handle())
person.set_death_ref(death_ref)
# Burial:
if burialdate is not None:
burialdate = _dp.parse(burialdate)
if burialplace is not None:
new, burialplace = self.get_or_create_place(burialplace)
if burialsource is not None:
new, burialsource = self.get_or_create_source(burialsource)
if burialdate or burialplace or burialsource:
new, burial = self.get_or_create_event(person,
gen.lib.EventType.BURIAL, burialdate,
burialplace, burialsource)
burial_ref = get_primary_event_ref_from_type(self.db, person, "Burial")
if burial_ref is None:
# new
burial_ref = gen.lib.EventRef()
burial_ref.set_reference_handle( burial.get_handle())
person.add_event_ref( burial_ref)
if source:
# add, if new
new, source = self.get_or_create_source(source)
source_refs = person.get_source_references()
found = 0
for ref in source_refs:
LOG.debug("person: %s looking for ref: %s", ref.ref, source.get_handle())
if ref.ref == source.get_handle():
found = 1
if not found:
sref = gen.lib.SourceRef()
sref.set_reference_handle(source.get_handle())
person.add_source_reference(sref)
self.db.commit_person(person, self.trans)
else:
LOG.warn("ignoring line %d" % line_number)
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.transaction_commit(self.trans,_("CSV import"))
LOG.warn("ignoring line %d" % line_number)
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.enable_signals()
self.db.request_rebuild()
LOG.debug(msg)

View File

@ -112,73 +112,73 @@ class GeneWebParser(object):
return line
def parse_geneweb_file(self):
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
t = time.time()
self.lineno = 0
self.index = 0
self.fam_count = 0
self.indi_count = 0
with self.db.transaction_begin(_("GeneWeb import"), batch=True
) as self.trans:
self.db.disable_signals()
t = time.time()
self.lineno = 0
self.index = 0
self.fam_count = 0
self.indi_count = 0
self.fkeys = []
self.ikeys = {}
self.pkeys = {}
self.skeys = {}
self.fkeys = []
self.ikeys = {}
self.pkeys = {}
self.skeys = {}
self.current_mode = None
self.current_family = None
self.current_husband_handle = None
self.current_child_birthplace_handle = None
self.current_child_source_handle = None
try:
while 1:
line = self.get_next_line()
if line is None:
break
if line == "":
continue
self.current_mode = None
self.current_family = None
self.current_husband_handle = None
self.current_child_birthplace_handle = None
self.current_child_source_handle = None
try:
while 1:
line = self.get_next_line()
if line is None:
break
if line == "":
continue
fields = line.split(" ")
fields = line.split(" ")
LOG.debug("LINE: %s" %line)
if fields[0] == "fam":
self.current_mode = "fam"
self.read_family_line(line,fields)
elif fields[0] == "rel":
self.current_mode = "rel"
self.read_relationship_person(line,fields)
elif fields[0] == "src":
self.read_source_line(line,fields)
elif fields[0] in ("wit", "wit:"):
self.read_witness_line(line,fields)
elif fields[0] == "cbp":
self.read_children_birthplace_line(line,fields)
elif fields[0] == "csrc":
self.read_children_source_line(line,fields)
elif fields[0] == "beg" and self.current_mode == "fam":
self.read_children_lines()
elif fields[0] == "beg" and self.current_mode == "rel":
self.read_relation_lines()
elif fields[0] == "comm":
self.read_family_comment(line,fields)
elif fields[0] == "notes":
self.read_person_notes_lines(line,fields)
elif fields[0] == "notes-db":
self.read_database_notes_lines(line,fields)
elif fields[0] == "end":
self.current_mode = None
elif fields[0] == "encoding:":
self.encoding = fields[1]
else:
LOG.warn("parse_geneweb_file(): Token >%s< unknown. line %d skipped: %s" %
(fields[0],self.lineno,line))
except Errors.GedcomError, err:
self.errmsg(str(err))
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.transaction_commit(self.trans,_("GeneWeb import"))
LOG.debug("LINE: %s" %line)
if fields[0] == "fam":
self.current_mode = "fam"
self.read_family_line(line,fields)
elif fields[0] == "rel":
self.current_mode = "rel"
self.read_relationship_person(line,fields)
elif fields[0] == "src":
self.read_source_line(line,fields)
elif fields[0] in ("wit", "wit:"):
self.read_witness_line(line,fields)
elif fields[0] == "cbp":
self.read_children_birthplace_line(line,fields)
elif fields[0] == "csrc":
self.read_children_source_line(line,fields)
elif fields[0] == "beg" and self.current_mode == "fam":
self.read_children_lines()
elif fields[0] == "beg" and self.current_mode == "rel":
self.read_relation_lines()
elif fields[0] == "comm":
self.read_family_comment(line,fields)
elif fields[0] == "notes":
self.read_person_notes_lines(line,fields)
elif fields[0] == "notes-db":
self.read_database_notes_lines(line,fields)
elif fields[0] == "end":
self.current_mode = None
elif fields[0] == "encoding:":
self.encoding = fields[1]
else:
LOG.warn("parse_geneweb_file(): Token >%s< unknown. line %d skipped: %s" %
(fields[0],self.lineno,line))
except Errors.GedcomError, err:
self.errmsg(str(err))
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -495,14 +495,14 @@ class ProgenParser(object):
self.pers = _read_recs(self.def_['Table_1'], self.bname)
self.rels = _read_recs(self.def_['Table_2'], self.bname)
self.trans = self.db.transaction_begin('', batch=True)
self.db.disable_signals()
with self.db.transaction_begin(_("Pro-Gen import"), batch=True
) as self.trans:
self.db.disable_signals()
self.create_persons()
self.create_families()
self.add_children()
self.create_persons()
self.create_families()
self.add_children()
self.db.transaction_commit(self.trans, _("Pro-Gen import"))
self.db.enable_signals()
self.db.request_rebuild()
self.progress.close()

View File

@ -90,60 +90,60 @@ class VCardParser(object):
return line
def parse_vCard_file(self):
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
t = time.time()
self.person = None
with self.db.transaction_begin(_("vCard import"), batch=True
) as self.trans:
self.db.disable_signals()
t = time.time()
self.person = None
line_reg = re.compile('^([^:]+)+:(.*)$')
try:
while 1:
line = self.get_next_line()
if line is None:
break
if line == "":
continue
if line.find(":") == -1:
continue
line_parts = line_reg.match( line)
if not line_parts:
continue
fields = line_parts.group(1).split(";")
#for field in line_parts.groups():
# print " p "+field
#for field in fields:
# print " f "+field
line_reg = re.compile('^([^:]+)+:(.*)$')
try:
while 1:
line = self.get_next_line()
if line is None:
break
if line == "":
continue
if fields[0] == "BEGIN":
self.next_person()
elif fields[0] == "END":
self.finish_person()
elif fields[0] == "FN":
self.set_nick_name(fields, line_parts.group(2))
elif fields[0] == "N":
self.add_name(fields, line_parts.group(2))
elif fields[0] == "ADR":
self.add_address(fields, line_parts.group(2))
elif fields[0] == "TEL":
self.add_phone(fields, line_parts.group(2))
elif fields[0] == "BDAY":
self.add_birthday(fields, line_parts.group(2))
elif fields[0] == "TITLE":
self.add_title(fields, line_parts.group(2))
elif fields[0] == "URL":
self.add_url(fields, line_parts.group(2))
else:
LOG.warn("Token >%s< unknown. line skipped: %s" % (fields[0],line))
except Errors.GedcomError, err:
self.errmsg(str(err))
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.transaction_commit(self.trans,_("vCard import"))
if line.find(":") == -1:
continue
line_parts = line_reg.match( line)
if not line_parts:
continue
fields = line_parts.group(1).split(";")
#for field in line_parts.groups():
# print " p "+field
#for field in fields:
# print " f "+field
if fields[0] == "BEGIN":
self.next_person()
elif fields[0] == "END":
self.finish_person()
elif fields[0] == "FN":
self.set_nick_name(fields, line_parts.group(2))
elif fields[0] == "N":
self.add_name(fields, line_parts.group(2))
elif fields[0] == "ADR":
self.add_address(fields, line_parts.group(2))
elif fields[0] == "TEL":
self.add_phone(fields, line_parts.group(2))
elif fields[0] == "BDAY":
self.add_birthday(fields, line_parts.group(2))
elif fields[0] == "TITLE":
self.add_title(fields, line_parts.group(2))
elif fields[0] == "URL":
self.add_url(fields, line_parts.group(2))
else:
LOG.warn("Token >%s< unknown. line skipped: %s" % (fields[0],line))
except Errors.GedcomError, err:
self.errmsg(str(err))
t = time.time() - t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', t ) % t
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -771,49 +771,49 @@ class GrampsParser(UpdateCallback):
no_magic = True
else:
no_magic = False
self.trans = self.db.transaction_begin("", batch=True, no_magic=no_magic)
self.set_total(linecount)
with self.db.transaction_begin(_("Gramps XML import"), batch=True,
no_magic=no_magic) as self.trans:
self.set_total(linecount)
self.db.disable_signals()
self.db.disable_signals()
self.p = ParserCreate()
self.p.StartElementHandler = self.startElement
self.p.EndElementHandler = self.endElement
self.p.CharacterDataHandler = self.characters
self.p.ParseFile(ifile)
self.p = ParserCreate()
self.p.StartElementHandler = self.startElement
self.p.EndElementHandler = self.endElement
self.p.CharacterDataHandler = self.characters
self.p.ParseFile(ifile)
if len(self.name_formats) > 0:
# add new name formats to the existing table
self.db.name_formats += self.name_formats
# Register new formats
name_displayer.set_name_format(self.db.name_formats)
self.db.set_researcher(self.owner)
if self.home is not None:
person = self.db.get_person_from_handle(self.home)
self.db.set_default_person_handle(person.handle)
#set media path, this should really do some parsing to convert eg
# windows path to unix ?
if self.mediapath:
oldpath = self.db.get_mediapath()
if not oldpath:
self.db.set_mediapath(self.mediapath)
elif not oldpath == self.mediapath:
ErrorDialog(_("Could not change media path"),
_("The opened file has media path %s, which conflicts with"
" the media path of the family tree you import into. "
"The original media path has been retained. Copy the "
"files to a correct directory or change the media "
"path in the Preferences."
) % self.mediapath )
for key in self.func_map.keys():
del self.func_map[key]
del self.func_map
del self.func_list
del self.p
self.db.transaction_commit(self.trans, _("Gramps XML import"))
if len(self.name_formats) > 0:
# add new name formats to the existing table
self.db.name_formats += self.name_formats
# Register new formats
name_displayer.set_name_format(self.db.name_formats)
self.db.set_researcher(self.owner)
if self.home is not None:
person = self.db.get_person_from_handle(self.home)
self.db.set_default_person_handle(person.handle)
#set media path, this should really do some parsing to convert eg
# windows path to unix ?
if self.mediapath:
oldpath = self.db.get_mediapath()
if not oldpath:
self.db.set_mediapath(self.mediapath)
elif not oldpath == self.mediapath:
ErrorDialog(_("Could not change media path"),
_("The opened file has media path %s, which conflicts with"
" the media path of the family tree you import into. "
"The original media path has been retained. Copy the "
"files to a correct directory or change the media "
"path in the Preferences."
) % self.mediapath )
for key in self.func_map.keys():
del self.func_map[key]
del self.func_map
del self.func_list
del self.p
self.db.enable_signals()
self.db.request_rebuild()
return self.info

View File

@ -2281,24 +2281,24 @@ class GedcomParser(UpdateCallback):
Parses the opened GEDCOM file.
"""
no_magic = self.maxpeople < 1000
self.trans = self.dbase.transaction_begin("", not use_trans, no_magic)
with self.dbase.transaction_begin(_("GEDCOM import"), not use_trans,
no_magic) as self.trans:
self.dbase.disable_signals()
self.__parse_header_head()
self.want_parse_warnings = False
self.__parse_header_source()
self.want_parse_warnings = True
if self.use_def_src:
self.dbase.add_source(self.def_src, self.trans)
self.__parse_record()
self.__parse_trailer()
for title, handle in self.inline_srcs.iteritems():
src = gen.lib.Source()
src.set_handle(handle)
src.set_title(title)
self.dbase.add_source(src, self.trans)
self.dbase.disable_signals()
self.__parse_header_head()
self.want_parse_warnings = False
self.__parse_header_source()
self.want_parse_warnings = True
if self.use_def_src:
self.dbase.add_source(self.def_src, self.trans)
self.__parse_record()
self.__parse_trailer()
for title, handle in self.inline_srcs.iteritems():
src = gen.lib.Source()
src.set_handle(handle)
src.set_title(title)
self.dbase.add_source(src, self.trans)
self.dbase.transaction_commit(self.trans, _("GEDCOM import"))
self.dbase.enable_signals()
self.dbase.request_rebuild()

View File

@ -50,8 +50,9 @@ class DbMixin(object):
where "database" is the object name of your instance of the gramps
database.
"""
def __find_primary_from_handle(self, handle, transaction, class_type, dmap,
add_func):
def __find_primary_from_handle(self, handle, transaction, class_type,
get_raw_obj_data, add_func):
"""
Find a primary object of class_type in the database from the passed
handle.
@ -65,8 +66,9 @@ class DbMixin(object):
obj = class_type()
handle = str(handle)
new = True
if handle in dmap:
obj.unserialize(dmap.get(handle))
raw = get_raw_obj_data(handle)
if raw is not None:
obj.unserialize(raw)
#references create object with id None before object is really made
if obj.gramps_id is not None:
new = False
@ -75,8 +77,8 @@ class DbMixin(object):
add_func(obj, transaction)
return obj, new
def __find_table_from_handle(self, handle, transaction, class_type, dmap,
add_func):
def __find_table_from_handle(self, handle, transaction, class_type,
get_raw_obj_data, add_func):
"""
Find a table object of class_type in the database from the passed
handle.
@ -89,16 +91,17 @@ class DbMixin(object):
"""
obj = class_type()
handle = str(handle)
if handle in dmap:
obj.unserialize(dmap.get(handle))
raw = get_raw_obj_data(handle)
if raw is not None:
obj.unserialize(raw)
return obj, False
else:
obj.set_handle(handle)
add_func(obj, transaction)
return obj, True
def __check_primary_from_handle(self, handle, transaction, class_type, dmap,
add_func, set_gid=True):
def __check_primary_from_handle(self, handle, transaction, class_type,
has_handle_func, add_func, set_gid):
"""
Check whether a primary object of class_type with the passed handle
exists in the database.
@ -107,13 +110,13 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
handle = str(handle)
if handle not in dmap:
if not has_handle_func(handle):
obj = class_type()
obj.set_handle(handle)
add_func(obj, transaction, set_gid=set_gid)
def __check_table_from_handle(self, handle, transaction, class_type, dmap,
add_func):
def __check_table_from_handle(self, handle, transaction, class_type,
has_handle_func, add_func):
"""
Check whether a table object of class_type with the passed handle exists
in the database.
@ -121,7 +124,7 @@ class DbMixin(object):
If no such object exists, a new object is added to the database.
"""
handle = str(handle)
if handle not in dmap:
if not has_handle_func(handle):
obj = class_type()
obj.set_handle(handle)
add_func(obj, transaction)
@ -137,7 +140,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Person,
self.person_map, self.add_person)
self.get_raw_person_data, self.add_person)
def find_source_from_handle(self, handle, transaction):
"""
@ -150,7 +153,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Source,
self.source_map, self.add_source)
self.get_raw_source_data, self.add_source)
def find_event_from_handle(self, handle, transaction):
"""
@ -163,7 +166,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Event,
self.event_map, self.add_event)
self.get_raw_event_data, self.add_event)
def find_object_from_handle(self, handle, transaction):
"""
@ -175,8 +178,8 @@ class DbMixin(object):
if the object is new
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, MediaObject,
self.media_map, self.add_object)
return self.__find_primary_from_handle(handle, transaction, MediaObject,
self.get_raw_object_data, self.add_object)
def find_place_from_handle(self, handle, transaction):
"""
@ -189,7 +192,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Place,
self.place_map, self.add_place)
self.get_raw_place_data, self.add_place)
def find_family_from_handle(self, handle, transaction):
"""
@ -202,7 +205,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Family,
self.family_map, self.add_family)
self.get_raw_family_data, self.add_family)
def find_repository_from_handle(self, handle, transaction):
"""
@ -215,7 +218,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Repository,
self.repository_map, self.add_repository)
self.get_raw_repository_data, self.add_repository)
def find_note_from_handle(self, handle, transaction):
"""
@ -228,7 +231,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_primary_from_handle(handle, transaction, Note,
self.note_map, self.add_note)
self.get_raw_note_data, self.add_note)
def find_tag_from_handle(self, handle, transaction):
"""
@ -241,7 +244,7 @@ class DbMixin(object):
@rtype: tuple
"""
return self.__find_table_from_handle(handle, transaction, Tag,
self.tag_map, self.add_tag)
self.get_raw_tag_data, self.add_tag)
def check_person_from_handle(self, handle, transaction, set_gid=True):
"""
@ -251,7 +254,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Person,
self.person_map, self.add_person,
self.has_person_handle, self.add_person,
set_gid = set_gid)
def check_source_from_handle(self, handle, transaction, set_gid=True):
@ -262,7 +265,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Source,
self.source_map, self.add_source,
self.has_source_handle, self.add_source,
set_gid=set_gid)
def check_event_from_handle(self, handle, transaction, set_gid=True):
@ -273,7 +276,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Event,
self.event_map, self.add_event,
self.has_event_handle, self.add_event,
set_gid=set_gid)
def check_object_from_handle(self, handle, transaction, set_gid=True):
@ -286,7 +289,7 @@ class DbMixin(object):
"""
self.__check_primary_from_handle(handle, transaction, MediaObject,
self.media_map, self.add_object,
self.has_object_handle, self.add_object,
set_gid=set_gid)
def check_place_from_handle(self, handle, transaction, set_gid=True):
@ -297,7 +300,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Place,
self.place_map, self.add_place,
self.has_place_handle, self.add_place,
set_gid=set_gid)
def check_family_from_handle(self, handle, transaction, set_gid=True):
@ -308,7 +311,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Family,
self.family_map, self.add_family,
self.has_family_handle, self.add_family,
set_gid=set_gid)
def check_repository_from_handle(self, handle, transaction, set_gid=True):
@ -320,8 +323,8 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Repository,
self.repository_map, self.add_repository,
set_gid=set_gid)
self.has_repository_handle, self.add_repository,
set_gid=set_gid)
def check_note_from_handle(self, handle, transaction, set_gid=True):
"""
@ -331,7 +334,7 @@ class DbMixin(object):
If set_gid then a new gramps_id is created, if not, None is used.
"""
self.__check_primary_from_handle(handle, transaction, Note,
self.note_map, self.add_note,
self.has_note_handle, self.add_note,
set_gid=set_gid)
def check_tag_from_handle(self, handle, transaction):
@ -341,4 +344,4 @@ class DbMixin(object):
If no such Tag exists, a new Tag is added to the database.
"""
self.__check_table_from_handle(handle, transaction, Tag,
self.tag_map, self.add_tag)
self.has_tag_handle, self.add_tag)

View File

@ -305,19 +305,17 @@ class BasePersonView(ListView):
self.uistate.set_busy_cursor(True)
# create the transaction
trans = self.dbstate.db.transaction_begin()
with self.dbstate.db.transaction_begin() as trans:
# create name to save
person = self.active_person
active_name = _("Delete Person (%s)") % name_displayer.display(person)
# create name to save
person = self.active_person
active_name = _("Delete Person (%s)") % name_displayer.display(person)
# delete the person from the database
# Above will emit person-delete, which removes the person via
# callback to the model, so row delete is signaled
self.dbstate.db.delete_person_from_database(person, trans)
# commit the transaction
self.dbstate.db.transaction_commit(trans, active_name)
# delete the person from the database
# Above will emit person-delete, which removes the person via
# callback to the model, so row delete is signaled
self.dbstate.db.delete_person_from_database(person, trans)
trans.set_description(active_name)
self.uistate.set_busy_cursor(False)

View File

@ -231,30 +231,30 @@ class ChangeNames(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def on_ok_clicked(self, obj):
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
changelist = set(self.model.get_value(node,1)
for node in self.iter_list
if self.model.get_value(node,0))
with self.db.transaction_begin(_("Capitalization changes"),batch=True
) as self.trans:
self.db.disable_signals()
changelist = set(self.model.get_value(node,1)
for node in self.iter_list
if self.model.get_value(node,0))
#with self.db.get_person_cursor(update=True, commit=True) as cursor:
# for handle, data in cursor:
for handle in self.db.get_person_handles(False):
person = self.db.get_person_from_handle(handle)
#person = Person(data)
change = False
for name in [person.get_primary_name()] + person.get_alternate_names():
sname = find_surname_name(handle, name.serialize())
if sname in changelist:
change = True
for surn in name.get_surname_list():
sname = self.name_cap(surn.get_surname())
surn.set_surname(sname)
if change:
#cursor.update(handle, person.serialize())
self.db.commit_person(person, transaction=self.trans)
#with self.db.get_person_cursor(update=True, commit=True) as cursor:
# for handle, data in cursor:
for handle in self.db.get_person_handles(False):
person = self.db.get_person_from_handle(handle)
#person = Person(data)
change = False
for name in [person.get_primary_name()] + person.get_alternate_names():
sname = find_surname_name(handle, name.serialize())
if sname in changelist:
change = True
for surn in name.get_surname_list():
sname = self.name_cap(surn.get_surname())
surn.set_surname(sname)
if change:
#cursor.update(handle, person.serialize())
self.db.commit_person(person, transaction=self.trans)
self.db.transaction_commit(self.trans,_("Capitalization changes"))
self.db.enable_signals()
self.db.request_rebuild()
# FIXME: this probably needs to be removed, and bookmarks

View File

@ -110,23 +110,23 @@ class ChangeTypes(tool.BatchTool, ManagedWindow.ManagedWindow):
modified = 0
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
if not cli:
progress = ProgressMeter(_('Analyzing Events'),'')
progress.set_pass('',self.db.get_number_of_events())
for event_handle in self.db.get_event_handles():
event = self.db.get_event_from_handle(event_handle)
if event.get_type().xml_str() == fromtype:
event.type.set_from_xml_str(totype)
modified += 1
self.db.commit_event(event,self.trans)
with self.db.transaction_begin(_('Change types'), batch=True
) as self.trans:
self.db.disable_signals()
if not cli:
progress.step()
if not cli:
progress.close()
self.db.transaction_commit(self.trans,_('Change types'))
progress = ProgressMeter(_('Analyzing Events'),'')
progress.set_pass('',self.db.get_number_of_events())
for event_handle in self.db.get_event_handles():
event = self.db.get_event_from_handle(event_handle)
if event.get_type().xml_str() == fromtype:
event.type.set_from_xml_str(totype)
modified += 1
self.db.commit_event(event,self.trans)
if not cli:
progress.step()
if not cli:
progress.close()
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -174,37 +174,37 @@ class Check(tool.BatchTool):
if self.db.__class__.__name__ == 'DbBsddb':
low_level(self.db)
trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
checker = CheckIntegrity(dbstate, uistate, trans)
checker.fix_encoding()
checker.fix_ctrlchars_in_notes()
checker.cleanup_missing_photos(cli)
checker.cleanup_deleted_name_formats()
with self.db.transaction_begin(_("Check Integrity"), batch=True
) as trans:
self.db.disable_signals()
checker = CheckIntegrity(dbstate, uistate, trans)
checker.fix_encoding()
checker.fix_ctrlchars_in_notes()
checker.cleanup_missing_photos(cli)
checker.cleanup_deleted_name_formats()
prev_total = -1
total = 0
prev_total = -1
total = 0
#start with empty objects, broken links can be corrected below then
checker.cleanup_empty_objects()
while prev_total != total:
prev_total = total
checker.check_for_broken_family_links()
checker.check_parent_relationships()
checker.cleanup_empty_families(cli)
checker.cleanup_duplicate_spouses()
#start with empty objects, broken links can be corrected below then
checker.cleanup_empty_objects()
while prev_total != total:
prev_total = total
checker.check_for_broken_family_links()
checker.check_parent_relationships()
checker.cleanup_empty_families(cli)
checker.cleanup_duplicate_spouses()
total = checker.family_errors()
total = checker.family_errors()
checker.check_events()
checker.check_person_references()
checker.check_place_references()
checker.check_source_references()
checker.check_media_references()
checker.check_repo_references()
checker.check_note_references()
self.db.transaction_commit(trans, _("Check Integrity"))
checker.check_events()
checker.check_person_references()
checker.check_place_references()
checker.check_source_references()
checker.check_media_references()
checker.check_repo_references()
checker.check_note_references()
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -155,70 +155,70 @@ class DateParserDisplayTest(tool.Tool):
# (4,7,1789,False,5,88,1876,False),"Text comment")
#dates.append( d)
trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
self.progress.set_pass(_('Generating dates'),
len(dates))
# now add them as birth to new persons
i = 1
for dateval in dates:
person = gen.lib.Person()
name = gen.lib.Name()
name.set_surname("DateTest")
name.set_first_name("Test %d" % i)
person.set_primary_name( name)
self.db.add_person(person,trans)
bevent = gen.lib.Event()
bevent.set_type(gen.lib.EventType.BIRTH)
bevent.set_date_object(dateval)
bevent.set_description("Date Test %d (source)" % i)
bevent_h = self.db.add_event(bevent,trans)
bevent_ref = gen.lib.EventRef()
bevent_ref.set_reference_handle(bevent_h)
# for the death event display the date as text and parse it back to a new date
ndate = None
try:
datestr = _dd.display( dateval)
with self.db.transaction_begin(_("Date Test Plugin"),batch=True
) as trans:
self.db.disable_signals()
self.progress.set_pass(_('Generating dates'),
len(dates))
# now add them as birth to new persons
i = 1
for dateval in dates:
person = gen.lib.Person()
name = gen.lib.Name()
name.set_surname("DateTest")
name.set_first_name("Test %d" % i)
person.set_primary_name( name)
self.db.add_person(person,trans)
bevent = gen.lib.Event()
bevent.set_type(gen.lib.EventType.BIRTH)
bevent.set_date_object(dateval)
bevent.set_description("Date Test %d (source)" % i)
bevent_h = self.db.add_event(bevent,trans)
bevent_ref = gen.lib.EventRef()
bevent_ref.set_reference_handle(bevent_h)
# for the death event display the date as text and parse it back to a new date
ndate = None
try:
ndate = _dp.parse( datestr)
if not ndate:
datestr = _dd.display( dateval)
try:
ndate = _dp.parse( datestr)
if not ndate:
ndate = gen.lib.Date()
ndate.set_as_text("DateParser None")
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
else:
person.set_marker(gen.lib.MarkerType.COMPLETE)
except:
ndate = gen.lib.Date()
ndate.set_as_text("DateParser None")
ndate.set_as_text("DateParser Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
else:
person.set_marker(gen.lib.MarkerType.COMPLETE)
except:
ndate = gen.lib.Date()
ndate.set_as_text("DateParser Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
ndate.set_as_text("DateDisplay Exception: %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
except:
ndate = gen.lib.Date()
ndate.set_as_text("DateDisplay Exception: %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
if dateval.get_modifier() != gen.lib.Date.MOD_TEXTONLY \
and ndate.get_modifier() == gen.lib.Date.MOD_TEXTONLY:
# parser was unable to correctly parse the string
ndate.set_as_text( "TEXTONLY: "+ndate.get_text())
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
if dateval.get_modifier() == gen.lib.Date.MOD_TEXTONLY \
and dateval.get_text().count("Traceback") \
and person.get_marker() == gen.lib.MarkerType.COMPLETE:
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
devent = gen.lib.Event()
devent.set_type(gen.lib.EventType.DEATH)
devent.set_date_object(ndate)
devent.set_description("Date Test %d (result)" % i)
devent_h = self.db.add_event(devent,trans)
devent_ref = gen.lib.EventRef()
devent_ref.set_reference_handle(devent_h)
person.set_birth_ref(bevent_ref)
person.set_death_ref(devent_ref)
self.db.commit_person(person,trans)
i = i + 1
self.progress.step()
self.db.transaction_commit(trans, _("Date Test Plugin"))
if dateval.get_modifier() != gen.lib.Date.MOD_TEXTONLY \
and ndate.get_modifier() == gen.lib.Date.MOD_TEXTONLY:
# parser was unable to correctly parse the string
ndate.set_as_text( "TEXTONLY: "+ndate.get_text())
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
if dateval.get_modifier() == gen.lib.Date.MOD_TEXTONLY \
and dateval.get_text().count("Traceback") \
and person.get_marker() == gen.lib.MarkerType.COMPLETE:
person.set_marker(gen.lib.MarkerType.TODO_TYPE)
devent = gen.lib.Event()
devent.set_type(gen.lib.EventType.DEATH)
devent.set_date_object(ndate)
devent.set_description("Date Test %d (result)" % i)
devent_h = self.db.add_event(devent,trans)
devent_ref = gen.lib.EventRef()
devent_ref.set_reference_handle(devent_h)
person.set_birth_ref(bevent_ref)
person.set_death_ref(devent_ref)
self.db.commit_person(person,trans)
i = i + 1
self.progress.step()
self.db.enable_signals()
self.db.request_rebuild()
self.progress.close()

View File

@ -78,34 +78,34 @@ class EventNames(tool.BatchTool, ManagedWindow.ManagedWindow):
"""
Perform the actual extraction of information.
"""
trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
self.change = False
counter = 0
with self.db.transaction_begin(_("Event name changes"), batch=True
) as trans:
self.db.disable_signals()
self.change = False
counter = 0
for person in self.db.iter_people():
for event_ref in person.get_event_ref_list():
if event_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
event_handle = event_ref.ref
event = self.db.get_event_from_handle(event_handle)
if event.get_description() == "":
person_event_name(event, person)
self.db.commit_event(event, trans)
self.change = True
counter += 1
for person in self.db.iter_people():
for event_ref in person.get_event_ref_list():
if event_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
event_handle = event_ref.ref
event = self.db.get_event_from_handle(event_handle)
if event.get_description() == "":
person_event_name(event, person)
self.db.commit_event(event, trans)
self.change = True
counter += 1
for family in self.db.iter_families():
for event_ref in family.get_event_ref_list():
if event_ref.get_role() == gen.lib.EventRoleType.FAMILY:
event_handle = event_ref.ref
event = self.db.get_event_from_handle(event_handle)
if event.get_description() == "":
family_event_name(event, family, self.db)
self.db.commit_event(event, trans)
self.change = True
counter += 1
for family in self.db.iter_families():
for event_ref in family.get_event_ref_list():
if event_ref.get_role() == gen.lib.EventRoleType.FAMILY:
event_handle = event_ref.ref
event = self.db.get_event_from_handle(event_handle)
if event.get_description() == "":
family_event_name(event, family, self.db)
self.db.commit_event(event, trans)
self.change = True
counter += 1
self.db.transaction_commit(trans, _("Event name changes"))
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -591,27 +591,27 @@ class ExtractCity(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help()
def on_ok_clicked(self, obj):
self.trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
changelist = [node for node in self.iter_list
if self.model.get_value(node, 0)]
with self.db.transaction_begin(_("Extract Place data"), batch=True
) as self.trans:
self.db.disable_signals()
changelist = [node for node in self.iter_list
if self.model.get_value(node, 0)]
for change in changelist:
row = self.model[change]
place = self.db.get_place_from_handle(row[6])
(city, state, postal, country) = (row[2], row[3], row[4], row[5])
for change in changelist:
row = self.model[change]
place = self.db.get_place_from_handle(row[6])
(city, state, postal, country) = (row[2], row[3], row[4], row[5])
if city:
place.get_main_location().set_city(city)
if state:
place.get_main_location().set_state(state)
if postal:
place.get_main_location().set_postal_code(postal)
if country:
place.get_main_location().set_country(country)
self.db.commit_place(place, self.trans)
if city:
place.get_main_location().set_city(city)
if state:
place.get_main_location().set_state(state)
if postal:
place.get_main_location().set_postal_code(postal)
if country:
place.get_main_location().set_country(country)
self.db.commit_place(place, self.trans)
self.db.transaction_commit(self.trans, _("Extract Place data"))
self.db.enable_signals()
self.db.request_rebuild()
self.close()

View File

@ -358,27 +358,13 @@ class BatchOp(UpdateCallback):
and transactions before and after the running.
Should not be overridden without good reasons.
"""
self._pre_run()
success = self._run()
self._post_run()
return success
def _pre_run(self):
"""
Low-level method for starting transaction and disabling signals.
Should not be overridden without good reasons.
"""
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
def _post_run(self):
"""
Low-level method for committing transaction and enabling signals.
Should not be overridden without good reasons.
"""
self.db.transaction_commit(self.trans,self.title)
with self.db.transaction_begin("", batch=True) as self.trans:
success = self._run()
trans.set_description(self.title)
self.db.enable_signals()
self.db.request_rebuild()
return success
def _run(self):
"""

View File

@ -242,47 +242,45 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow.ManagedWindow) :
tag_name = self.tagcombo.get_active_text()
# start the db transaction
transaction = self.db.transaction_begin()
with self.db.transaction_begin("Tag not related") as transaction:
tag = self.db.get_tag_from_name(tag_name)
if not tag:
# create the tag if it doesn't already exist
tag = Tag()
tag.set_name(tag_name)
tag.set_priority(self.db.get_number_of_tags())
tag_handle = self.db.add_tag(tag, transaction)
else:
tag_handle = tag.get_handle()
tag = self.db.get_tag_from_name(tag_name)
if not tag:
# create the tag if it doesn't already exist
tag = Tag()
tag.set_name(tag_name)
tag.set_priority(self.db.get_number_of_tags())
tag_handle = self.db.add_tag(tag, transaction)
else:
tag_handle = tag.get_handle()
# if more than 1 person is selected, use a progress indicator
if rows > 1:
progress = ProgressMeter(self.title,_('Starting'))
#TRANS: no singular form needed, as rows is always > 1
progress.set_pass(ngettext("Setting tag for %d person",
"Setting tag for %d people",
rows) % rows, rows)
# if more than 1 person is selected, use a progress indicator
if rows > 1:
progress = ProgressMeter(self.title,_('Starting'))
#TRANS: no singular form needed, as rows is always > 1
progress.set_pass(ngettext("Setting tag for %d person",
"Setting tag for %d people",
rows) % rows, rows)
# iterate through all of the selected rows
(model, paths) = self.treeSelection.get_selected_rows()
# iterate through all of the selected rows
(model, paths) = self.treeSelection.get_selected_rows()
for path in paths:
if progress:
progress.step()
# for the current row, get the GID and the person from the database
iter = self.model.get_iter(path)
personGid = self.model.get_value(iter, 1)
person = self.db.get_person_from_gramps_id(personGid)
for path in paths:
if progress:
progress.step()
# add the tag to the person
person.add_tag(tag_handle)
# for the current row, get the GID and the person from the database
iter = self.model.get_iter(path)
personGid = self.model.get_value(iter, 1)
person = self.db.get_person_from_gramps_id(personGid)
# save this change
self.db.commit_person(person, transaction)
# add the tag to the person
person.add_tag(tag_handle)
# save this change
self.db.commit_person(person, transaction)
# commit the entire transaction
self.db.transaction_commit(transaction, "Tag not related")
# refresh the tags column
self.treeView.set_model(None)

View File

@ -481,63 +481,62 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
GrampsDisplay.help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)
def on_ok_clicked(self, obj):
trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
with self.db.transaction_begin(_("Extract information from names"),
batch=True) as trans:
self.db.disable_signals()
for key, data in self.handle_to_action.items():
p = self.db.get_person_from_handle(key)
if self.nickid in data:
modelhandle = self.nick_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, nick = data[self.nickid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_nick_name(nick.strip())
for key, data in self.handle_to_action.items():
p = self.db.get_person_from_handle(key)
if self.nickid in data:
modelhandle = self.nick_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, nick = data[self.nickid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_nick_name(nick.strip())
if self.titleid in data:
modelhandle = self.title_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
title, given = data[self.titleid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_title(title.strip())
if self.pref1id in data:
modelhandle = self.prefix1_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, prefixtotal, prefix = data[self.pref1id]
name = p.get_primary_name()
name.set_first_name(given.strip())
oldpref = name.get_surname_list()[0].get_prefix().strip()
if oldpref == '' or oldpref == prefix.strip():
name.get_surname_list()[0].set_prefix(prefix)
else:
name.get_surname_list()[0].set_prefix('%s %s' % (prefix, oldpref))
if self.compid in data:
modelhandle = self.compound_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
surns, prefs, cons, prims, origs = data[self.compid]
name = p.get_primary_name()
new_surn_list = []
for surn, pref, con, prim, orig in zip(surns, prefs, cons,
prims, origs):
new_surn_list.append(gen.lib.Surname())
new_surn_list[-1].set_surname(surn.strip())
new_surn_list[-1].set_prefix(pref.strip())
new_surn_list[-1].set_connector(con.strip())
new_surn_list[-1].set_primary(prim)
new_surn_list[-1].set_origintype(orig)
name.set_surname_list(new_surn_list)
if self.titleid in data:
modelhandle = self.title_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
title, given = data[self.titleid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_title(title.strip())
self.db.commit_person(p, trans)
self.db.transaction_commit(trans,
_("Extract information from names"))
if self.pref1id in data:
modelhandle = self.prefix1_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, prefixtotal, prefix = data[self.pref1id]
name = p.get_primary_name()
name.set_first_name(given.strip())
oldpref = name.get_surname_list()[0].get_prefix().strip()
if oldpref == '' or oldpref == prefix.strip():
name.get_surname_list()[0].set_prefix(prefix)
else:
name.get_surname_list()[0].set_prefix('%s %s' % (prefix, oldpref))
if self.compid in data:
modelhandle = self.compound_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
surns, prefs, cons, prims, origs = data[self.compid]
name = p.get_primary_name()
new_surn_list = []
for surn, pref, con, prim, orig in zip(surns, prefs, cons,
prims, origs):
new_surn_list.append(gen.lib.Surname())
new_surn_list[-1].set_surname(surn.strip())
new_surn_list[-1].set_prefix(pref.strip())
new_surn_list[-1].set_connector(con.strip())
new_surn_list[-1].set_primary(prim)
new_surn_list[-1].set_origintype(orig)
name.set_surname_list(new_surn_list)
self.db.commit_person(p, trans)
self.db.enable_signals()
self.db.request_rebuild()
self.close()

View File

@ -285,23 +285,23 @@ class RemoveUnused(tool.Tool, ManagedWindow.ManagedWindow, UpdateCallback):
self.reset()
def do_remove(self, obj):
trans = self.db.transaction_begin("", batch=False)
self.db.disable_signals()
with self.db.transaction_begin(_("Remove unused objects"),
batch=False) as trans:
self.db.disable_signals()
for row_num in range(len(self.real_model)-1, -1, -1):
path = (row_num,)
row = self.real_model[path]
if not row[RemoveUnused.MARK_COL]:
continue
for row_num in range(len(self.real_model)-1, -1, -1):
path = (row_num,)
row = self.real_model[path]
if not row[RemoveUnused.MARK_COL]:
continue
the_type = row[RemoveUnused.OBJ_TYPE_COL]
handle = row[RemoveUnused.OBJ_HANDLE_COL]
remove_func = self.tables[the_type]['remove']
remove_func(handle, trans)
the_type = row[RemoveUnused.OBJ_TYPE_COL]
handle = row[RemoveUnused.OBJ_HANDLE_COL]
remove_func = self.tables[the_type]['remove']
remove_func(handle, trans)
self.real_model.remove(row.iter)
self.real_model.remove(row.iter)
self.db.transaction_commit(trans, _("Remove unused objects"))
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -67,97 +67,97 @@ class ReorderIds(tool.BatchTool):
else:
print "Reordering Gramps IDs..."
self.trans = db.transaction_begin("", batch=True)
db.disable_signals()
with db.transaction_begin(_("Reorder Gramps IDs"), batch=True
) as self.trans:
db.disable_signals()
if uistate:
self.progress.set_pass(_('Reordering People IDs'),
db.get_number_of_people())
self.reorder(gen.lib.Person,
db.get_person_from_gramps_id,
db.get_person_from_handle,
db.find_next_person_gramps_id,
db.person_map,
db.commit_person,
db.person_prefix)
if uistate:
self.progress.set_pass(_('Reordering People IDs'),
db.get_number_of_people())
self.reorder(gen.lib.Person,
db.get_person_from_gramps_id,
db.get_person_from_handle,
db.find_next_person_gramps_id,
db.person_map,
db.commit_person,
db.person_prefix)
if uistate:
self.progress.set_pass(_('Reordering Family IDs'),
db.get_number_of_families())
self.reorder(gen.lib.Family,
db.get_family_from_gramps_id,
db.get_family_from_handle,
db.find_next_family_gramps_id,
db.family_map,
db.commit_family,
db.family_prefix)
if uistate:
self.progress.set_pass(_('Reordering Event IDs'),
db.get_number_of_events())
self.reorder(gen.lib.Event,
db.get_event_from_gramps_id,
db.get_event_from_handle,
db.find_next_event_gramps_id,
db.event_map,
db.commit_event,
db.event_prefix)
if uistate:
self.progress.set_pass(_('Reordering Media Object IDs'),
db.get_number_of_media_objects())
self.reorder(gen.lib.MediaObject,
db.get_object_from_gramps_id,
db.get_object_from_handle,
db.find_next_object_gramps_id,
db.media_map,
db.commit_media_object,
db.mediaobject_prefix)
if uistate:
self.progress.set_pass(_('Reordering Source IDs'),
db.get_number_of_sources())
self.reorder(gen.lib.Source,
db.get_source_from_gramps_id,
db.get_source_from_handle,
db.find_next_source_gramps_id,
db.source_map,
db.commit_source,
db.source_prefix)
if uistate:
self.progress.set_pass(_('Reordering Place IDs'),
db.get_number_of_places())
self.reorder(gen.lib.Place,
db.get_place_from_gramps_id,
db.get_place_from_handle,
db.find_next_place_gramps_id,
db.place_map,
db.commit_place,
db.place_prefix)
if uistate:
self.progress.set_pass(_('Reordering Repository IDs'),
db.get_number_of_repositories())
self.reorder(gen.lib.Repository,
db.get_repository_from_gramps_id,
db.get_repository_from_handle,
db.find_next_repository_gramps_id,
db.repository_map,
db.commit_repository,
db.repository_prefix)
#add reorder notes ID
if uistate:
self.progress.set_pass(_('Reordering Note IDs'),
db.get_number_of_notes())
self.reorder(gen.lib.Note,
db.get_note_from_gramps_id,
db.get_note_from_handle,
db.find_next_note_gramps_id,
db.note_map,
db.commit_note,
db.note_prefix)
if uistate:
self.progress.close()
else:
print "Done."
db.transaction_commit(self.trans, _("Reorder Gramps IDs"))
if uistate:
self.progress.set_pass(_('Reordering Family IDs'),
db.get_number_of_families())
self.reorder(gen.lib.Family,
db.get_family_from_gramps_id,
db.get_family_from_handle,
db.find_next_family_gramps_id,
db.family_map,
db.commit_family,
db.family_prefix)
if uistate:
self.progress.set_pass(_('Reordering Event IDs'),
db.get_number_of_events())
self.reorder(gen.lib.Event,
db.get_event_from_gramps_id,
db.get_event_from_handle,
db.find_next_event_gramps_id,
db.event_map,
db.commit_event,
db.event_prefix)
if uistate:
self.progress.set_pass(_('Reordering Media Object IDs'),
db.get_number_of_media_objects())
self.reorder(gen.lib.MediaObject,
db.get_object_from_gramps_id,
db.get_object_from_handle,
db.find_next_object_gramps_id,
db.media_map,
db.commit_media_object,
db.mediaobject_prefix)
if uistate:
self.progress.set_pass(_('Reordering Source IDs'),
db.get_number_of_sources())
self.reorder(gen.lib.Source,
db.get_source_from_gramps_id,
db.get_source_from_handle,
db.find_next_source_gramps_id,
db.source_map,
db.commit_source,
db.source_prefix)
if uistate:
self.progress.set_pass(_('Reordering Place IDs'),
db.get_number_of_places())
self.reorder(gen.lib.Place,
db.get_place_from_gramps_id,
db.get_place_from_handle,
db.find_next_place_gramps_id,
db.place_map,
db.commit_place,
db.place_prefix)
if uistate:
self.progress.set_pass(_('Reordering Repository IDs'),
db.get_number_of_repositories())
self.reorder(gen.lib.Repository,
db.get_repository_from_gramps_id,
db.get_repository_from_handle,
db.find_next_repository_gramps_id,
db.repository_map,
db.commit_repository,
db.repository_prefix)
#add reorder notes ID
if uistate:
self.progress.set_pass(_('Reordering Note IDs'),
db.get_number_of_notes())
self.reorder(gen.lib.Note,
db.get_note_from_gramps_id,
db.get_note_from_handle,
db.find_next_note_gramps_id,
db.note_map,
db.commit_note,
db.note_prefix)
if uistate:
self.progress.close()
else:
print "Done."
db.enable_signals()
db.request_rebuild()

View File

@ -95,12 +95,12 @@ 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)
trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
family_handles = self.sort_person_events(trans)
if len(family_handles) > 0:
self.sort_family_events(family_handles, trans)
self.db.transaction_commit(trans, _("Sort event changes"))
with self.db.transaction_begin(_("Sort event changes"), batch=True
) as trans:
self.db.disable_signals()
family_handles = self.sort_person_events(trans)
if len(family_handles) > 0:
self.sort_family_events(family_handles, trans)
self.db.enable_signals()
self.db.request_rebuild()

View File

@ -219,7 +219,7 @@ class TestcaseGenerator(tool.BatchTool):
self.db.disable_signals()
else:
batch = False
self.trans = self.db.transaction_begin("")
self.trans = self.db.transaction_begin(_("Testcase generator"))
if False and self.options.handler.options_dict['no_trans']:
@ -1324,6 +1324,9 @@ class TestcaseGenerator(tool.BatchTool):
return result
def commit_transaction(self):
# The way transactions are used in this file is outdated; use a with
# statement so that transaction abort is called on failure. It is too
# much effort to update this file.
#if self.options.handler.options_dict['no_trans']:
self.db.transaction_commit(self.trans,_("Testcase generator step %d") % self.transaction_count)
self.transaction_count += 1

View File

@ -206,10 +206,9 @@ class MediaView(ListView):
basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename)
photo.set_description(root)
trans = self.dbstate.db.transaction_begin()
self.dbstate.db.add_object(photo, trans)
self.dbstate.db.transaction_commit(trans,
_("Drag Media Object"))
with self.dbstate.db.transaction_begin(_("Drag Media Object")
) as trans:
self.dbstate.db.add_object(photo, trans)
widget.emit_stop_by_name('drag_data_received')
def get_bookmarks(self):

View File

@ -1500,14 +1500,14 @@ class RelationshipView(NavigationView):
family = self.dbstate.db.get_family_from_handle(family_handle)
family.add_child_ref(ref)
trans = self.dbstate.db.transaction_begin()
#add parentref to child
person.add_parent_family_handle(family_handle)
#default relationship is used
self.dbstate.db.commit_person(person, trans)
#add child to family
self.dbstate.db.commit_family(family, trans)
self.dbstate.db.transaction_commit(trans, _("Add Child to Family"))
with self.dbstate.db.transaction_begin(_("Add Child to Family")
) as trans:
#add parentref to child
person.add_parent_family_handle(family_handle)
#default relationship is used
self.dbstate.db.commit_person(person, trans)
#add child to family
self.dbstate.db.commit_family(family, trans)
def sel_child_to_fam(self, obj, event, handle, surname=None):
if button_activated(event, _LEFT_BUTTON):