Dbapi: Fix for broken 'backlinks' after a delete.

Fixes #10221
This commit is contained in:
prculley 2017-10-13 15:27:49 -05:00 committed by Nick Hall
parent 455d56db1b
commit 97db4cf64e

View File

@ -35,7 +35,7 @@ import logging
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.gen.db.dbconst import (DBLOGNAME, DBBACKEND, KEY_TO_NAME_MAP, from gramps.gen.db.dbconst import (DBLOGNAME, DBBACKEND, KEY_TO_NAME_MAP,
TXNADD, TXNUPD, TXNDEL, KEY_TO_CLASS_MAP, TXNADD, TXNUPD, TXNDEL,
PERSON_KEY, FAMILY_KEY, SOURCE_KEY, PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
EVENT_KEY, MEDIA_KEY, PLACE_KEY, NOTE_KEY, EVENT_KEY, MEDIA_KEY, PLACE_KEY, NOTE_KEY,
TAG_KEY, CITATION_KEY, REPOSITORY_KEY, TAG_KEY, CITATION_KEY, REPOSITORY_KEY,
@ -664,12 +664,32 @@ class DBAPI(DbGeneric):
return return
if self._has_handle(obj_key, handle): if self._has_handle(obj_key, handle):
data = self._get_raw_data(obj_key, handle) data = self._get_raw_data(obj_key, handle)
obj_class = KEY_TO_CLASS_MAP[obj_key]
self._remove_backlinks(obj_class, handle, transaction)
table = KEY_TO_NAME_MAP[obj_key] table = KEY_TO_NAME_MAP[obj_key]
sql = "DELETE FROM %s WHERE handle = ?" % table sql = "DELETE FROM %s WHERE handle = ?" % table
self.dbapi.execute(sql, [handle]) self.dbapi.execute(sql, [handle])
if not transaction.batch: if not transaction.batch:
transaction.add(obj_key, TXNDEL, handle, data, None) transaction.add(obj_key, TXNDEL, handle, data, None)
def _remove_backlinks(self, obj_class, obj_handle, transaction):
"""
Removes all references from this object (backlinks).
"""
# collect backlinks from this object for undo
self.dbapi.execute("SELECT ref_class, ref_handle " +
"FROM reference WHERE obj_handle = ?", [obj_handle])
rows = self.dbapi.fetchall()
# Now, delete backlinks from this object:
self.dbapi.execute("DELETE FROM reference WHERE obj_handle = ?;",
[obj_handle])
# Add old references to the transaction
if not transaction.batch:
for (ref_class_name, ref_handle) in rows:
key = (obj_handle, ref_handle)
old_data = (obj_handle, obj_class, ref_handle, ref_class_name)
transaction.add(REFERENCE_KEY, TXNDEL, key, old_data, None)
def find_backlink_handles(self, handle, include_classes=None): def find_backlink_handles(self, handle, include_classes=None):
""" """
Find all objects that hold a reference to the object handle. Find all objects that hold a reference to the object handle.