diff --git a/ChangeLog b/ChangeLog index b41a769db..ab1520ee8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-01-19 Alex Roitman + * src/GrampsDb/_GrampsInMemDB.py: Support the cached surname list. + * src/GrampsDb/_GrampsBSDDB.py: Support the cached surname list. + * src/GrampsDb/_GrampsDbBase.py: Support the cached surname list. + 2007-01-18 Don Allingham * src/DataViews/Utils.py: add profile function diff --git a/src/GrampsDb/_GrampsBSDDB.py b/src/GrampsDb/_GrampsBSDDB.py index 2ef2c51a5..911d0dba6 100644 --- a/src/GrampsDb/_GrampsBSDDB.py +++ b/src/GrampsDb/_GrampsBSDDB.py @@ -60,7 +60,7 @@ import Errors from BasicUtils import UpdateCallback _MINVERSION = 5 -_DBVERSION = 11 +_DBVERSION = 12 def find_surname(key,data): return str(data[3][5]) @@ -513,6 +513,8 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): self.url_types = set(self.metadata.get('url_types',default=[])) self.media_attributes = set(self.metadata.get('mattr_names', default=[])) + # surname list + self.surname_list = self.metadata.get('surname_list',default=[]) def connect_secondary(self): """ @@ -1033,6 +1035,9 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): txn=the_txn) self.metadata.put('mattr_names',list(self.media_attributes), txn=the_txn) + # name display formats + self.metadata.put('surname_list',self.surname_list,txn=the_txn) + if self.UseTXN: the_txn.commit() else: @@ -1193,11 +1198,19 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): self.name_group.sync() self.emit('person-rebuild') - def get_surname_list(self): - vals = [ (locale.strxfrm(unicode(val)),unicode(val)) - for val in set(self.surnames.keys()) ] - vals.sort() - return [item[1] for item in vals] + def build_surname_list(self): + self.surname_list = list(set(self.surnames.keys())) + self.sort_surname_list() + + def remove_from_surname_list(self,person): + """ + Check whether there are persons with the same surname left in + the database. If not then we need to remove the name from the list. + The function must be overridden in the derived class. + """ + name = str(person.get_primary_name().get_surname()) + if self.surnames.keys().count(name) > 1: + self.surname_list.remove(unicode(name)) def _get_obj_from_gramps_id(self,val,tbl,class_init,prim_tbl): if tbl.has_key(str(val)): @@ -1370,6 +1383,7 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): self.surnames.close() junk = db.DB(self.env) junk.remove(self.full_name,"surnames") + self.surnames = None self.reference_map_referenced_map.close() junk = db.DB(self.env) @@ -1424,6 +1438,9 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): db.DB_BTREE,flags=open_flags) self.reference_map.associate(self.reference_map_referenced_map, find_referenced_handle,open_flags) + + self.build_surname_list() + self.txn = None def undo(self,update_history=True): @@ -1494,6 +1511,8 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): self.gramps_upgrade_10() if version < 11: self.gramps_upgrade_11() + if version < 12: + self.gramps_upgrade_12() print "Upgrade time:", int(time.time()-t), "seconds" def gramps_upgrade_6(self): @@ -1588,7 +1607,7 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): to commit the objects, because the unpickled objects will lack some attributes that are necessary for serialization on commit. """ - print "Upgrading to DB version 11 -- this may take a while" + print "Upgrading to DB version 12 -- this may take a while" # The very very first thing is to check for duplicates in the # primary tables and remove them. self.set_total(7) @@ -1974,7 +1993,7 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): self.commit_media_object(media_object,trans) self.update() - self.transaction_commit(trans,"Upgrade to DB version 9") + self.transaction_commit(trans,"Upgrade to DB version 12") # Close secodnary index self.reference_map_primary_map.close() @@ -1983,13 +2002,13 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): the_txn = self.env.txn_begin() else: the_txn = None - self.metadata.put('version',11,txn=the_txn) + self.metadata.put('version',12,txn=the_txn) if self.UseTXN: the_txn.commit() else: self.metadata.sync() - print "Done upgrading to DB version 11" + print "Done upgrading to DB version 12" def gramps_upgrade_10(self): print "Upgrading to DB version 10..." @@ -2243,6 +2262,35 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback): print "Done upgrading to DB version 11" + def gramps_upgrade_12(self): + print "Upgrading to DB version 12..." + # Hook up surnames + table_flags = self.open_flags() + self.surnames = db.DB(self.env) + self.surnames.set_flags(db.DB_DUP|db.DB_DUPSORT) + self.surnames.open(self.full_name, "surnames", db.DB_BTREE, + flags=table_flags) + self.person_map.associate(self.surnames, find_surname, table_flags) + + self.build_surname_list() + + # Close so that we can open it again later + self.surnames.close() + + if self.UseTXN: + # Separate transaction to save metadata + the_txn = self.env.txn_begin() + else: + the_txn = None + self.metadata.put('version', 12, txn=the_txn) + if self.UseTXN: + the_txn.commit() + else: + self.metadata.sync() + + print "Done upgrading to DB version 12" + + class BdbTransaction(Transaction): def __init__(self,msg,db,batch=False,no_magic=False): Transaction.__init__(self,msg,db,batch,no_magic) diff --git a/src/GrampsDb/_GrampsDbBase.py b/src/GrampsDb/_GrampsDbBase.py index fc253da3a..41241e62f 100644 --- a/src/GrampsDb/_GrampsDbBase.py +++ b/src/GrampsDb/_GrampsDbBase.py @@ -304,6 +304,7 @@ class GrampsDbBase(GrampsDBCallback): self.media_bookmarks = GrampsDbBookmarks() self.path = "" self.name_group = {} + self.surname_list = [] def rebuild_secondary(self, callback): pass @@ -472,8 +473,11 @@ class GrampsDbBase(GrampsDBCallback): old_data[3][2]!= person.primary_name.first_name): self.genderStats.uncount_person(old_person) self.genderStats.count_person(person) + self.remove_from_surname_list(old_person) + self.add_to_surname_list(person,transaction.batch) else: self.genderStats.count_person(person) + self.add_to_surname_list(person,transaction.batch) self.individual_attributes.update( [str(attr.type) for attr in person.attribute_list @@ -1359,11 +1363,14 @@ class GrampsDbBase(GrampsDBCallback): """ Commits the transaction to the assocated UNDO database. """ - if self.__LOG_ALL: log.debug("%s: Transaction commit '%s'\n" % (self.__class__.__name__, str(msg))) - if not len(transaction) or self.readonly: + if self.readonly: + return + if not len(transaction): + if self.surnames != None: + self.build_surname_list() return transaction.set_description(msg) transaction.timestamp = time.time() @@ -1584,7 +1591,34 @@ class GrampsDbBase(GrampsDBCallback): def get_surname_list(self): """ - Returns the list of surnames contained within the database. + Returns the list of locale-sorted surnames contained in the database. + """ + return self.surname_list + + def build_surname_list(self): + """ + Builds the list of locale-sorted surnames contained in the database. + The function must be overridden in the derived class. + """ + assert False, "Needs to be overridden in the derived class" + + def sort_surname_list(self): + vals = [(locale.strxfrm(item),item) for item in self.surname_list] + vals.sort() + self.surname_list = [item[1] for item in vals] + + def add_to_surname_list(self,person,batch_transaction): + if batch_transaction: + return + name = unicode(person.get_primary_name().get_surname()) + if name not in self.surname_list: + self.surname_list.append(name) + self.sort_surname_list() + + def remove_from_surname_list(self,person): + """ + Check whether there are persons with the same surname left in + the database. If not then we need to remove the name from the list. The function must be overridden in the derived class. """ assert False, "Needs to be overridden in the derived class" @@ -1733,6 +1767,7 @@ class GrampsDbBase(GrampsDBCallback): self._delete_primary_from_reference_map(handle, transaction) person = self.get_person_from_handle(handle) self.genderStats.uncount_person (person) + self.remove_from_surname_list(person) if transaction.batch: self._del_person(handle) else: diff --git a/src/GrampsDb/_GrampsInMemDB.py b/src/GrampsDb/_GrampsInMemDB.py index 31bfc0ae1..51f132ff7 100644 --- a/src/GrampsDb/_GrampsInMemDB.py +++ b/src/GrampsDb/_GrampsInMemDB.py @@ -138,14 +138,30 @@ class GrampsInMemDB(GrampsDbBase): else: self.name_group[name] = group - def get_surname_list(self): - a = {} + def build_surname_list(self): + a = set() for person_id in iter(self.person_map): p = self.get_person_from_handle(person_id) - a[p.get_primary_name().get_group_as()] = 1 - vals = a.keys() - vals.sort() - return vals + a.add(unicode(p.get_primary_name().get_surname())) + self.surname_list = list(a) + self.sort_surname_list() + + def remove_from_surname_list(self,person): + """ + Check whether there are persons with the same surname left in + the database. If not then we need to remove the name from the list. + The function must be overridden in the derived class. + """ + name = str(person.get_primary_name().get_surname()) + count = 0 + for person_id in iter(self.person_map): + p = self.get_person_from_handle(person_id) + pn = str(p.get_primary_name().get_surname()) + if pn == name: + count += 1 + if count > 1: + self.surname_list.remove(unicode(name)) + break def _del_person(self,handle): person = self.get_person_from_handle(str(handle))