9744: Tidy up commit_* methods

This commit is contained in:
Nick Hall
2016-10-28 17:07:27 +01:00
parent 9f4cb97512
commit 89cba484c0

View File

@@ -699,15 +699,51 @@ class DBAPI(DbGeneric):
"INSERT INTO name_group (name, grouping) VALUES(?, ?);", "INSERT INTO name_group (name, grouping) VALUES(?, ?);",
[name, grouping]) [name, grouping])
def _commit_base(self, obj, obj_key, trans, change_time):
"""
Commit the specified object to the database, storing the changes as
part of the transaction.
"""
old_data = None
obj.change = int(change_time or time.time())
table = KEY_TO_NAME_MAP[obj_key]
if self.has_handle(obj_key, obj.handle):
old_data = self.get_raw_data(obj_key, obj.handle)
# update the object:
sql = "UPDATE %s SET blob_data = ? WHERE handle = ?" % table
self.dbapi.execute(sql,
[pickle.dumps(obj.serialize()),
obj.handle])
else:
# Insert the object:
sql = ("INSERT INTO %s (handle, blob_data) VALUES (?, ?)") % table
self.dbapi.execute(sql,
[obj.handle,
pickle.dumps(obj.serialize())])
self.update_secondary_values(obj)
if not trans.batch:
self.update_backlinks(obj)
if old_data:
trans.add(obj_key, TXNUPD, obj.handle,
old_data,
obj.serialize())
else:
trans.add(obj_key, TXNADD, obj.handle,
None,
obj.serialize())
return old_data
def commit_person(self, person, trans, change_time=None): def commit_person(self, person, trans, change_time=None):
""" """
Commit the specified Person to the database, storing the changes as Commit the specified Person to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_person = None old_data = self._commit_base(person, PERSON_KEY, trans, change_time)
person.change = int(change_time or time.time())
if self.has_person_handle(person.handle): if old_data:
old_person = self.get_person_from_handle(person.handle) old_person = Person(old_data)
# Update gender statistics if necessary # Update gender statistics if necessary
if (old_person.gender != person.gender if (old_person.gender != person.gender
or (old_person.primary_name.first_name != or (old_person.primary_name.first_name !=
@@ -720,45 +756,10 @@ class DBAPI(DbGeneric):
self._order_by_person_key(old_person)): self._order_by_person_key(old_person)):
self.remove_from_surname_list(old_person) self.remove_from_surname_list(old_person)
self.add_to_surname_list(person, trans.batch) self.add_to_surname_list(person, trans.batch)
given_name, surname = self._get_person_data(person)
# update the person:
self.dbapi.execute("""UPDATE person SET gramps_id = ?,
order_by = ?,
blob_data = ?,
given_name = ?,
surname = ?
WHERE handle = ?;""",
[person.gramps_id,
self._order_by_person_key(person),
pickle.dumps(person.serialize()),
given_name,
surname,
person.handle])
else: else:
self.genderStats.count_person(person) self.genderStats.count_person(person)
self.add_to_surname_list(person, trans.batch) self.add_to_surname_list(person, trans.batch)
given_name, surname = self._get_person_data(person)
# Insert the person:
self.dbapi.execute(
"""INSERT INTO person (handle, order_by, gramps_id, blob_data,
given_name, surname)
VALUES(?, ?, ?, ?, ?, ?);""",
[person.handle,
self._order_by_person_key(person),
person.gramps_id,
pickle.dumps(person.serialize()),
given_name, surname])
self.update_secondary_values(person)
if not trans.batch:
self.update_backlinks(person)
if old_person:
trans.add(PERSON_KEY, TXNUPD, person.handle,
old_person.serialize(),
person.serialize())
else:
trans.add(PERSON_KEY, TXNADD, person.handle,
None,
person.serialize())
# Other misc update tasks: # Other misc update tasks:
self.individual_attributes.update( self.individual_attributes.update(
[str(attr.type) for attr in person.attribute_list [str(attr.type) for attr in person.attribute_list
@@ -792,37 +793,7 @@ class DBAPI(DbGeneric):
Commit the specified Family to the database, storing the changes as Commit the specified Family to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_family = None self._commit_base(family, FAMILY_KEY, trans, change_time)
family.change = int(change_time or time.time())
if self.has_family_handle(family.handle):
old_family = self.get_family_from_handle(family.handle).serialize()
self.dbapi.execute("""UPDATE family SET gramps_id = ?,
father_handle = ?,
mother_handle = ?,
blob_data = ?
WHERE handle = ?;""",
[family.gramps_id,
family.father_handle,
family.mother_handle,
pickle.dumps(family.serialize()),
family.handle])
else:
self.dbapi.execute(
"""INSERT INTO family (handle, gramps_id,
father_handle, mother_handle, blob_data)
VALUES(?, ?, ?, ?, ?);""",
[family.handle,
family.gramps_id,
family.father_handle,
family.mother_handle,
pickle.dumps(family.serialize())])
self.update_secondary_values(family)
if not trans.batch:
self.update_backlinks(family)
db_op = TXNUPD if old_family else TXNADD
trans.add(FAMILY_KEY, db_op, family.handle,
old_family,
family.serialize())
# Misc updates: # Misc updates:
self.family_attributes.update( self.family_attributes.update(
@@ -855,34 +826,8 @@ class DBAPI(DbGeneric):
Commit the specified Citation to the database, storing the changes as Commit the specified Citation to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_citation = None self._commit_base(citation, CITATION_KEY, trans, change_time)
citation.change = int(change_time or time.time())
if self.has_citation_handle(citation.handle):
old_citation = self.get_citation_from_handle(
citation.handle).serialize()
self.dbapi.execute("""UPDATE citation SET gramps_id = ?,
order_by = ?,
blob_data = ?
WHERE handle = ?;""",
[citation.gramps_id,
self._order_by_citation_key(citation),
pickle.dumps(citation.serialize()),
citation.handle])
else:
self.dbapi.execute(
"""INSERT INTO citation (handle, order_by, gramps_id, blob_data)
VALUES(?, ?, ?, ?);""",
[citation.handle,
self._order_by_citation_key(citation),
citation.gramps_id,
pickle.dumps(citation.serialize())])
self.update_secondary_values(citation)
if not trans.batch:
self.update_backlinks(citation)
db_op = TXNUPD if old_citation else TXNADD
trans.add(CITATION_KEY, db_op, citation.handle,
old_citation,
citation.serialize())
# Misc updates: # Misc updates:
attr_list = [] attr_list = []
for mref in citation.media_list: for mref in citation.media_list:
@@ -899,33 +844,8 @@ class DBAPI(DbGeneric):
Commit the specified Source to the database, storing the changes as Commit the specified Source to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_source = None self._commit_base(source, SOURCE_KEY, trans, change_time)
source.change = int(change_time or time.time())
if self.has_source_handle(source.handle):
old_source = self.get_source_from_handle(source.handle).serialize()
self.dbapi.execute("""UPDATE source SET gramps_id = ?,
order_by = ?,
blob_data = ?
WHERE handle = ?;""",
[source.gramps_id,
self._order_by_source_key(source),
pickle.dumps(source.serialize()),
source.handle])
else:
self.dbapi.execute(
"""INSERT INTO source (handle, order_by, gramps_id, blob_data)
VALUES(?, ?, ?, ?);""",
[source.handle,
self._order_by_source_key(source),
source.gramps_id,
pickle.dumps(source.serialize())])
self.update_secondary_values(source)
if not trans.batch:
self.update_backlinks(source)
db_op = TXNUPD if old_source else TXNADD
trans.add(SOURCE_KEY, db_op, source.handle,
old_source,
source.serialize())
# Misc updates: # Misc updates:
self.source_media_types.update( self.source_media_types.update(
[str(ref.media_type) for ref in source.reporef_list [str(ref.media_type) for ref in source.reporef_list
@@ -945,30 +865,8 @@ class DBAPI(DbGeneric):
Commit the specified Repository to the database, storing the changes Commit the specified Repository to the database, storing the changes
as part of the transaction. as part of the transaction.
""" """
old_repository = None self._commit_base(repository, REPOSITORY_KEY, trans, change_time)
repository.change = int(change_time or time.time())
if self.has_repository_handle(repository.handle):
old_repository = self.get_repository_from_handle(
repository.handle).serialize()
self.dbapi.execute("""UPDATE repository SET gramps_id = ?,
blob_data = ?
WHERE handle = ?;""",
[repository.gramps_id,
pickle.dumps(repository.serialize()),
repository.handle])
else:
self.dbapi.execute(
"""INSERT INTO repository (handle, gramps_id, blob_data)
VALUES(?, ?, ?);""",
[repository.handle, repository.gramps_id,
pickle.dumps(repository.serialize())])
self.update_secondary_values(repository)
if not trans.batch:
self.update_backlinks(repository)
db_op = TXNUPD if old_repository else TXNADD
trans.add(REPOSITORY_KEY, db_op, repository.handle,
old_repository,
repository.serialize())
# Misc updates: # Misc updates:
if repository.type.is_custom(): if repository.type.is_custom():
self.repository_types.add(str(repository.type)) self.repository_types.add(str(repository.type))
@@ -981,28 +879,8 @@ class DBAPI(DbGeneric):
Commit the specified Note to the database, storing the changes as part Commit the specified Note to the database, storing the changes as part
of the transaction. of the transaction.
""" """
old_note = None self._commit_base(note, NOTE_KEY, trans, change_time)
note.change = int(change_time or time.time())
if self.has_note_handle(note.handle):
old_note = self.get_note_from_handle(note.handle).serialize()
self.dbapi.execute("""UPDATE note SET gramps_id = ?,
blob_data = ?
WHERE handle = ?;""",
[note.gramps_id,
pickle.dumps(note.serialize()),
note.handle])
else:
self.dbapi.execute(
"""INSERT INTO note (handle, gramps_id, blob_data)
VALUES(?, ?, ?);""",
[note.handle, note.gramps_id, pickle.dumps(note.serialize())])
self.update_secondary_values(note)
if not trans.batch:
self.update_backlinks(note)
db_op = TXNUPD if old_note else TXNADD
trans.add(NOTE_KEY, db_op, note.handle,
old_note,
note.serialize())
# Misc updates: # Misc updates:
if note.type.is_custom(): if note.type.is_custom():
self.note_types.add(str(note.type)) self.note_types.add(str(note.type))
@@ -1012,33 +890,8 @@ class DBAPI(DbGeneric):
Commit the specified Place to the database, storing the changes as Commit the specified Place to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_place = None self._commit_base(place, PLACE_KEY, trans, change_time)
place.change = int(change_time or time.time())
if self.has_place_handle(place.handle):
old_place = self.get_place_from_handle(place.handle).serialize()
self.dbapi.execute("""UPDATE place SET gramps_id = ?,
order_by = ?,
blob_data = ?
WHERE handle = ?;""",
[place.gramps_id,
self._order_by_place_key(place),
pickle.dumps(place.serialize()),
place.handle])
else:
self.dbapi.execute(
"""INSERT INTO place (handle, order_by, gramps_id, blob_data)
VALUES(?, ?, ?, ?);""",
[place.handle,
self._order_by_place_key(place),
place.gramps_id,
pickle.dumps(place.serialize())])
self.update_secondary_values(place)
if not trans.batch:
self.update_backlinks(place)
db_op = TXNUPD if old_place else TXNADD
trans.add(PLACE_KEY, db_op, place.handle,
old_place,
place.serialize())
# Misc updates: # Misc updates:
if place.get_type().is_custom(): if place.get_type().is_custom():
self.place_types.add(str(place.get_type())) self.place_types.add(str(place.get_type()))
@@ -1057,30 +910,8 @@ class DBAPI(DbGeneric):
Commit the specified Event to the database, storing the changes as Commit the specified Event to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
old_event = None self._commit_base(event, EVENT_KEY, trans, change_time)
event.change = int(change_time or time.time())
if self.has_event_handle(event.handle):
old_event = self.get_event_from_handle(event.handle).serialize()
self.dbapi.execute("""UPDATE event SET gramps_id = ?,
blob_data = ?
WHERE handle = ?;""",
[event.gramps_id,
pickle.dumps(event.serialize()),
event.handle])
else:
self.dbapi.execute(
"""INSERT INTO event (handle, gramps_id, blob_data)
VALUES(?, ?, ?);""",
[event.handle,
event.gramps_id,
pickle.dumps(event.serialize())])
self.update_secondary_values(event)
if not trans.batch:
self.update_backlinks(event)
db_op = TXNUPD if old_event else TXNADD
trans.add(EVENT_KEY, db_op, event.handle,
old_event,
event.serialize())
# Misc updates: # Misc updates:
self.event_attributes.update( self.event_attributes.update(
[str(attr.type) for attr in event.attribute_list [str(attr.type) for attr in event.attribute_list
@@ -1098,55 +929,15 @@ class DBAPI(DbGeneric):
Commit the specified Tag to the database, storing the changes as Commit the specified Tag to the database, storing the changes as
part of the transaction. part of the transaction.
""" """
tag.change = int(change_time or time.time()) self._commit_base(tag, TAG_KEY, trans, change_time)
if self.has_tag_handle(tag.handle):
self.dbapi.execute("""UPDATE tag SET blob_data = ?,
order_by = ?
WHERE handle = ?;""",
[pickle.dumps(tag.serialize()),
self._order_by_tag_key(tag.name),
tag.handle])
else:
self.dbapi.execute("""INSERT INTO tag (handle, order_by, blob_data)
VALUES(?, ?, ?);""",
[tag.handle,
self._order_by_tag_key(tag.name),
pickle.dumps(tag.serialize())])
if not trans.batch:
self.update_backlinks(tag)
def commit_media(self, media, trans, change_time=None): def commit_media(self, media, trans, change_time=None):
""" """
Commit the specified Media to the database, storing the changes Commit the specified Media to the database, storing the changes
as part of the transaction. as part of the transaction.
""" """
old_media = None self._commit_base(media, MEDIA_KEY, trans, change_time)
media.change = int(change_time or time.time())
if self.has_media_handle(media.handle):
old_media = self.get_media_from_handle(media.handle).serialize()
self.dbapi.execute("""UPDATE media SET gramps_id = ?,
order_by = ?,
blob_data = ?
WHERE handle = ?;""",
[media.gramps_id,
self._order_by_media_key(media),
pickle.dumps(media.serialize()),
media.handle])
else:
self.dbapi.execute(
"""INSERT INTO media (handle, order_by, gramps_id, blob_data)
VALUES(?, ?, ?, ?);""",
[media.handle,
self._order_by_media_key(media),
media.gramps_id,
pickle.dumps(media.serialize())])
self.update_secondary_values(media)
if not trans.batch:
self.update_backlinks(media)
db_op = TXNUPD if old_media else TXNADD
trans.add(MEDIA_KEY, db_op, media.handle,
old_media,
media.serialize())
# Misc updates: # Misc updates:
self.media_attributes.update( self.media_attributes.update(
[str(attr.type) for attr in media.attribute_list [str(attr.type) for attr in media.attribute_list
@@ -1491,67 +1282,6 @@ class DBAPI(DbGeneric):
# Next, rebuild stats: # Next, rebuild stats:
gstats = self.get_gender_stats() gstats = self.get_gender_stats()
self.genderStats = GenderStats(gstats) self.genderStats = GenderStats(gstats)
# Rebuild all order_by fields:
## Rebuild place order_by:
self.dbapi.execute("""select blob_data from place;""")
row = self.dbapi.fetchone()
while row:
place = Place.create(pickle.loads(row[0]))
order_by = self._order_by_place_key(place)
cur2 = self.dbapi.execute(
"""UPDATE place SET order_by = ? WHERE handle = ?;""",
[order_by, place.handle])
row = self.dbapi.fetchone()
## Rebuild person order_by:
self.dbapi.execute("""select blob_data from person;""")
row = self.dbapi.fetchone()
while row:
person = Person.create(pickle.loads(row[0]))
order_by = self._order_by_person_key(person)
cur2 = self.dbapi.execute(
"""UPDATE person SET order_by = ? WHERE handle = ?;""",
[order_by, person.handle])
row = self.dbapi.fetchone()
## Rebuild citation order_by:
self.dbapi.execute("""select blob_data from citation;""")
row = self.dbapi.fetchone()
while row:
citation = Citation.create(pickle.loads(row[0]))
order_by = self._order_by_citation_key(citation)
cur2 = self.dbapi.execute(
"""UPDATE citation SET order_by = ? WHERE handle = ?;""",
[order_by, citation.handle])
row = self.dbapi.fetchone()
## Rebuild source order_by:
self.dbapi.execute("""select blob_data from source;""")
row = self.dbapi.fetchone()
while row:
source = Source.create(pickle.loads(row[0]))
order_by = self._order_by_source_key(source)
cur2 = self.dbapi.execute(
"""UPDATE source SET order_by = ? WHERE handle = ?;""",
[order_by, source.handle])
row = self.dbapi.fetchone()
## Rebuild tag order_by:
self.dbapi.execute("""select blob_data from tag;""")
row = self.dbapi.fetchone()
while row:
tag = Tag.create(pickle.loads(row[0]))
order_by = self._order_by_tag_key(tag.name)
cur2 = self.dbapi.execute(
"""UPDATE tag SET order_by = ? WHERE handle = ?;""",
[order_by, tag.handle])
row = self.dbapi.fetchone()
## Rebuild media order_by:
self.dbapi.execute("""select blob_data from media;""")
row = self.dbapi.fetchone()
while row:
media = Media.create(pickle.loads(row[0]))
order_by = self._order_by_media_key(media)
cur2 = self.dbapi.execute(
"""UPDATE media SET order_by = ? WHERE handle = ?;""",
[order_by, media.handle])
row = self.dbapi.fetchone()
def has_handle(self, obj_key, handle): def has_handle(self, obj_key, handle):
if isinstance(handle, bytes): if isinstance(handle, bytes):
@@ -1926,28 +1656,54 @@ class DBAPI(DbGeneric):
for item in self.get_table_func(table, "iter_func")(): for item in self.get_table_func(table, "iter_func")():
self.update_secondary_values(item) self.update_secondary_values(item)
def update_secondary_values(self, item): def update_secondary_values(self, obj):
""" """
Given a primary object update its secondary field values Given a primary object update its secondary field values
in the database. in the database.
Does not commit. Does not commit.
""" """
table = item.__class__.__name__ table = obj.__class__.__name__
fields = self.get_table_func(table, "class_func").get_secondary_fields() fields = self.get_table_func(table, "class_func").get_secondary_fields()
fields = [field for (field, direction) in fields] fields = [field for (field, direction) in fields]
sets = [] sets = []
values = [] values = []
for field in fields: for field in fields:
value = item.get_field(field, self, ignore_errors=True) value = obj.get_field(field, self, ignore_errors=True)
field = self._hash_name(item.__class__.__name__, field) field = self._hash_name(obj.__class__.__name__, field)
sets.append("%s = ?" % field) sets.append("%s = ?" % field)
values.append(value) values.append(value)
# Derived fields
if table == 'Person':
given_name, surname = self._get_person_data(obj)
sets.append("given_name = ?")
values.append(given_name)
sets.append("surname = ?")
values.append(surname)
sets.append("order_by = ?")
values.append(self._order_by_person_key(obj))
if table == 'Place':
sets.append("order_by = ?")
values.append(self._order_by_place_key(obj))
if table == 'Source':
sets.append("order_by = ?")
values.append(self._order_by_source_key(obj))
if table == 'Citation':
sets.append("order_by = ?")
values.append(self._order_by_citation_key(obj))
if table == 'Media':
sets.append("order_by = ?")
values.append(self._order_by_media_key(obj))
if table == 'Tag':
sets.append("order_by = ?")
values.append(self._order_by_tag_key(obj.name))
if len(values) > 0: if len(values) > 0:
table_name = table.lower() table_name = table.lower()
self.dbapi.execute("UPDATE %s SET %s where handle = ?;" self.dbapi.execute("UPDATE %s SET %s where handle = ?;"
% (table_name, ", ".join(sets)), % (table_name, ", ".join(sets)),
self._sql_cast_list(table, sets, values) self._sql_cast_list(table, sets, values)
+ [item.handle]) + [obj.handle])
def _sql_cast_list(self, table, fields, values): def _sql_cast_list(self, table, fields, values):
""" """