5140: Import of Gramps XML file with cross table duplicate handles crashes
svn: r18036
This commit is contained in:
parent
603238aeb0
commit
9dd5465216
@ -625,9 +625,10 @@ class GrampsParser(UpdateCallback):
|
|||||||
"reporef": (self.start_reporef, self.stop_reporef),
|
"reporef": (self.start_reporef, self.stop_reporef),
|
||||||
"rname": (None, self.stop_rname),
|
"rname": (None, self.stop_rname),
|
||||||
}
|
}
|
||||||
|
self.grampsuri = re.compile(r"^gramps://(?P<object_class>[A-Z][a-z]+)/"
|
||||||
|
"handle/(?P<handle>\w+)$")
|
||||||
|
|
||||||
def inaugurate(self, handle, prim_obj, has_handle_func, add_func,
|
def inaugurate(self, handle, target, prim_obj):
|
||||||
get_raw_obj_data):
|
|
||||||
"""
|
"""
|
||||||
Assign a handle (identity) to a primary object (and create it if it
|
Assign a handle (identity) to a primary object (and create it if it
|
||||||
doesn't exist yet) and add it to the database.
|
doesn't exist yet) and add it to the database.
|
||||||
@ -641,28 +642,40 @@ class GrampsParser(UpdateCallback):
|
|||||||
:param handle: The handle of the primary object, typically as read
|
:param handle: The handle of the primary object, typically as read
|
||||||
directly from the XML attributes.
|
directly from the XML attributes.
|
||||||
:type handle: str
|
:type handle: str
|
||||||
|
:param target: Indicates the primary object type this handle relates to.
|
||||||
|
:type targe": str, identical to target attr of bookmarks.
|
||||||
:param prim_obj: template of the primary object that is to be created.
|
:param prim_obj: template of the primary object that is to be created.
|
||||||
:type prim_obj: Either an empty instance of a primary object or the
|
:type prim_obj: Either an empty instance of a primary object or the
|
||||||
class object of a primary object.
|
class object of a primary object.
|
||||||
:param has_handle_func: function to determine if the database contains
|
|
||||||
a given handle for a specific object type.
|
|
||||||
:type has_handle_func: func
|
|
||||||
:param add_func: function to add a primary object of a specific type
|
|
||||||
to the database.
|
|
||||||
:type add_func: func
|
|
||||||
:param get_raw_obj_data: function to read the content of a primary
|
|
||||||
object from the db in serialized form.
|
|
||||||
:type get_raw_obj_data: func
|
|
||||||
:returns: The handle of the primary object.
|
:returns: The handle of the primary object.
|
||||||
:rtype: str
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
handle = str(handle.replace('_', ''))
|
handle = str(handle.replace('_', ''))
|
||||||
if handle in self.import_handles:
|
if (handle in self.import_handles and
|
||||||
handle = self.import_handles[handle]
|
target in self.import_handles[handle]):
|
||||||
|
handle = self.import_handles[handle][target]
|
||||||
if not callable(prim_obj):
|
if not callable(prim_obj):
|
||||||
# This method is called by a start_<primary_object> method.
|
# This method is called by a start_<primary_object> method.
|
||||||
|
get_raw_obj_data = {"person": self.db.get_raw_person_data,
|
||||||
|
"family": self.db.get_raw_family_data,
|
||||||
|
"event": self.db.get_raw_event_data,
|
||||||
|
"place": self.db.get_raw_place_data,
|
||||||
|
"source": self.db.get_raw_source_data,
|
||||||
|
"repository": self.db.get_raw_repository_data,
|
||||||
|
"media": self.db.get_raw_object_data,
|
||||||
|
"note": self.db.get_raw_note_data,
|
||||||
|
"tag": self.db.get_raw_tag_data}[target]
|
||||||
raw = get_raw_obj_data(handle)
|
raw = get_raw_obj_data(handle)
|
||||||
prim_obj.unserialize(raw)
|
prim_obj.unserialize(raw)
|
||||||
|
return handle
|
||||||
|
elif handle in self.import_handles:
|
||||||
|
LOG.warn("The file you import contains duplicate handles "
|
||||||
|
"which is illegal and being fixed now.")
|
||||||
|
orig_handle = handle
|
||||||
|
handle = Utils.create_id()
|
||||||
|
while handle in self.import_handles:
|
||||||
|
handle = Utils.create_id()
|
||||||
|
self.import_handles[orig_handle][target] = handle
|
||||||
else:
|
else:
|
||||||
orig_handle = handle
|
orig_handle = handle
|
||||||
if self.replace_import_handle:
|
if self.replace_import_handle:
|
||||||
@ -670,15 +683,32 @@ class GrampsParser(UpdateCallback):
|
|||||||
while handle in self.import_handles:
|
while handle in self.import_handles:
|
||||||
handle = Utils.create_id()
|
handle = Utils.create_id()
|
||||||
else:
|
else:
|
||||||
|
has_handle_func = {"person": self.db.has_person_handle,
|
||||||
|
"family": self.db.has_family_handle,
|
||||||
|
"event": self.db.has_event_handle,
|
||||||
|
"place": self.db.has_place_handle,
|
||||||
|
"source": self.db.has_source_handle,
|
||||||
|
"repository": self.db.has_repository_handle,
|
||||||
|
"media": self.db.has_object_handle,
|
||||||
|
"note": self.db.has_note_handle,
|
||||||
|
"tag": self.db.has_tag_handle}[target]
|
||||||
while has_handle_func(handle):
|
while has_handle_func(handle):
|
||||||
handle = Utils.create_id()
|
handle = Utils.create_id()
|
||||||
self.import_handles[orig_handle] = handle
|
self.import_handles[orig_handle] = {target: handle}
|
||||||
if callable(prim_obj): # method is called by a reference
|
if callable(prim_obj): # method is called by a reference
|
||||||
prim_obj = prim_obj()
|
prim_obj = prim_obj()
|
||||||
prim_obj.set_handle(handle)
|
prim_obj.set_handle(handle)
|
||||||
if add_func == self.db.add_tag:
|
if target == "tag":
|
||||||
add_func(prim_obj, self.trans)
|
self.db.add_tag(prim_obj, self.trans)
|
||||||
else:
|
else:
|
||||||
|
add_func = {"person": self.db.add_person,
|
||||||
|
"family": self.db.add_family,
|
||||||
|
"event": self.db.add_event,
|
||||||
|
"place": self.db.add_place,
|
||||||
|
"source": self.db.add_source,
|
||||||
|
"repository": self.db.add_repository,
|
||||||
|
"media": self.db.add_object,
|
||||||
|
"note": self.db.add_note}[target]
|
||||||
add_func(prim_obj, self.trans, set_gid=False)
|
add_func(prim_obj, self.trans, set_gid=False)
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
@ -954,10 +984,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
Add a family reference to the LDS ordinance currently processed.
|
Add a family reference to the LDS ordinance currently processed.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Family,
|
handle = self.inaugurate(attrs['hlink'], "family", gen.lib.Family)
|
||||||
self.db.has_family_handle,
|
|
||||||
self.db.add_family,
|
|
||||||
self.db.get_raw_family_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
||||||
gen.lib.Family)
|
gen.lib.Family)
|
||||||
@ -967,10 +994,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""A reference to a place in an object: event or lds_ord
|
"""A reference to a place in an object: event or lds_ord
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Place,
|
handle = self.inaugurate(attrs['hlink'], "place", gen.lib.Place)
|
||||||
self.db.has_place_handle,
|
|
||||||
self.db.add_place,
|
|
||||||
self.db.get_raw_place_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), PLACE_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), PLACE_KEY,
|
||||||
gen.lib.Place)
|
gen.lib.Place)
|
||||||
@ -989,10 +1013,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_place_handle(orig_handle))
|
self.db.has_place_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.placeobj,
|
self.inaugurate(orig_handle, "place", self.placeobj)
|
||||||
self.db.has_place_handle,
|
|
||||||
self.db.add_place,
|
|
||||||
self.db.get_raw_place_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), PLACE_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), PLACE_KEY,
|
||||||
self.pidswap, self.db.pid2user_format,
|
self.pidswap, self.db.pid2user_format,
|
||||||
self.db.find_next_place_gramps_id)
|
self.db.find_next_place_gramps_id)
|
||||||
@ -1056,8 +1077,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
|
|
||||||
person = gen.lib.Person()
|
person = gen.lib.Person()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
self.inaugurate(attrs['hlink'], person, self.db.has_person_handle,
|
self.inaugurate(attrs['hlink'], "person", person)
|
||||||
self.db.add_person, self.db.get_raw_person_data)
|
|
||||||
elif 'ref' in attrs:
|
elif 'ref' in attrs:
|
||||||
self.inaugurate_id(attrs['ref'], PERSON_KEY, person)
|
self.inaugurate_id(attrs['ref'], PERSON_KEY, person)
|
||||||
else:
|
else:
|
||||||
@ -1100,10 +1120,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_event_handle(orig_handle))
|
self.db.has_event_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.event,
|
self.inaugurate(orig_handle, "event", self.event)
|
||||||
self.db.has_event_handle,
|
|
||||||
self.db.add_event,
|
|
||||||
self.db.get_raw_event_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), EVENT_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), EVENT_KEY,
|
||||||
self.eidswap, self.db.eid2user_format,
|
self.eidswap, self.db.eid2user_format,
|
||||||
self.db.find_next_event_gramps_id)
|
self.db.find_next_event_gramps_id)
|
||||||
@ -1124,10 +1141,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
self.eventref = gen.lib.EventRef()
|
self.eventref = gen.lib.EventRef()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Event,
|
handle = self.inaugurate(attrs['hlink'], "event", gen.lib.Event)
|
||||||
self.db.has_event_handle,
|
|
||||||
self.db.add_event,
|
|
||||||
self.db.get_raw_event_data)
|
|
||||||
else: # there is no old style XML
|
else: # there is no old style XML
|
||||||
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
||||||
"import is malformed."), _("Any event reference must have a "
|
"import is malformed."), _("Any event reference must have a "
|
||||||
@ -1194,10 +1208,8 @@ class GrampsParser(UpdateCallback):
|
|||||||
# Old XML. Can be either handle or id reference
|
# Old XML. Can be either handle or id reference
|
||||||
# and this is guaranteed to be a person bookmark
|
# and this is guaranteed to be a person bookmark
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person",
|
||||||
self.db.has_person_handle,
|
gen.lib.Person)
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
else:
|
else:
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
||||||
gen.lib.Person)
|
gen.lib.Person)
|
||||||
@ -1206,7 +1218,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
|
|
||||||
# This is new XML, so we are guaranteed to have a handle ref
|
# This is new XML, so we are guaranteed to have a handle ref
|
||||||
handle = attrs['hlink'].replace('_', '')
|
handle = attrs['hlink'].replace('_', '')
|
||||||
handle = self.import_handles[handle]
|
handle = self.import_handles[handle][target]
|
||||||
# Due to pre 2.2.9 bug, bookmarks might be handle of other object
|
# Due to pre 2.2.9 bug, bookmarks might be handle of other object
|
||||||
# Make sure those are filtered out.
|
# Make sure those are filtered out.
|
||||||
# Bookmarks are at end, so all handle must exist before we do bookmrks
|
# Bookmarks are at end, so all handle must exist before we do bookmrks
|
||||||
@ -1279,10 +1291,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_person_handle(orig_handle))
|
self.db.has_person_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.person,
|
self.inaugurate(orig_handle, "person", self.person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), PERSON_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), PERSON_KEY,
|
||||||
self.idswap, self.db.id2user_format,
|
self.idswap, self.db.id2user_format,
|
||||||
self.db.find_next_person_gramps_id)
|
self.db.find_next_person_gramps_id)
|
||||||
@ -1303,10 +1312,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
Store the home person of the database.
|
Store the home person of the database.
|
||||||
"""
|
"""
|
||||||
if 'home' in attrs:
|
if 'home' in attrs:
|
||||||
handle = self.inaugurate(attrs['home'], gen.lib.Person,
|
handle = self.inaugurate(attrs['home'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
self.home = handle
|
self.home = handle
|
||||||
|
|
||||||
def start_father(self, attrs):
|
def start_father(self, attrs):
|
||||||
@ -1314,10 +1320,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
Add a father reference to the family currently processed.
|
Add a father reference to the family currently processed.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
||||||
gen.lib.Person)
|
gen.lib.Person)
|
||||||
@ -1328,10 +1331,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
Add a mother reference to the family currently processed.
|
Add a mother reference to the family currently processed.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
||||||
gen.lib.Person)
|
gen.lib.Person)
|
||||||
@ -1345,10 +1345,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
frel and mrel belonged to the "childof" tag
|
frel and mrel belonged to the "childof" tag
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
|
||||||
gen.lib.Person)
|
gen.lib.Person)
|
||||||
@ -1366,10 +1363,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
belong to the "childref" tag under family.
|
belong to the "childref" tag under family.
|
||||||
"""
|
"""
|
||||||
self.childref = gen.lib.ChildRef()
|
self.childref = gen.lib.ChildRef()
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
self.childref.ref = handle
|
self.childref.ref = handle
|
||||||
self.childref.private = bool(attrs.get('priv'))
|
self.childref.private = bool(attrs.get('priv'))
|
||||||
|
|
||||||
@ -1392,10 +1386,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
self.personref = gen.lib.PersonRef()
|
self.personref = gen.lib.PersonRef()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Person,
|
handle = self.inaugurate(attrs['hlink'], "person", gen.lib.Person)
|
||||||
self.db.has_person_handle,
|
|
||||||
self.db.add_person,
|
|
||||||
self.db.get_raw_person_data)
|
|
||||||
else: # there is no old style XML
|
else: # there is no old style XML
|
||||||
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
||||||
"import is malformed."), _("Any person reference must have a "
|
"import is malformed."), _("Any person reference must have a "
|
||||||
@ -1431,10 +1422,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_family_handle(orig_handle))
|
self.db.has_family_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.family,
|
self.inaugurate(orig_handle, "family", self.family)
|
||||||
self.db.has_family_handle,
|
|
||||||
self.db.add_family,
|
|
||||||
self.db.get_raw_family_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), FAMILY_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), FAMILY_KEY,
|
||||||
self.fidswap, self.db.fid2user_format,
|
self.fidswap, self.db.fid2user_format,
|
||||||
self.db.find_next_family_gramps_id)
|
self.db.find_next_family_gramps_id)
|
||||||
@ -1478,10 +1466,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
person is a child.
|
person is a child.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Family,
|
handle = self.inaugurate(attrs['hlink'], "family", gen.lib.Family)
|
||||||
self.db.has_family_handle,
|
|
||||||
self.db.add_family,
|
|
||||||
self.db.get_raw_family_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
||||||
gen.lib.Family)
|
gen.lib.Family)
|
||||||
@ -1510,10 +1495,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
person is a parent.
|
person is a parent.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Family,
|
handle = self.inaugurate(attrs['hlink'], "family", gen.lib.Family)
|
||||||
self.db.has_family_handle,
|
|
||||||
self.db.add_family,
|
|
||||||
self.db.get_raw_family_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
|
||||||
gen.lib.Family)
|
gen.lib.Family)
|
||||||
@ -1613,8 +1595,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
|
|
||||||
# Tag defintion
|
# Tag defintion
|
||||||
self.tag = gen.lib.Tag()
|
self.tag = gen.lib.Tag()
|
||||||
self.inaugurate(attrs['handle'], self.tag, self.db.has_tag_handle,
|
self.inaugurate(attrs['handle'], "tag", self.tag)
|
||||||
self.db.add_tag, self.db.get_raw_tag_data)
|
|
||||||
self.tag.change = int(attrs.get('change', self.change))
|
self.tag.change = int(attrs.get('change', self.change))
|
||||||
self.info.add('new-object', TAG_KEY, self.tag)
|
self.info.add('new-object', TAG_KEY, self.tag)
|
||||||
self.tag.set_name(attrs['name'])
|
self.tag.set_name(attrs['name'])
|
||||||
@ -1626,9 +1607,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
Tag reference in a primary object.
|
Tag reference in a primary object.
|
||||||
"""
|
"""
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Tag,
|
handle = self.inaugurate(attrs['hlink'], "tag", gen.lib.Tag)
|
||||||
self.db.has_tag_handle,
|
|
||||||
self.db.add_tag, self.db.get_raw_tag_data)
|
|
||||||
|
|
||||||
if self.person:
|
if self.person:
|
||||||
self.person.add_tag(handle)
|
self.person.add_tag(handle)
|
||||||
@ -1660,10 +1639,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_note_handle(orig_handle))
|
self.db.has_note_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.note,
|
self.inaugurate(orig_handle, "note", self.note)
|
||||||
self.db.has_note_handle,
|
|
||||||
self.db.add_note,
|
|
||||||
self.db.get_raw_note_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), NOTE_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), NOTE_KEY,
|
||||||
self.nidswap, self.db.nid2user_format,
|
self.nidswap, self.db.nid2user_format,
|
||||||
self.db.find_next_note_gramps_id)
|
self.db.find_next_note_gramps_id)
|
||||||
@ -1763,10 +1739,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
Add a note reference to the object currently processed.
|
Add a note reference to the object currently processed.
|
||||||
"""
|
"""
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Note,
|
handle = self.inaugurate(attrs['hlink'], "note", gen.lib.Note)
|
||||||
self.db.has_note_handle,
|
|
||||||
self.db.add_note,
|
|
||||||
self.db.get_raw_note_data)
|
|
||||||
else:
|
else:
|
||||||
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
raise GrampsImportError(_("The Gramps Xml you are trying to "
|
||||||
"import is malformed."), _("Any note reference must have a "
|
"import is malformed."), _("Any note reference must have a "
|
||||||
@ -1817,10 +1790,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
self.source_ref = gen.lib.SourceRef()
|
self.source_ref = gen.lib.SourceRef()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Source,
|
handle = self.inaugurate(attrs['hlink'], "source", gen.lib.Source)
|
||||||
self.db.has_source_handle,
|
|
||||||
self.db.add_source,
|
|
||||||
self.db.get_raw_source_data)
|
|
||||||
else:
|
else:
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), SOURCE_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), SOURCE_KEY,
|
||||||
gen.lib.Source)
|
gen.lib.Source)
|
||||||
@ -1866,10 +1836,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_source_handle(orig_handle))
|
self.db.has_source_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.source,
|
self.inaugurate(orig_handle, "source", self.source)
|
||||||
self.db.has_source_handle,
|
|
||||||
self.db.add_source,
|
|
||||||
self.db.get_raw_source_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), SOURCE_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), SOURCE_KEY,
|
||||||
self.sidswap, self.db.sid2user_format,
|
self.sidswap, self.db.sid2user_format,
|
||||||
self.db.find_next_source_gramps_id)
|
self.db.find_next_source_gramps_id)
|
||||||
@ -1890,10 +1857,8 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
self.reporef = gen.lib.RepoRef()
|
self.reporef = gen.lib.RepoRef()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.Repository,
|
handle = self.inaugurate(attrs['hlink'], "repository",
|
||||||
self.db.has_repository_handle,
|
gen.lib.Repository)
|
||||||
self.db.add_repository,
|
|
||||||
self.db.get_raw_repository_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), REPOSITORY_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), REPOSITORY_KEY,
|
||||||
gen.lib.Repository)
|
gen.lib.Repository)
|
||||||
@ -1912,10 +1877,8 @@ class GrampsParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
self.objref = gen.lib.MediaRef()
|
self.objref = gen.lib.MediaRef()
|
||||||
if 'hlink' in attrs:
|
if 'hlink' in attrs:
|
||||||
handle = self.inaugurate(attrs['hlink'], gen.lib.MediaObject,
|
handle = self.inaugurate(attrs['hlink'], "media",
|
||||||
self.db.has_object_handle,
|
gen.lib.MediaObject)
|
||||||
self.db.add_object,
|
|
||||||
self.db.get_raw_object_data)
|
|
||||||
else: # old style XML
|
else: # old style XML
|
||||||
handle = self.inaugurate_id(attrs.get('ref'), MEDIA_KEY,
|
handle = self.inaugurate_id(attrs.get('ref'), MEDIA_KEY,
|
||||||
gen.lib.MediaObject)
|
gen.lib.MediaObject)
|
||||||
@ -1949,10 +1912,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_object_handle(orig_handle))
|
self.db.has_object_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.object,
|
self.inaugurate(orig_handle, "media", self.object)
|
||||||
self.db.has_object_handle,
|
|
||||||
self.db.add_object,
|
|
||||||
self.db.get_raw_object_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), MEDIA_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), MEDIA_KEY,
|
||||||
self.oidswap, self.db.oid2user_format,
|
self.oidswap, self.db.oid2user_format,
|
||||||
self.db.find_next_object_gramps_id)
|
self.db.find_next_object_gramps_id)
|
||||||
@ -1986,10 +1946,7 @@ class GrampsParser(UpdateCallback):
|
|||||||
orig_handle = attrs['handle'].replace('_', '')
|
orig_handle = attrs['handle'].replace('_', '')
|
||||||
is_merge_candidate = (self.replace_import_handle and
|
is_merge_candidate = (self.replace_import_handle and
|
||||||
self.db.has_repository_handle(orig_handle))
|
self.db.has_repository_handle(orig_handle))
|
||||||
self.inaugurate(orig_handle, self.repo,
|
self.inaugurate(orig_handle, "repository", self.repo)
|
||||||
self.db.has_repository_handle,
|
|
||||||
self.db.add_repository,
|
|
||||||
self.db.get_raw_repository_data)
|
|
||||||
gramps_id = self.legalize_id(attrs.get('id'), REPOSITORY_KEY,
|
gramps_id = self.legalize_id(attrs.get('id'), REPOSITORY_KEY,
|
||||||
self.ridswap, self.db.rid2user_format,
|
self.ridswap, self.db.rid2user_format,
|
||||||
self.db.find_next_repository_gramps_id)
|
self.db.find_next_repository_gramps_id)
|
||||||
|
@ -150,6 +150,27 @@ def _table_low_level(db,table):
|
|||||||
table.sync()
|
table.sync()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def cross_table_duplicates(db):
|
||||||
|
"""
|
||||||
|
Function to find the presence of identical handles that occur in different
|
||||||
|
database tables.
|
||||||
|
|
||||||
|
Assumes there are no intable duplicates, see low_level function.
|
||||||
|
|
||||||
|
:param db: the database to check
|
||||||
|
:type db: :class:`gen.db.read.DbBsddbRead`
|
||||||
|
:returns: the presence of cross table duplicate handles
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
total_nr_handles = 0
|
||||||
|
all_handles = set([])
|
||||||
|
for the_map in [db.person_map, db.family_map, db.event_map, db.place_map,
|
||||||
|
db.source_map, db.media_map, db.repository_map, db.note_map]:
|
||||||
|
handle_list = the_map.keys()
|
||||||
|
total_nr_handles += len(handle_list)
|
||||||
|
all_handles.update(handle_list)
|
||||||
|
return total_nr_handles > len(all_handles)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# runTool
|
# runTool
|
||||||
@ -174,6 +195,14 @@ class Check(tool.BatchTool):
|
|||||||
# We only do this for the dbdir backend.
|
# We only do this for the dbdir backend.
|
||||||
if self.db.__class__.__name__ == 'DbBsddb':
|
if self.db.__class__.__name__ == 'DbBsddb':
|
||||||
low_level(self.db)
|
low_level(self.db)
|
||||||
|
if cross_table_duplicates(self.db):
|
||||||
|
Report(uistate, _(
|
||||||
|
"Your family tree contains cross table duplicate handles.\n "
|
||||||
|
"This is bad and can be fixed by making a backup of your\n"
|
||||||
|
"family tree and importing that backup in an empty family\n"
|
||||||
|
"tree. The rest of the checking is skipped, the Check and\n"
|
||||||
|
"Repair tool should be run anew on this new family tree."), cli)
|
||||||
|
return
|
||||||
|
|
||||||
with DbTxn(_("Check Integrity"), self.db, batch=True) as trans:
|
with DbTxn(_("Check Integrity"), self.db, batch=True) as trans:
|
||||||
self.db.disable_signals()
|
self.db.disable_signals()
|
||||||
|
Loading…
Reference in New Issue
Block a user