Working in remove in dictionaryDB; fix for Dictionary Cursors
This commit is contained in:
parent
90eda9d89c
commit
2fb9f2ffa0
@ -36,14 +36,16 @@ import time
|
||||
import re
|
||||
from . import DbReadBase, DbWriteBase, DbTxn
|
||||
from . import (PERSON_KEY,
|
||||
FAMILY_KEY,
|
||||
CITATION_KEY,
|
||||
SOURCE_KEY,
|
||||
EVENT_KEY,
|
||||
MEDIA_KEY,
|
||||
PLACE_KEY,
|
||||
REPOSITORY_KEY,
|
||||
NOTE_KEY)
|
||||
FAMILY_KEY,
|
||||
CITATION_KEY,
|
||||
SOURCE_KEY,
|
||||
EVENT_KEY,
|
||||
MEDIA_KEY,
|
||||
PLACE_KEY,
|
||||
REPOSITORY_KEY,
|
||||
NOTE_KEY,
|
||||
TAG_KEY)
|
||||
|
||||
from ..utils.id import create_id
|
||||
from ..lib.researcher import Researcher
|
||||
from ..lib.mediaobj import MediaObject
|
||||
@ -707,34 +709,34 @@ class DictionaryDb(DbWriteBase, DbReadBase):
|
||||
return len(self.repository_map)
|
||||
|
||||
def get_place_cursor(self):
|
||||
return Cursor(self.place_map, self.get_raw_place_data).iter()
|
||||
return Cursor(self.place_map, self.get_raw_place_data)
|
||||
|
||||
def get_person_cursor(self):
|
||||
return Cursor(self.person_map, self.get_raw_person_data).iter()
|
||||
return Cursor(self.person_map, self.get_raw_person_data)
|
||||
|
||||
def get_family_cursor(self):
|
||||
return Cursor(self.family_map, self.get_raw_family_data).iter()
|
||||
return Cursor(self.family_map, self.get_raw_family_data)
|
||||
|
||||
def get_event_cursor(self):
|
||||
return Cursor(self.event_map, self.get_raw_event_data).iter()
|
||||
return Cursor(self.event_map, self.get_raw_event_data)
|
||||
|
||||
def get_note_cursor(self):
|
||||
return Cursor(self.note_map, self.get_raw_note_data).iter()
|
||||
return Cursor(self.note_map, self.get_raw_note_data)
|
||||
|
||||
def get_tag_cursor(self):
|
||||
return Cursor(self.tag_map, self.get_raw_tag_data).iter()
|
||||
return Cursor(self.tag_map, self.get_raw_tag_data)
|
||||
|
||||
def get_repository_cursor(self):
|
||||
return Cursor(self.repository_map, self.get_raw_repository_data).iter()
|
||||
return Cursor(self.repository_map, self.get_raw_repository_data)
|
||||
|
||||
def get_media_cursor(self):
|
||||
return Cursor(self.media_map, self.get_raw_object_data).iter()
|
||||
return Cursor(self.media_map, self.get_raw_object_data)
|
||||
|
||||
def get_citation_cursor(self):
|
||||
return Cursor(self.citation_map, self.get_raw_citation_data).iter()
|
||||
return Cursor(self.citation_map, self.get_raw_citation_data)
|
||||
|
||||
def get_source_cursor(self):
|
||||
return Cursor(self.source_map, self.get_raw_source_data).iter()
|
||||
return Cursor(self.source_map, self.get_raw_source_data)
|
||||
|
||||
def has_gramps_id(self, obj_key, gramps_id):
|
||||
key2table = {
|
||||
@ -1031,3 +1033,179 @@ class DictionaryDb(DbWriteBase, DbReadBase):
|
||||
return self._tables[table_name]["gramps_id_func"](gramps_id)
|
||||
return None
|
||||
|
||||
def remove_person(self, handle, transaction):
|
||||
"""
|
||||
Remove the Person specified by the database handle from the database,
|
||||
preserving the change in the passed transaction.
|
||||
"""
|
||||
|
||||
if self.readonly or not handle:
|
||||
return
|
||||
person = self.get_person_from_handle(handle)
|
||||
#self.genderStats.uncount_person (person)
|
||||
#self.remove_from_surname_list(person)
|
||||
if isinstance(handle, UNITYPE):
|
||||
handle = handle.encode('utf-8')
|
||||
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(handle, txn=self.txn)
|
||||
transaction.add(PERSON_KEY, TXNDEL, handle, person.serialize(), None)
|
||||
|
||||
def remove_source(self, handle, transaction):
|
||||
"""
|
||||
Remove the Source specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.source_map,
|
||||
SOURCE_KEY)
|
||||
|
||||
def remove_citation(self, handle, transaction):
|
||||
"""
|
||||
Remove the Citation specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.citation_map,
|
||||
CITATION_KEY)
|
||||
|
||||
def remove_event(self, handle, transaction):
|
||||
"""
|
||||
Remove the Event specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.event_map,
|
||||
EVENT_KEY)
|
||||
|
||||
def remove_object(self, handle, transaction):
|
||||
"""
|
||||
Remove the MediaObjectPerson specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.media_map,
|
||||
MEDIA_KEY)
|
||||
|
||||
def remove_place(self, handle, transaction):
|
||||
"""
|
||||
Remove the Place specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.place_map,
|
||||
PLACE_KEY)
|
||||
|
||||
def remove_family(self, handle, transaction):
|
||||
"""
|
||||
Remove the Family specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.family_map,
|
||||
FAMILY_KEY)
|
||||
|
||||
def remove_repository(self, handle, transaction):
|
||||
"""
|
||||
Remove the Repository specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.repository_map,
|
||||
REPOSITORY_KEY)
|
||||
|
||||
def remove_note(self, handle, transaction):
|
||||
"""
|
||||
Remove the Note specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.note_map,
|
||||
NOTE_KEY)
|
||||
|
||||
def remove_tag(self, handle, transaction):
|
||||
"""
|
||||
Remove the Tag specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.tag_map,
|
||||
TAG_KEY)
|
||||
|
||||
def __do_remove(self, handle, transaction, data_map, key):
|
||||
if self.readonly or not handle:
|
||||
return
|
||||
|
||||
if isinstance(handle, UNITYPE):
|
||||
handle = handle.encode('utf-8')
|
||||
if transaction.batch:
|
||||
with BSDDBTxn(self.env, data_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)
|
||||
old_data = data_map.get(handle, txn=self.txn)
|
||||
data_map.delete(handle, txn=self.txn)
|
||||
transaction.add(key, TXNDEL, handle, old_data, None)
|
||||
|
||||
def delete_primary_from_reference_map(self, handle, transaction, txn=None):
|
||||
"""
|
||||
Remove all references to the primary object from the reference_map.
|
||||
handle should be utf-8
|
||||
"""
|
||||
primary_cur = self.get_reference_map_primary_cursor()
|
||||
|
||||
try:
|
||||
ret = primary_cur.set(handle)
|
||||
except:
|
||||
ret = None
|
||||
|
||||
remove_list = set()
|
||||
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))
|
||||
|
||||
# so we need the second tuple give us a reference that we can
|
||||
# combine with the primary_handle to get the main key.
|
||||
if sys.version_info[0] < 3:
|
||||
#handle should be in python 2 str
|
||||
main_key = (handle, pickle.loads(data)[1][1])
|
||||
else:
|
||||
#python 3 work internally with unicode
|
||||
main_key = (handle.decode('utf-8'), pickle.loads(data)[1][1])
|
||||
|
||||
# The trick is not to remove while inside the cursor,
|
||||
# but collect them all and remove after the cursor is closed
|
||||
remove_list.add(main_key)
|
||||
|
||||
ret = primary_cur.next_dup()
|
||||
|
||||
primary_cur.close()
|
||||
|
||||
# Now that the cursor is closed, we can remove things
|
||||
for main_key in remove_list:
|
||||
self.__remove_reference(main_key, transaction, txn)
|
||||
|
||||
def __remove_reference(self, key, transaction, txn):
|
||||
"""
|
||||
Remove the reference specified by the key, preserving the change in
|
||||
the passed transaction.
|
||||
"""
|
||||
if isinstance(key, tuple):
|
||||
#create a byte string key, first validity check in python 3!
|
||||
for val in key:
|
||||
if sys.version_info[0] >= 3 and isinstance(val, bytes):
|
||||
raise DbError(_('An attempt is made to save a reference key '
|
||||
'which is partly bytecode, this is not allowed.\n'
|
||||
'Key is %s') % str(key))
|
||||
key = str(key)
|
||||
if isinstance(key, UNITYPE):
|
||||
key = key.encode('utf-8')
|
||||
if not self.readonly:
|
||||
if not transaction.batch:
|
||||
old_data = self.reference_map.get(key, txn=txn)
|
||||
transaction.add(REFERENCE_KEY, TXNDEL, key, old_data, None)
|
||||
#transaction.reference_del.append(str(key))
|
||||
self.reference_map.delete(key, txn=txn)
|
||||
|
@ -550,6 +550,8 @@ class Struct(object):
|
||||
new_obj = from_struct(self.struct)
|
||||
name, handle = self.struct["_class"], self.struct["handle"]
|
||||
old_obj = self.db.get_from_name_and_handle(name, handle)
|
||||
# FIXME: this needs to find the closest _class before each diff
|
||||
# and commit that, not the topmost _class
|
||||
if old_obj:
|
||||
commit_func = self.db._tables[name]["commit_func"]
|
||||
commit_func(new_obj, trans)
|
||||
|
Loading…
Reference in New Issue
Block a user