From 1231b1cac87194552bd19ce8171e71ce16634743 Mon Sep 17 00:00:00 2001 From: Michiel Nauta Date: Wed, 9 Feb 2011 16:03:52 +0000 Subject: [PATCH] 4590: Error on access of LDS editor when sealed to family has been removed. svn: r16592 --- src/Merge/mergefamily.py | 6 ++++ src/Merge/mergeperson.py | 11 ++++++++ src/gen/db/base.py | 52 +++++++++++++---------------------- src/gen/db/write.py | 1 + src/gen/lib/ldsord.py | 2 ++ src/gen/lib/person.py | 12 ++++++-- src/gui/editors/editfamily.py | 2 +- src/plugins/tool/Check.py | 34 +++++++++++++++++++++-- 8 files changed, 81 insertions(+), 39 deletions(-) diff --git a/src/Merge/mergefamily.py b/src/Merge/mergefamily.py index 025c7d2fc..343735932 100644 --- a/src/Merge/mergefamily.py +++ b/src/Merge/mergefamily.py @@ -340,5 +340,11 @@ class MergeFamilyQuery(object): if phoenix_mother: phoenix_mother.remove_family_handle(old_handle) self.database.commit_person(phoenix_mother, trans) + # replace the family in lds ordinances + for (dummy, person_handle) in self.database.find_backlink_handles( + old_handle, ['Person']): + person = self.database.get_person_from_handle(person_handle) + person.replace_handle_reference('Family', old_handle,new_handle) + self.database.commit_person(person, trans) self.database.remove_family(old_handle, trans) self.database.commit_family(self.phoenix, trans) diff --git a/src/Merge/mergeperson.py b/src/Merge/mergeperson.py index 332eafc2a..86887886e 100644 --- a/src/Merge/mergeperson.py +++ b/src/Merge/mergeperson.py @@ -366,6 +366,7 @@ class MergePersonQuery(object): Merge content of family into the family with handle main_family_handle. """ new_handle = self.phoenix.get_handle() if self.phoenix else None + old_handle = self.titanic.get_handle() if self.titanic else None family_handle = family.get_handle() main_family = self.database.get_family_from_handle(main_family_handle) main_family.merge(family) @@ -387,6 +388,16 @@ class MergePersonQuery(object): if spouse: spouse.remove_family_handle(family_handle) self.database.commit_person(spouse, trans) + # replace the family in lds ordinances + for (dummy, person_handle) in self.database.find_backlink_handles( + family_handle, ['Person']): + if person_handle == old_handle: + continue + person = self.database.get_person_from_handle(person_handle) + person.replace_handle_reference('Family', family_handle, + main_family_handle) + if person_handle != new_handle and person_handle != old_handle: + self.database.commit_person(person, trans) self.database.remove_family(family_handle, trans) self.database.commit_family(main_family, trans) diff --git a/src/gen/db/base.py b/src/gen/db/base.py index c69b0a420..9859df3a2 100644 --- a/src/gen/db/base.py +++ b/src/gen/db/base.py @@ -1556,14 +1556,9 @@ class DbWriteBase(object): person.remove_parent_family_handle(family_handle) family.remove_child_handle(person_handle) - child_list = family.get_child_ref_list() - if (not family.get_father_handle() and not family.get_mother_handle() and - len(child_list) <= 1): - self.remove_family(family_handle, trans) - if child_list: - child = self.get_person_from_handle(child_list[0].ref) - child.remove_parent_family_handle(family_handle) - self.commit_person(child, trans) + if (not family.get_father_handle() and not family.get_mother_handle() + and not family.get_child_ref_list()): + self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) self.commit_person(person, trans) @@ -1590,7 +1585,7 @@ class DbWriteBase(object): if not family.get_father_handle() and not family.get_mother_handle() and \ not family.get_child_ref_list(): - self.remove_family(family_handle, trans) + self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) @@ -1598,7 +1593,12 @@ class DbWriteBase(object): if family_handle: family = self.get_family_from_handle(family_handle) family.remove_child_handle(person.get_handle()) - self.commit_family(family, trans) + if not family.get_father_handle() and \ + not family.get_mother_handle() and \ + not family.get_child_ref_list(): + self.remove_family_relationships(family_handle, trans) + else: + self.commit_family(family, trans) handle = person.get_handle() @@ -1625,25 +1625,16 @@ class DbWriteBase(object): def __remove_family_relationships(self, family_handle, trans): """ - Remove a family and its relationships; trans is compulsory. + Remove a family and all that references it; trans is compulsory. """ - family = self.get_family_from_handle(family_handle) - - for phandle in [ family.get_father_handle(), - family.get_mother_handle()]: - if phandle: - person = self.get_person_from_handle(phandle) - person.remove_family_handle(family_handle) - self.commit_person(person, trans) - - for ref in family.get_child_ref_list(): - phandle = ref.ref + person_list = [item[1] for item in + self.find_backlink_handles(family_handle, ['Person'])] + for phandle in person_list: person = self.get_person_from_handle(phandle) - person.remove_parent_family_handle(family_handle) + person.remove_handle_references('Family', [family_handle]) self.commit_person(person, trans) - self.remove_family(family_handle, trans) - + def remove_parent_from_family(self, person_handle, family_handle, trans=None): """ @@ -1676,14 +1667,9 @@ class DbWriteBase(object): msg = _("Remove mother from family") family.set_mother_handle(None) - child_list = family.get_child_ref_list() - if (not family.get_father_handle() and not family.get_mother_handle() and - len(child_list) <= 1): - self.remove_family(family_handle, trans) - if child_list: - child = self.get_person_from_handle(child_list[0].ref) - child.remove_parent_family_handle(family_handle) - self.commit_person(child, trans) + if (not family.get_father_handle() and not family.get_mother_handle() + and not family.get_child_ref_list()): + self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) self.commit_person(person, trans) diff --git a/src/gen/db/write.py b/src/gen/db/write.py index 98e83c72a..ed57cfd23 100644 --- a/src/gen/db/write.py +++ b/src/gen/db/write.py @@ -726,6 +726,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): result_list = list(find_backlink_handles(handle)) """ + handle = str(handle) # Use the secondary index to locate all the reference_map entries # that include a reference to the object we are looking for. referenced_cur = self.get_reference_map_referenced_cursor() diff --git a/src/gen/lib/ldsord.py b/src/gen/lib/ldsord.py index 78dcade69..172f69013 100644 --- a/src/gen/lib/ldsord.py +++ b/src/gen/lib/ldsord.py @@ -194,6 +194,8 @@ class LdsOrd(SecondaryObject, SourceBase, NoteBase, ret = self.get_referenced_note_handles() if self.place: ret += [('Place', self.place)] + if self.famc: + ret += [('Family', self.famc)] return ret def get_handle_referents(self): diff --git a/src/gen/lib/person.py b/src/gen/lib/person.py index 4292c653c..94589a562 100644 --- a/src/gen/lib/person.py +++ b/src/gen/lib/person.py @@ -226,7 +226,8 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase, return any(ref.ref == handle for ref in self.person_ref_list) elif classname == 'Family': return any(ref == handle - for ref in self.family_list + self.parent_family_list) + for ref in self.family_list + self.parent_family_list + + [ordinance.famc for ordinance in self.lds_ord_list]) elif classname == 'Place': return any(ordinance.place == handle for ordinance in self.lds_ord_list) @@ -268,6 +269,9 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase, new_list = [handle for handle in self.parent_family_list if handle not in handle_list] self.parent_family_list = new_list + for ordinance in self.lds_ord_list: + if ordinance.famc in handle_list: + ordinance.famc = None elif classname == 'Place': for ordinance in self.lds_ord_list: if ordinance.place in handle_list: @@ -326,10 +330,14 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase, while old_handle in self.family_list: ix = self.family_list.index(old_handle) self.family_list[ix] = new_handle - while old_handle in self.parent_family_list: ix = self.parent_family_list.index(old_handle) self.parent_family_list[ix] = new_handle + handle_list = [ordinance.famc for ordinance in self.lds_ord_list] + while old_handle in handle_list: + ix = handle_list.index(old_handle) + self.lds_ord_list[ix].famc = new_handle + handle_list[ix] = '' elif classname == "Place": handle_list = [ordinance.place for ordinance in self.lds_ord_list] while old_handle in handle_list: diff --git a/src/gui/editors/editfamily.py b/src/gui/editors/editfamily.py index 5fd575326..02c8c8db8 100644 --- a/src/gui/editors/editfamily.py +++ b/src/gui/editors/editfamily.py @@ -1109,7 +1109,7 @@ class EditFamily(EditPrimary): self.db.commit_person(person, trans) if self.object_is_empty(): - self.db.remove_family(self.obj.handle, trans) + self.db.remove_family_relationships(self.obj.handle, trans) else: if not self.obj.get_gramps_id(): self.obj.set_gramps_id( diff --git a/src/plugins/tool/Check.py b/src/plugins/tool/Check.py index fbe3fd677..067490b7d 100644 --- a/src/plugins/tool/Check.py +++ b/src/plugins/tool/Check.py @@ -200,6 +200,7 @@ class Check(tool.BatchTool): checker.check_events() checker.check_person_references() + checker.check_family_references() checker.check_place_references() checker.check_source_references() checker.check_media_references() @@ -234,6 +235,7 @@ class CheckIntegrity(object): self.invalid_birth_events = [] self.invalid_death_events = [] self.invalid_person_references = [] + self.invalid_family_references = [] self.invalid_place_references = [] self.invalid_source_references = [] self.invalid_repo_references = [] @@ -871,6 +873,24 @@ class CheckIntegrity(object): self.db.commit_person(person, self.trans) self.invalid_person_references.append(key) + def check_family_references(self): + plist = self.db.get_person_handles() + + self.progress.set_pass(_('Looking for family reference problems'), + len(plist)) + + for key in plist: + person = self.db.get_person_from_handle(key) + for ordinance in person.get_lds_ord_list(): + family_handle = ordinance.get_family_handle() + if family_handle: + family = self.db.get_family_from_handle(family_handle) + if not family: + # The referenced family does not exist in the database + ordinance.set_family_handle(None) + self.db.commit_person(person, self.trans) + self.invalid_family_references.append(key) + def check_repo_references(self): slist = self.db.get_source_handles() @@ -1298,6 +1318,7 @@ class CheckIntegrity(object): death_invalid = len(self.invalid_death_events) person = birth_invalid + death_invalid person_references = len(self.invalid_person_references) + family_references = len(self.invalid_family_references) invalid_dates = len(self.invalid_dates) place_references = len(self.invalid_place_references) source_references = len(self.invalid_source_references) @@ -1318,9 +1339,9 @@ class CheckIntegrity(object): errors = (photos + efam + blink + plink + slink + rel + event_invalid + person + - person_references + place_references + source_references + - repo_references + media_references + note_references + - name_format + empty_objs + invalid_dates + person_references + family_references + place_references + + source_references + repo_references + media_references + + note_references + name_format + empty_objs + invalid_dates ) if errors == 0: @@ -1427,6 +1448,13 @@ class CheckIntegrity(object): person_references) % person_references ) + if family_references: + self.text.write( + ngettext("%d family was referenced but not found\n", + "%d families were referenced, but not found\n", + family_references) % family_references + ) + if invalid_dates: self.text.write(ngettext("%d date was corrected\n", "%d dates were corrected\n",