9465: DB-API: duplicate note ID
This commit is contained in:
parent
a70f7eb58f
commit
55d2141476
@ -81,6 +81,27 @@ def touch(fname, mode=0o666, dir_fd=None, **kwargs):
|
||||
os.utime(f.fileno() if os.utime in os.supports_fd else fname,
|
||||
dir_fd=None if os.supports_fd else dir_fd, **kwargs)
|
||||
|
||||
class IDMapTransaction:
|
||||
"""
|
||||
Provide compatibility with BSDDB. A class to provide a lookup
|
||||
to see if a gramps_id has been inserted.
|
||||
"""
|
||||
def __init__(self, table_name, database):
|
||||
"""
|
||||
Takes a table_name and database.
|
||||
Provides .get(b"gramps_id")
|
||||
"""
|
||||
self.table_name = table_name
|
||||
self.database = database
|
||||
|
||||
def get(self, bkey, default=None, txn=None, **kwargs):
|
||||
"""
|
||||
Returns True if bkey (binary gramps_id) is in database.
|
||||
"""
|
||||
skey = bkey.decode("utf-8")
|
||||
return self.database.get_table_func(self.table_name,
|
||||
"has_gramps_id_func")(skey)
|
||||
|
||||
class DbGenericUndo(DbUndo):
|
||||
def __init__(self, grampsdb, path):
|
||||
super(DbGenericUndo, self).__init__(grampsdb)
|
||||
@ -259,7 +280,8 @@ class Map:
|
||||
self.keys_func = keys_func
|
||||
self.contains_func = contains_func
|
||||
self.raw_func = raw_func
|
||||
self.txn = DbGenericTxn("Dummy transaction", db=self.table.db, batch=True)
|
||||
self.txn = DbGenericTxn("Dummy transaction",
|
||||
db=self.table.db, batch=True)
|
||||
|
||||
def keys(self):
|
||||
return self.table.funcs[self.keys_func]()
|
||||
@ -393,25 +415,17 @@ class Bookmarks:
|
||||
def close(self):
|
||||
del self.handles
|
||||
|
||||
|
||||
class DbGenericTxn(DbTxn):
|
||||
"""
|
||||
Generic Transaction.
|
||||
"""
|
||||
def __init__(self, message, db, batch=False):
|
||||
"""
|
||||
Placeholder. This can probably be removed once it is
|
||||
known that it is not needed.
|
||||
"""
|
||||
DbTxn.__init__(self, message, db, batch)
|
||||
|
||||
def get(self, key, default=None, txn=None, **kwargs):
|
||||
"""
|
||||
Returns the data object associated with key
|
||||
"""
|
||||
if txn and key in txn:
|
||||
return txn[key]
|
||||
else:
|
||||
return None
|
||||
|
||||
def put(self, handle, new_data, txn):
|
||||
"""
|
||||
"""
|
||||
txn[handle] = new_data
|
||||
|
||||
class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
"""
|
||||
A Gramps Database Backend. This replicates the grampsdb functions.
|
||||
@ -653,15 +667,15 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
self.set_note_id_prefix('N%04d')
|
||||
# ----------------------------------
|
||||
self.undodb = None
|
||||
self.id_trans = DbGenericTxn("ID Transaction", self)
|
||||
self.fid_trans = DbGenericTxn("FID Transaction", self)
|
||||
self.pid_trans = DbGenericTxn("PID Transaction", self)
|
||||
self.cid_trans = DbGenericTxn("CID Transaction", self)
|
||||
self.sid_trans = DbGenericTxn("SID Transaction", self)
|
||||
self.oid_trans = DbGenericTxn("OID Transaction", self)
|
||||
self.rid_trans = DbGenericTxn("RID Transaction", self)
|
||||
self.nid_trans = DbGenericTxn("NID Transaction", self)
|
||||
self.eid_trans = DbGenericTxn("EID Transaction", self)
|
||||
self.id_trans = IDMapTransaction("Person", self)
|
||||
self.fid_trans = IDMapTransaction("Family", self)
|
||||
self.pid_trans = IDMapTransaction("Place", self)
|
||||
self.cid_trans = IDMapTransaction("Citation", self)
|
||||
self.sid_trans = IDMapTransaction("Source", self)
|
||||
self.oid_trans = IDMapTransaction("Media", self)
|
||||
self.rid_trans = IDMapTransaction("Repository", self)
|
||||
self.nid_trans = IDMapTransaction("Note", self)
|
||||
self.eid_trans = IDMapTransaction("Event", self)
|
||||
self.cmap_index = 0
|
||||
self.smap_index = 0
|
||||
self.emap_index = 0
|
||||
@ -2185,4 +2199,3 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
return ast.literal_eval(version)
|
||||
else:
|
||||
return (0, 0, 0)
|
||||
|
||||
|
@ -179,70 +179,3 @@ class DbTxn(defaultdict):
|
||||
if self.first is None or self.last is None:
|
||||
return 0
|
||||
return self.last - self.first + 1
|
||||
|
||||
# Test functions
|
||||
|
||||
def testtxn():
|
||||
"""
|
||||
Test suite
|
||||
"""
|
||||
class FakeMap(dict):
|
||||
"""Fake database map with just two methods"""
|
||||
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 FakeDb:
|
||||
"""Fake gramps database"""
|
||||
def __init__(self):
|
||||
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 FakeCommitDb(list):
|
||||
""" Fake commit database"""
|
||||
def commit(self, transaction):
|
||||
"""commit transaction to undo db"""
|
||||
pass
|
||||
def undo(self):
|
||||
"""undo last transaction"""
|
||||
pass
|
||||
|
||||
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)
|
||||
print(trans.get_description())
|
||||
print(trans.set_description("new text"))
|
||||
print(trans.get_description())
|
||||
for i in trans.get_recnos():
|
||||
print(trans.get_record(i))
|
||||
print(list(trans.get_recnos()))
|
||||
print(list(trans.get_recnos(reverse=True)))
|
||||
print(grampsdb.person_map)
|
||||
|
||||
if __name__ == '__main__':
|
||||
testtxn()
|
||||
|
Loading…
Reference in New Issue
Block a user