From 1587cb8ad16fdb015093bf0cc4ad4c8657b1284b Mon Sep 17 00:00:00 2001 From: Gerald Britton Date: Mon, 31 Aug 2009 18:42:29 +0000 Subject: [PATCH] Implement restructured database objects svn: r13139 --- src/DbState.py | 10 +- src/GrampsDbUtils/_Backup.py | 2 +- src/UndoHistory.py | 44 +- src/gen/db/__init__.py | 6 +- src/gen/db/base.py | 1761 ++++++---------------------- src/gen/db/dbconst.py | 44 + src/gen/db/write.py | 6 +- src/gui/viewmanager.py | 2 +- src/plugins/import/ImportGedcom.py | 6 + src/plugins/import/ImportGrdb.py | 32 +- src/plugins/import/ImportXml.py | 5 + src/plugins/tool/Check.py | 4 +- 12 files changed, 494 insertions(+), 1428 deletions(-) diff --git a/src/DbState.py b/src/DbState.py index afe909027..313f321e3 100644 --- a/src/DbState.py +++ b/src/DbState.py @@ -22,7 +22,7 @@ Provide the database state class """ -from gen.db import GrampsDbBase +from gen.db import GrampsDbRead from gen.utils import Callback import Config @@ -32,18 +32,18 @@ class DbState(Callback): """ __signals__ = { - 'database-changed' : (GrampsDbBase, ), + 'database-changed' : (GrampsDbRead, ), 'active-changed' : (str, ), 'no-database' : None, } def __init__(self): """ - Initalize the state with an empty (and useless) GrampsDbBase. This is + Initalize the state with an empty (and useless) GrampsDbRead. This is just a place holder until a real DB is assigned. """ Callback.__init__(self) - self.db = GrampsDbBase() + self.db = GrampsDbRead() self.open = False self.active = None self.sighndl = None @@ -115,7 +115,7 @@ class DbState(Callback): Closes the database without a new database """ self.db.close() - self.db = GrampsDbBase() + self.db = GrampsDbRead() self.db.db_is_open = False self.active = None self.open = False diff --git a/src/GrampsDbUtils/_Backup.py b/src/GrampsDbUtils/_Backup.py index 481266028..e4632f267 100644 --- a/src/GrampsDbUtils/_Backup.py +++ b/src/GrampsDbUtils/_Backup.py @@ -58,7 +58,7 @@ from gettext import gettext as _ # #------------------------------------------------------------------------ from QuestionDialog import ErrorDialog -from gen.db.dbdir import FAMILY_TBL, PLACES_TBL, SOURCES_TBL, MEDIA_TBL, \ +from gen.db.write import FAMILY_TBL, PLACES_TBL, SOURCES_TBL, MEDIA_TBL, \ EVENTS_TBL, PERSON_TBL, REPO_TBL, NOTE_TBL, META #------------------------------------------------------------------------ diff --git a/src/UndoHistory.py b/src/UndoHistory.py index 310db26b5..b52f19ee4 100644 --- a/src/UndoHistory.py +++ b/src/UndoHistory.py @@ -63,6 +63,7 @@ class UndoHistory(ManagedWindow.ManagedWindow): self.title = _("Undo History") ManagedWindow.ManagedWindow.__init__(self,uistate,[],self.__class__) self.db = dbstate.db + self.undodb = self.db.undodb self.dbstate = dbstate window = gtk.Dialog("",uistate.window, @@ -113,22 +114,22 @@ class UndoHistory(ManagedWindow.ManagedWindow): if not node: return path = self.model.get_path(node) - - start = min(path[0],self.db.undoindex+1) - end = max(path[0],self.db.undoindex+1) + + start = min(path[0],self.undodb.undoindex+1) + end = max(path[0],self.undodb.undoindex+1) self._paint_rows(0,len(self.model)-1,False) self._paint_rows(start,end,True) - if path[0] < self.db.undoindex+1: + if path[0] < self.undodb.undoindex+1: self.redo_button.set_sensitive(False) - self.undo_button.set_sensitive(self.db.undo_available()) - if path[0] > self.db.undoindex+1: + self.undo_button.set_sensitive(self.undodb.undo_available()) + if path[0] > self.undodb.undoindex+1: self.undo_button.set_sensitive(False) - self.redo_button.set_sensitive(self.db.redo_available()) - if path[0] == self.db.undoindex+1: - self.undo_button.set_sensitive(self.db.undo_available()) - self.redo_button.set_sensitive(self.db.redo_available()) + self.redo_button.set_sensitive(self.undodb.redo_available()) + if path[0] == self.undodb.undoindex+1: + self.undo_button.set_sensitive(self.undodb.undo_available()) + self.redo_button.set_sensitive(self.undodb.redo_available()) def _paint_rows(self,start,end,selected=False): if selected: @@ -149,7 +150,7 @@ class UndoHistory(ManagedWindow.ManagedWindow): if not node: return path = self.model.get_path(node) - nsteps = path[0]-self.db.undoindex-1 + nsteps = path[0]-self.undodb.undoindex-1 if nsteps == 0: self._move(-1) else: @@ -159,7 +160,7 @@ class UndoHistory(ManagedWindow.ManagedWindow): if not node: return path = self.model.get_path(node) - nsteps = path[0]-self.db.undoindex-1 + nsteps = path[0]-self.undodb.undoindex-1 if nsteps == 0: self._move(1) else: @@ -180,9 +181,8 @@ class UndoHistory(ManagedWindow.ManagedWindow): self.window) def clear(self): - self.db.undoindex = -1 - self.db.translist = [None] * len(self.db.translist) - self.db.abort_possible = False + self.undodb.clear() + self.undodb.abort_possible = False self.update() if self.db.undo_callback: self.db.undo_callback(None) @@ -203,30 +203,30 @@ class UndoHistory(ManagedWindow.ManagedWindow): def _update_ui(self): self._paint_rows(0,len(self.model)-1,False) - self.undo_button.set_sensitive(self.db.undo_available()) - self.redo_button.set_sensitive(self.db.redo_available()) + self.undo_button.set_sensitive(self.undodb.undo_available()) + self.redo_button.set_sensitive(self.undodb.redo_available()) self.clear_button.set_sensitive( - self.db.undo_available() or self.db.redo_available() ) + self.undodb.undo_available() or self.undodb.redo_available() ) def _build_model(self): self.model.clear() fg = bg = None - if self.db.undo_history_timestamp: + if self.undodb.undo_history_timestamp: if self.db.abort_possible: mod_text = _('Database opened') else: mod_text = _('History cleared') - time_text = time.ctime(self.db.undo_history_timestamp) + time_text = time.ctime(self.undodb.undo_history_timestamp) self.model.append(row=[time_text,mod_text,fg,bg]) # Get the not-None portion of transaction list - translist = [item for item in self.db.translist if item] + translist = [item for item in self.undodb.translist if item] for transaction in translist: time_text = time.ctime(transaction.timestamp) mod_text = transaction.get_description() self.model.append(row=[time_text,mod_text,fg,bg]) - path = (self.db.undoindex+1,) + path = (self.undodb.undoindex+1,) self.selection.select_path(path) def update(self): diff --git a/src/gen/db/__init__.py b/src/gen/db/__init__.py index 028c9de14..6b2f5e048 100644 --- a/src/gen/db/__init__.py +++ b/src/gen/db/__init__.py @@ -19,7 +19,9 @@ # from base import * -from cursor import * from dbconst import * -from dbdir import * +from read import * +from cursor import * +from bsddbtxn import * +from write import * from exceptions import * diff --git a/src/gen/db/base.py b/src/gen/db/base.py index e063284d1..62b5cc2cf 100644 --- a/src/gen/db/base.py +++ b/src/gen/db/base.py @@ -39,9 +39,6 @@ from sys import maxint from bsddb import db from gettext import gettext as _ -import logging -LOG = logging.getLogger(".GrampsDb") - #------------------------------------------------------------------------- # # GRAMPS libraries @@ -51,130 +48,13 @@ from gen.lib import (MediaObject, Person, Family, Source, Event, Place, Repository, Note, GenderStats, Researcher) from gen.utils.callback import Callback from gen.db.iterator import CursorIterator - -#------------------------------------------------------------------------- -# -# constants -# -#------------------------------------------------------------------------- -from gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, - MEDIA_KEY, PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, - REFERENCE_KEY, PERSON_COL_KEY, FAMILY_COL_KEY, - CHILD_COL_KEY, PLACE_COL_KEY, SOURCE_COL_KEY, - MEDIA_COL_KEY, EVENT_COL_KEY, REPOSITORY_COL_KEY, - NOTE_COL_KEY) - -_UNDO_SIZE = 1000 - - -# The following two dictionaries provide fast translation -# between the primary class names and the keys used to reference -# these classes in the database tables. Beware that changing -# these maps or modifying the values of the keys will break -# existing databases. - -CLASS_TO_KEY_MAP = {Person.__name__: PERSON_KEY, - Family.__name__: FAMILY_KEY, - Source.__name__: SOURCE_KEY, - Event.__name__: EVENT_KEY, - MediaObject.__name__: MEDIA_KEY, - Place.__name__: PLACE_KEY, - Repository.__name__:REPOSITORY_KEY, - Note.__name__: NOTE_KEY} - -KEY_TO_CLASS_MAP = {PERSON_KEY: Person.__name__, - FAMILY_KEY: Family.__name__, - SOURCE_KEY: Source.__name__, - EVENT_KEY: Event.__name__, - MEDIA_KEY: MediaObject.__name__, - PLACE_KEY: Place.__name__, - REPOSITORY_KEY: Repository.__name__, - NOTE_KEY: Note.__name__} - -_SIGBASE = ('person', 'family', 'source', 'event', - 'media', 'place', 'repository', 'reference', 'note') - -class GrampsDbBookmarks(object): - def __init__(self, default=[]): - self.bookmarks = list(default) # want a copy (not an alias) - - def set(self, new_list): - self.bookmarks = list(new_list) - - def get(self): - return self.bookmarks - - def append(self, item): - self.bookmarks.append(item) - - def append_list(self, blist): - self.bookmarks += blist - - def remove(self, item): - self.bookmarks.remove(item) - - def pop(self, item): - return self.bookmarks.pop(item) - - def insert(self, pos, item): - self.bookmarks.insert(pos, item) - -class GrampsDbBase(Callback): +class GrampsDbBase(object): """ GRAMPS database object. This object is a base class for all - database interfaces. + database interfaces. All methods raise NotImplementedError + and must be implemented in the derived class as required. """ - # This holds a reference to the gramps Config module if - # it is available, it is setup by the factory methods. - __config__ = None - - __signals__ = { - 'person-add' : (list, ), - 'person-update' : (list, ), - 'person-delete' : (list, ), - 'person-rebuild' : None, - 'family-add' : (list, ), - 'family-update' : (list, ), - 'family-delete' : (list, ), - 'family-rebuild' : None, - 'source-add' : (list, ), - 'source-update' : (list, ), - 'source-delete' : (list, ), - 'source-rebuild' : None, - 'place-add' : (list, ), - 'place-update' : (list, ), - 'place-delete' : (list, ), - 'place-rebuild' : None, - 'media-add' : (list, ), - 'media-update' : (list, ), - 'media-delete' : (list, ), - 'media-rebuild' : None, - 'event-add' : (list, ), - 'event-update' : (list, ), - 'event-delete' : (list, ), - 'event-rebuild' : None, - 'repository-add' : (list, ), - 'repository-update' : (list, ), - 'repository-delete' : (list, ), - 'repository-rebuild' : None, - 'note-add' : (list, ), - 'note-update' : (list, ), - 'note-delete' : (list, ), - 'note-rebuild' : None, - 'long-op-start' : (object, ), - 'long-op-heartbeat' : None, - 'long-op-end' : None, - 'home-person-changed': None, - } - - # If this is True logging will be turned on. - try: - _LOG_ALL = int(os.environ.get('GRAMPS_SIGNAL', "0")) == 1 - except: - _LOG_ALL = False - - def __init__(self): """ Create a new GrampsDbBase instance. @@ -183,210 +63,202 @@ class GrampsDbBase(Callback): derived from this class should be created. """ - Callback.__init__(self) - - self.set_person_id_prefix('I%04d') - self.set_object_id_prefix('O%04d') - self.set_family_id_prefix('F%04d') - self.set_source_id_prefix('S%04d') - self.set_place_id_prefix('P%04d') - self.set_event_id_prefix('E%04d') - self.set_repository_id_prefix('R%04d') - self.set_note_id_prefix('N%04d') - - self.readonly = False - self.rand = random.Random(time.time()) - self.smap_index = 0 - self.emap_index = 0 - self.pmap_index = 0 - self.fmap_index = 0 - self.lmap_index = 0 - self.omap_index = 0 - self.rmap_index = 0 - self.nmap_index = 0 - self.db_is_open = False - - self.family_event_names = set() - self.individual_event_names = set() - self.individual_attributes = set() - self.family_attributes = set() - self.marker_names = set() - self.child_ref_types = set() - self.family_rel_types = set() - self.event_role_names = set() - self.name_types = set() - self.repository_types = set() - self.note_types = set() - self.source_media_types = set() - self.url_types = set() - self.media_attributes = set() - - self.open = 0 - self.genderStats = GenderStats() - - self.undodb = [] - self.id_trans = {} - self.fid_trans = {} - self.pid_trans = {} - self.sid_trans = {} - self.oid_trans = {} - self.rid_trans = {} - self.nid_trans = {} - self.eid_trans = {} - self.env = None - self.person_map = {} - self.family_map = {} - self.place_map = {} - self.source_map = {} - self.repository_map = {} - self.note_map = {} - self.media_map = {} - self.event_map = {} - self.metadata = {} - self.name_group = {} - self.undo_callback = None - self.redo_callback = None - self.undo_history_callback = None - self.modified = 0 - - self.undoindex = -1 - self.translist = [None] * _UNDO_SIZE - self.abort_possible = True - self.undo_history_timestamp = 0 - self.default = None - self.owner = Researcher() - self.name_formats = [] - self.bookmarks = GrampsDbBookmarks() - self.family_bookmarks = GrampsDbBookmarks() - self.event_bookmarks = GrampsDbBookmarks() - self.place_bookmarks = GrampsDbBookmarks() - self.source_bookmarks = GrampsDbBookmarks() - self.repo_bookmarks = GrampsDbBookmarks() - self.media_bookmarks = GrampsDbBookmarks() - self.note_bookmarks = GrampsDbBookmarks() - self._bm_changes = 0 - self.path = "" - self.surname_list = [] + super(GrampsDbBase, self).__init__() def set_prefixes(self, person, media, family, source, place, event, repository, note): - self.person_prefix = self._validated_id_prefix(person, 'I') - self.mediaobject_prefix = self._validated_id_prefix(media, 'M') - self.family_prefix = self._validated_id_prefix(family, 'F') - self.source_prefix = self._validated_id_prefix(source, 'S') - self.place_prefix = self._validated_id_prefix(place, 'P') - self.event_prefix = self._validated_id_prefix(event, 'E') - self.repository_prefix = self._validated_id_prefix(repository, 'R') - self.note_prefix = self._validated_id_prefix(note, 'N') + """ + Set the prefixes for the gramps ids for all gramps objects + """ + raise NotImplementedError def rebuild_secondary(self, callback): - pass + """ + Rebuild secondary indices + """ + raise NotImplementedError def version_supported(self): """Return True when the file has a supported version.""" - return True + raise NotImplementedError def need_upgrade(self): - return False + """ + Return True if database needs to be upgraded + """ + raise NotImplementedError def gramps_upgrade(self): - pass + """ + Return True if database is upgraded + """ + raise NotImplementedError def del_person(self, handle): - pass + """ + Delete a Person object given the handle + """ + raise NotImplementedError def del_source(self, handle): - pass + """ + Delete a Source object given the handle + """ + raise NotImplementedError def del_repository(self, handle): - pass + """ + Delete a Repository object given the handle + """ + raise NotImplementedError def del_note(self, handle): - pass + """ + Delete a Person object given the handle + """ + raise NotImplementedError def del_place(self, handle): - pass + """ + Delete a Place object given the handle + """ + raise NotImplementedError def del_media(self, handle): - pass + """ + Delete a Media object given the handle + """ + raise NotImplementedError def del_family(self, handle): - pass + """ + Delete a Family object given the handle + """ + raise NotImplementedError def del_event(self, handle): - pass + """ + Delete an Event object given the handle + """ + raise NotImplementedError def create_id(self): - return "%08x%08x" % ( int(time.time()*10000), - self.rand.randint(0, maxint)) + """ + Create an id + """ + raise NotImplementedError def get_person_cursor(self): - raise NotImplementedError + """ + Return a reference to a cursor over Person objects + """ + raise NotImplementedError - def get_person_cursor_iter(self, msg=_("Processing Person records")): - return CursorIterator(self, self.get_person_cursor(), msg) + def get_person_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Person objects + """ + raise NotImplementedError def get_family_cursor(self): + """ + Return a reference to a cursor over Family objects + """ raise NotImplementedError - def get_family_cursor_iter(self, msg=_("Processing Family records")): - return CursorIterator(self, self.get_family_cursor(), msg) + def get_family_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Family objects + """ + raise NotImplementedError def get_event_cursor(self): + """ + Return a reference to a cursor over Family objects + """ raise NotImplementedError - def get_event_cursor_iter(self, msg=_("Processing Event records")): - return CursorIterator(self, self.get_event_cursor(), msg) + def get_event_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Family objects + """ + raise NotImplementedError def get_place_cursor(self): + """ + Return a reference to a cursor over Place objects + """ raise NotImplementedError - def get_place_cursor_iter(self, msg=_("Processing Place records")): - return CursorIterator(self, self.get_place_cursor(), msg) + def get_place_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Place objects + """ + raise NotImplementedError def get_source_cursor(self): + """ + Return a reference to a cursor over Source objects + """ raise NotImplementedError - def get_source_cursor_iter(self, msg=_("Processing Source records")): - return CursorIterator(self, self.get_source_cursor(), msg) + def get_source_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Source objects + """ + raise NotImplementedError def get_media_cursor(self): + """ + Return a reference to a cursor over Media objects + """ raise NotImplementedError - def get_media_cursor_iter(self, msg=_("Processing Media records")): - return CursorIterator(self, self.get_media_cursor(), msg) + def get_media_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Media objects + """ + raise NotImplementedError def get_repository_cursor(self): + """ + Return a reference to a cursor over Repository objects + """ raise NotImplementedError - def get_repository_cursor_iter(self, msg=_("Processing Repository records")): - return CursorIterator(self, self.get_repository_cursor(), msg) + def get_repository_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Repository objects + """ + raise NotImplementedError def get_note_cursor(self): + """ + Return a reference to a cursor over Note objects + """ raise NotImplementedError - def get_note_cursor_iter(self, msg=_("Processing Note records")): - return CursorIterator(self, self.get_note_cursor(), msg) + def get_note_cursor_iter(self, msg=None): + """ + Return a reference to a cursor iterator over Note objects + """ + raise NotImplementedError def open_undodb(self): - if not self.readonly: - self.undolog = "%s.undo" % self.full_name - self.undodb = db.DB() - self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE) + """ + Open the undo database + """ + raise NotImplementedError def close_undodb(self): - if not self.readonly: - self.undodb.close() - try: - os.remove(self.undolog) - except: - pass + """ + Close the undo database + """ + raise NotImplementedError - def load(self, name, callback, mode="w"): + def load(self, name, callback, mode=None): """ Open the specified database. - - The method needs to be overridden in the derived class. """ raise NotImplementedError @@ -395,23 +267,20 @@ class GrampsDbBase(Callback): Load data from the other database into itself. The filename is the name of the file for the newly created database. - The method needs to be overridden in the derived class. """ raise NotImplementedError def close(self): """ Close the specified database. - - The method needs to be overridden in the derived class. """ pass def is_open(self): """ - Return 1 if the database has been opened. + Return True if the database has been opened. """ - return self.db_is_open + raise NotImplementedError def request_rebuild(self): """ @@ -422,336 +291,147 @@ class GrampsDbBase(Callback): TODO: it might be better to replace these rebuild signals by one single database-rebuild signal. """ - self.emit('person-rebuild') - self.emit('family-rebuild') - self.emit('place-rebuild') - self.emit('source-rebuild') - self.emit('media-rebuild') - self.emit('event-rebuild') - self.emit('repository-rebuild') - self.emit('note-rebuild') + raise NotImplementedError def commit_base(self, obj, data_map, key, update_list, add_list, transaction, change_time): """ - Commit the specified Person to the database, storing the changes as + Commit the specified object to the database, storing the changes as part of the transaction. """ - if self.readonly or not obj or not obj.handle: - return - - if change_time: - obj.change = int(change_time) - else: - obj.change = int(time.time()) - handle = str(obj.handle) - - self.update_reference_map(obj, transaction) - - if transaction.batch: - data_map[handle] = obj.serialize() - old_data = None - else: - old_data = data_map.get(handle) - new_data = obj.serialize() - transaction.add(key, handle, old_data, new_data) - if old_data: - update_list.append((handle, new_data)) - else: - add_list.append((handle, new_data)) - return old_data + raise NotImplementedError def commit_person(self, person, transaction, change_time=None): """ Commit the specified Person to the database, storing the changes as part of the transaction. """ - - old_data = self.commit_base( - person, self.person_map, PERSON_KEY, transaction.person_update, - transaction.person_add, transaction, change_time) - if old_data: - old_person = Person(old_data) - if (old_data[2] != person.gender or - old_data[3][4]!= person.primary_name.first_name): - self.genderStats.uncount_person(old_person) - self.genderStats.count_person(person) - if (old_data[3][5]!=person.primary_name.surname): - 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 - if attr.type.is_custom() and str(attr.type)]) - - if person.marker.is_custom(): - self.marker_names.add(str(person.marker)) - - self.event_role_names.update([str(eref.role) - for eref in person.event_ref_list - if eref.role.is_custom()]) - - self.name_types.update([str(name.type) - for name in ([person.primary_name] - + person.alternate_names) - if name.type.is_custom()]) - - self.url_types.update([str(url.type) for url in person.urls - if url.type.is_custom()]) - - attr_list = [] - for mref in person.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] - self.media_attributes.update(attr_list) + raise NotImplementedError def commit_media_object(self, obj, transaction, change_time=None): """ Commit the specified MediaObject to the database, storing the changes as part of the transaction. """ - - self.commit_base(obj, self.media_map, MEDIA_KEY, - transaction.media_update, transaction.media_add, - transaction, change_time) - self.media_attributes.update( - [str(attr.type) for attr in obj.attribute_list - if attr.type.is_custom() and str(attr.type)]) + raise NotImplementedError def commit_source(self, source, transaction, change_time=None): """ Commit the specified Source to the database, storing the changes as part of the transaction. """ - - self.commit_base(source, self.source_map, SOURCE_KEY, - transaction.source_update, transaction.source_add, - transaction, change_time) - - self.source_media_types.update( - [str(ref.media_type) for ref in source.reporef_list - if ref.media_type.is_custom()]) - - attr_list = [] - for mref in source.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] - self.media_attributes.update(attr_list) + raise NotImplementedError def commit_place(self, place, transaction, change_time=None): """ Commit the specified Place to the database, storing the changes as part of the transaction. """ - - self.commit_base(place, self.place_map, PLACE_KEY, - transaction.place_update, transaction.place_add, - transaction, change_time) - - self.url_types.update([str(url.type) for url in place.urls - if url.type.is_custom()]) - - attr_list = [] - for mref in place.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] - self.media_attributes.update(attr_list) + raise NotImplementedError def commit_personal_event(self, event, transaction, change_time=None): - if event.type.is_custom(): - self.individual_event_names.add(str(event.type)) - self.commit_event(event, transaction, change_time) + """ + Commit the specified personal Event to the database, storing the + changes as part of the transaction. + """ + raise NotImplementedError def commit_family_event(self, event, transaction, change_time=None): - if event.type.is_custom(): - self.family_event_names.add(str(event.type)) - self.commit_event(event, transaction, change_time) + """ + Commit the specified family Event to the database, storing the + changes as part of the transaction. + """ + raise NotImplementedError def commit_event(self, event, transaction, change_time=None): """ Commit the specified Event to the database, storing the changes as part of the transaction. """ - self.commit_base(event, self.event_map, EVENT_KEY, - transaction.event_update, transaction.event_add, - transaction, change_time) - - attr_list = [] - for mref in event.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] - self.media_attributes.update(attr_list) + raise NotImplementedError def commit_family(self, family, transaction, change_time=None): """ Commit the specified Family to the database, storing the changes as part of the transaction. """ - - self.commit_base(family, self.family_map, FAMILY_KEY, - transaction.family_update, transaction.family_add, - transaction, change_time) - - self.family_attributes.update( - [str(attr.type) for attr in family.attribute_list - if attr.type.is_custom() and str(attr.type)]) - - rel_list = [] - for ref in family.child_ref_list: - if ref.frel.is_custom(): - rel_list.append(str(ref.frel)) - if ref.mrel.is_custom(): - rel_list.append(str(ref.mrel)) - self.child_ref_types.update(rel_list) - - self.event_role_names.update( - [str(eref.role) for eref in family.event_ref_list - if eref.role.is_custom()]) - - if family.type.is_custom(): - self.family_rel_types.add(str(family.type)) - - attr_list = [] - for mref in family.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] - self.media_attributes.update(attr_list) + raise NotImplementedError def commit_repository(self, repository, transaction, change_time=None): """ Commit the specified Repository to the database, storing the changes as part of the transaction. """ - self.commit_base(repository, self.repository_map, REPOSITORY_KEY, - transaction.repository_update, - transaction.repository_add, - transaction, change_time) - - if repository.type.is_custom(): - self.repository_types.add(str(repository.type)) - - self.url_types.update([str(url.type) for url in repository.urls - if url.type.is_custom()]) + raise NotImplementedError def commit_note(self, note, transaction, change_time=None): """ Commit the specified Note to the database, storing the changes as part of the transaction. """ - self.commit_base(note, self.note_map, NOTE_KEY, - transaction.note_update, - transaction.note_add, - transaction, change_time) - - if note.type.is_custom(): - self.note_types.add(str(note.type)) + raise NotImplementedError def find_next_person_gramps_id(self): """ Return the next available GRAMPS' ID for a Person object based off the person ID prefix. """ - index = self.person_prefix % self.pmap_index - while self.id_trans.has_key(str(index)): - self.pmap_index += 1 - index = self.person_prefix % self.pmap_index - self.pmap_index += 1 - return index + raise NotImplementedError def find_next_place_gramps_id(self): """ Return the next available GRAMPS' ID for a Place object based off the place ID prefix. """ - index = self.place_prefix % self.lmap_index - while self.pid_trans.has_key(str(index)): - self.lmap_index += 1 - index = self.place_prefix % self.lmap_index - self.lmap_index += 1 - return index + raise NotImplementedError def find_next_event_gramps_id(self): """ Return the next available GRAMPS' ID for a Event object based off the event ID prefix. """ - index = self.event_prefix % self.emap_index - while self.eid_trans.has_key(str(index)): - self.emap_index += 1 - index = self.event_prefix % self.emap_index - self.emap_index += 1 - return index + raise NotImplementedError def find_next_object_gramps_id(self): """ Return the next available GRAMPS' ID for a MediaObject object based off the media object ID prefix. """ - index = self.mediaobject_prefix % self.omap_index - while self.oid_trans.has_key(str(index)): - self.omap_index += 1 - index = self.mediaobject_prefix % self.omap_index - self.omap_index += 1 - return index + raise NotImplementedError def find_next_source_gramps_id(self): """ Return the next available GRAMPS' ID for a Source object based off the source ID prefix. """ - index = self.source_prefix % self.smap_index - while self.sid_trans.has_key(str(index)): - self.smap_index += 1 - index = self.source_prefix % self.smap_index - self.smap_index += 1 - return index + raise NotImplementedError def find_next_family_gramps_id(self): """ Return the next available GRAMPS' ID for a Family object based off the family ID prefix. """ - index = self.family_prefix % self.fmap_index - while self.fid_trans.has_key(str(index)): - self.fmap_index += 1 - index = self.family_prefix % self.fmap_index - self.fmap_index += 1 - return index + raise NotImplementedError def find_next_repository_gramps_id(self): """ Return the next available GRAMPS' ID for a Respository object based off the repository ID prefix. """ - index = self.repository_prefix % self.rmap_index - while self.rid_trans.has_key(str(index)): - self.rmap_index += 1 - index = self.repository_prefix % self.rmap_index - self.rmap_index += 1 - return index + raise NotImplementedError def find_next_note_gramps_id(self): """ Return the next available GRAMPS' ID for a Note object based off the note ID prefix. """ - index = self.note_prefix % self.nmap_index - while self.nid_trans.has_key(str(index)): - self.nmap_index += 1 - index = self.note_prefix % self.nmap_index - self.nmap_index += 1 - return index + raise NotImplementedError def get_from_handle(self, handle, class_type, data_map): - data = data_map.get(str(handle)) - if data: - newobj = class_type() - newobj.unserialize(data) - return newobj - return None + """ + Return unserialized data from database given handle and object class + """ + raise NotImplementedError def get_person_from_handle(self, handle): """ @@ -759,7 +439,7 @@ class GrampsDbBase(Callback): If no such Person exists, None is returned. """ - return self.get_from_handle(handle, Person, self.person_map) + raise NotImplementedError def get_source_from_handle(self, handle): """ @@ -767,7 +447,7 @@ class GrampsDbBase(Callback): If no such Source exists, None is returned. """ - return self.get_from_handle(handle, Source, self.source_map) + raise NotImplementedError def get_object_from_handle(self, handle): """ @@ -775,7 +455,7 @@ class GrampsDbBase(Callback): If no such Object exists, None is returned. """ - return self.get_from_handle(handle, MediaObject, self.media_map) + raise NotImplementedError def get_place_from_handle(self, handle): """ @@ -783,7 +463,7 @@ class GrampsDbBase(Callback): If no such Place exists, None is returned. """ - return self.get_from_handle(handle, Place, self.place_map) + raise NotImplementedError def get_event_from_handle(self, handle): """ @@ -791,7 +471,7 @@ class GrampsDbBase(Callback): If no such Event exists, None is returned. """ - return self.get_from_handle(handle, Event, self.event_map) + raise NotImplementedError def get_family_from_handle(self, handle): """ @@ -799,7 +479,7 @@ class GrampsDbBase(Callback): If no such Family exists, None is returned. """ - return self.get_from_handle(handle, Family, self.family_map) + raise NotImplementedError def get_repository_from_handle(self, handle): """ @@ -807,7 +487,7 @@ class GrampsDbBase(Callback): If no such Repository exists, None is returned. """ - return self.get_from_handle(handle, Repository, self.repository_map) + raise NotImplementedError def get_note_from_handle(self, handle): """ @@ -815,7 +495,7 @@ class GrampsDbBase(Callback): If no such Note exists, None is returned. """ - return self.get_from_handle(handle, Note, self.note_map) + raise NotImplementedError def find_from_handle(self, handle, transaction, class_type, dmap, add_func): @@ -828,26 +508,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - obj = class_type() - handle = str(handle) - new = True - if handle in dmap: - obj.unserialize(dmap.get(handle)) - #references create object with id None before object is really made - if obj.gramps_id is not None: - new = False - else: - obj.set_handle(handle) - add_func(obj, transaction) - return obj, new - - def __check_from_handle(self, handle, transaction, class_type, dmap, - add_func, set_gid=True): - handle = str(handle) - if handle not in dmap: - obj = class_type() - obj.set_handle(handle) - add_func(obj, transaction, set_gid=set_gid) + raise NotImplementedError def find_person_from_handle(self, handle, transaction): """ @@ -859,8 +520,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Person, - self.person_map, self.add_person) + raise NotImplementedError def find_source_from_handle(self, handle, transaction): """ @@ -872,8 +532,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Source, - self.source_map, self.add_source) + raise NotImplementedError def find_event_from_handle(self, handle, transaction): """ @@ -885,8 +544,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Event, - self.event_map, self.add_event) + raise NotImplementedError def find_object_from_handle(self, handle, transaction): """ @@ -898,8 +556,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, MediaObject, - self.media_map, self.add_object) + raise NotImplementedError def find_place_from_handle(self, handle, transaction): """ @@ -911,8 +568,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Place, - self.place_map, self.add_place) + raise NotImplementedError def find_family_from_handle(self, handle, transaction): """ @@ -924,8 +580,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Family, - self.family_map, self.add_family) + raise NotImplementedError def find_repository_from_handle(self, handle, transaction): """ @@ -937,8 +592,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Repository, - self.repository_map, self.add_repository) + raise NotImplementedError def find_note_from_handle(self, handle, transaction): """ @@ -950,8 +604,7 @@ class GrampsDbBase(Callback): if the object is new @rtype: tuple """ - return self.find_from_handle(handle, transaction, Note, - self.note_map, self.add_note) + raise NotImplementedError def check_person_from_handle(self, handle, transaction, set_gid=True): """ @@ -960,10 +613,8 @@ class GrampsDbBase(Callback): If no such Person exists, a new Person is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Person, - self.person_map, self.add_person, - set_gid = set_gid) - + raise NotImplementedError + def check_source_from_handle(self, handle, transaction, set_gid=True): """ Check whether a Source with the passed handle exists in the database. @@ -971,9 +622,7 @@ class GrampsDbBase(Callback): If no such Source exists, a new Source is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Source, - self.source_map, self.add_source, - set_gid=set_gid) + raise NotImplementedError def check_event_from_handle(self, handle, transaction, set_gid=True): """ @@ -982,9 +631,7 @@ class GrampsDbBase(Callback): If no such Event exists, a new Event is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Event, - self.event_map, self.add_event, - set_gid=set_gid) + raise NotImplementedError def check_object_from_handle(self, handle, transaction, set_gid=True): """ @@ -994,10 +641,7 @@ class GrampsDbBase(Callback): If no such MediaObject exists, a new Object is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - - self.__check_from_handle(handle, transaction, MediaObject, - self.media_map, self.add_object, - set_gid=set_gid) + raise NotImplementedError def check_place_from_handle(self, handle, transaction, set_gid=True): """ @@ -1006,9 +650,7 @@ class GrampsDbBase(Callback): If no such Place exists, a new Place is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Place, - self.place_map, self.add_place, - set_gid=set_gid) + raise NotImplementedError def check_family_from_handle(self, handle, transaction, set_gid=True): """ @@ -1017,9 +659,7 @@ class GrampsDbBase(Callback): If no such Family exists, a new Family is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Family, - self.family_map, self.add_family, - set_gid=set_gid) + raise NotImplementedError def check_repository_from_handle(self, handle, transaction, set_gid=True): """ @@ -1029,9 +669,7 @@ class GrampsDbBase(Callback): If no such Repository exists, a new Repository is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Repository, - self.repository_map, self.add_repository, - set_gid=set_gid) + raise NotImplementedError def check_note_from_handle(self, handle, transaction, set_gid=True): """ @@ -1040,9 +678,7 @@ class GrampsDbBase(Callback): If no such Note exists, a new Note is added to the database. If set_gid then a new gramps_id is created, if not, None is used. """ - self.__check_from_handle(handle, transaction, Note, - self.note_map, self.add_note, - set_gid=set_gid) + raise NotImplementedError def get_person_from_gramps_id(self, val): """ @@ -1116,16 +752,6 @@ class GrampsDbBase(Callback): """ raise NotImplementedError - def __add_object(self, obj, transaction, find_next_func, commit_func): - if find_next_func and not obj.gramps_id: - obj.gramps_id = find_next_func() - if not obj.handle: - obj.handle = self.create_id() - commit_func(obj, transaction) - if obj.__class__.__name__ == 'Person': - self.genderStats.count_person (obj) - return obj.handle - def add_person(self, person, transaction, set_gid=True): """ Add a Person to the database, assigning internal IDs if they have @@ -1133,14 +759,7 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(person, transaction, - self.find_next_person_gramps_id, - self.commit_person) - else: - return self.__add_object(person, transaction, - None, - self.commit_person) + raise NotImplementedError def add_family(self, family, transaction, set_gid=True): """ @@ -1149,14 +768,7 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(family, transaction, - self.find_next_family_gramps_id, - self.commit_family) - else: - return self.__add_object(family, transaction, - None, - self.commit_family) + raise NotImplementedError def add_source(self, source, transaction, set_gid=True): """ @@ -1165,15 +777,8 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(source, transaction, - self.find_next_source_gramps_id, - self.commit_source) - else : - return self.__add_object(source, transaction, - None, - self.commit_source) - + raise NotImplementedError + def add_event(self, event, transaction, set_gid=True): """ Add an Event to the database, assigning internal IDs if they have @@ -1181,32 +786,21 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(event, transaction, - self.find_next_event_gramps_id, - self.commit_event) - else: - return self.__add_object(event, transaction, - None, - self.commit_event) + raise NotImplementedError def add_person_event(self, event, transaction): """ Add an Event to the database, assigning internal IDs if they have not already been defined. """ - if event.type.is_custom(): - self.individual_event_names.add(str(event.type)) - return self.add_event(event, transaction) + raise NotImplementedError def add_family_event(self, event, transaction): """ Add an Event to the database, assigning internal IDs if they have not already been defined. """ - if event.type.is_custom(): - self.family_event_names.add(str(event.type)) - return self.add_event(event, transaction) + raise NotImplementedError def add_place(self, place, transaction, set_gid=True): """ @@ -1215,14 +809,7 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(place, transaction, - self.find_next_place_gramps_id, - self.commit_place) - else: - return self.__add_object(place, transaction, - None, - self.commit_place) + raise NotImplementedError def add_object(self, obj, transaction, set_gid=True): """ @@ -1231,14 +818,7 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(obj, transaction, - self.find_next_object_gramps_id, - self.commit_media_object) - else: - return self.__add_object(obj, transaction, - None, - self.commit_media_object) + raise NotImplementedError def add_repository(self, obj, transaction, set_gid=True): """ @@ -1247,14 +827,7 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(obj, transaction, - self.find_next_repository_gramps_id, - self.commit_repository) - else: - return self.__add_object(obj, transaction, - None, - self.commit_repository) + raise NotImplementedError def add_note(self, obj, transaction, set_gid=True): """ @@ -1263,32 +836,25 @@ class GrampsDbBase(Callback): If not set_gid, then gramps_id is not set. """ - if set_gid: - return self.__add_object(obj, transaction, - self.find_next_note_gramps_id, - self.commit_note) - else: - return self.__add_object(obj, transaction, - None, - self.commit_note) + raise NotImplementedError def get_name_group_mapping(self, name): """ Return the default grouping name for a surname. """ - return unicode(self.name_group.get(str(name), name)) + raise NotImplementedError def get_name_group_keys(self): """ Return the defined names that have been assigned to a default grouping. """ - return [unicode(k) for k in self.name_group.keys()] + raise NotImplementedError def has_name_group_key(self, name): """ Return if a key exists in the name_group table. """ - return self.name_group.has_key(str(name)) + raise NotImplementedError def set_name_group_mapping(self, name, group): """ @@ -1298,63 +864,58 @@ class GrampsDbBase(Callback): """ raise NotImplementedError - @staticmethod - def get_number_of_records(table): - return table.stat(db.DB_FAST_STAT)['nkeys'] - def get_number_of_people(self): """ Return the number of people currently in the database. """ - if self.db_is_open: - return self.get_number_of_records(self.person_map) - #return len(self.person_map) - else: - return 0 + raise NotImplementedError def get_number_of_families(self): """ Return the number of families currently in the database. """ - return self.get_number_of_records(self.family_map) + raise NotImplementedError def get_number_of_events(self): """ Return the number of events currently in the database. """ - return self.get_number_of_records(self.event_map) + raise NotImplementedError def get_number_of_places(self): """ Return the number of places currently in the database. """ - return self.get_number_of_records(self.place_map) + raise NotImplementedError def get_number_of_sources(self): """ Return the number of sources currently in the database. """ - return self.get_number_of_records(self.source_map) + raise NotImplementedError def get_number_of_media_objects(self): """ Return the number of media objects currently in the database. """ - return len(self.media_map) + raise NotImplementedError def get_number_of_repositories(self): """ Return the number of source repositories currently in the database. """ - return self.get_number_of_records(self.repository_map) + raise NotImplementedError def get_number_of_notes(self): """ Return the number of notes currently in the database. """ - return self.get_number_of_records(self.note_map) + raise NotImplementedError def all_handles(self, table): + """ + Return all handles from the specified table as a list + """ return table.keys() def get_person_handles(self, sort_handles=True): @@ -1364,22 +925,19 @@ class GrampsDbBase(Callback): If sort_handles is True, the list is sorted by surnames. """ - if self.db_is_open: - if sort_handles: - with self.get_person_cursor() as cursor: - slist = sorted((data[3][3], key) for key, data in cursor) - return [x[1] for x in slist] - else: - return self.all_handles(self.person_map) - return [] + raise NotImplementedError def iter_person_handles(self): """ Return an iterator over handles for Persons in the database """ - with self.get_person_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError + + def iter_people(self): + """ + Return an iterator over handles and objects for Persons in the database + """ + raise NotImplementedError def get_place_handles(self, sort_handles=True): """ @@ -1388,44 +946,28 @@ class GrampsDbBase(Callback): If sort_handles is True, the list is sorted by Place title. """ - if self.db_is_open: - if sort_handles: - with self.get_place_cursor() as cursor: - slist = sorted((data[2], key) for key, data in cursor) - return [x[1] for x in slist] - else: - return self.all_handles(self.place_map) - return [] + raise NotImplementedError def iter_place_handles(self): """ Return an iterator over handles for Places in the database """ - with self.get_place_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_source_handles(self, sort_handles=True): """ Return a list of database handles, one handle for each Source in the database. - If sort_handles is True, the list is sorted by Source title. + If sort_handles is True, the list is sorted by Source title. """ - if self.db_is_open: - handle_list = self.all_handles(self.source_map) - if sort_handles: - handle_list.sort(key=self.__sortbysource_key) - return handle_list - return [] + raise NotImplementedError def iter_source_handles(self): """ Return an iterator over handles for Sources in the database """ - with self.get_source_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_media_object_handles(self, sort_handles=True): """ @@ -1434,140 +976,86 @@ class GrampsDbBase(Callback): If sort_handles is True, the list is sorted by title. """ - if self.db_is_open: - handle_list = self.all_handles(self.media_map) - if sort_handles: - handle_list.sort(key=self.__sortbymedia_key) - return handle_list - return [] + raise NotImplementedError def iter_media_object_handles(self): """ Return an iterator over handles for Media in the database """ - with self.get_media_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_event_handles(self): """ Return a list of database handles, one handle for each Event in the database. """ - if self.db_is_open: - return self.all_handles(self.event_map) - return [] + raise NotImplementedError def iter_event_handles(self): """ Return an iterator over handles for Events in the database """ - with self.get_event_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_family_handles(self): """ Return a list of database handles, one handle for each Family in the database. """ - if self.db_is_open: - return self.all_handles(self.family_map) - return [] + raise NotImplementedError def iter_family_handles(self): """ Return an iterator over handles for Families in the database """ - with self.get_family_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_repository_handles(self): """ Return a list of database handles, one handle for each Repository in the database. """ - if self.db_is_open: - return self.all_handles(self.repository_map) - return [] + raise NotImplementedError def iter_repository_handles(self): """ Return an iterator over handles for Repositories in the database """ - with self.get_repository_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_note_handles(self): """ Return a list of database handles, one handle for each Note in the database. """ - if self.db_is_open: - return self.all_handles(self.note_map) - return [] + raise NotImplementedError def iter_note_handles(self): """ Return an iterator over handles for Notes in the database """ - with self.get_note_cursor() as cursor: - for key, data in cursor: - yield key + raise NotImplementedError def get_gramps_ids(self, obj_key): - key2table = { - PERSON_KEY: self.id_trans, - FAMILY_KEY: self.fid_trans, - SOURCE_KEY: self.sid_trans, - EVENT_KEY: self.eid_trans, - MEDIA_KEY: self.oid_trans, - PLACE_KEY: self.pid_trans, - REPOSITORY_KEY: self.rid_trans, - NOTE_KEY: self.nid_trans, - } - - table = key2table[obj_key] - return table.keys() - + """ + Returns all the keys from a table given a table name + """ + raise NotImplementedError + def has_gramps_id(self, obj_key, gramps_id): - key2table = { - PERSON_KEY: self.id_trans, - FAMILY_KEY: self.fid_trans, - SOURCE_KEY: self.sid_trans, - EVENT_KEY: self.eid_trans, - MEDIA_KEY: self.oid_trans, - PLACE_KEY: self.pid_trans, - REPOSITORY_KEY: self.rid_trans, - NOTE_KEY: self.nid_trans, - } + """ + Returns True if the key exists in table given a table name - table = key2table[obj_key] - #return str(gramps_id) in table - return table.has_key(str(gramps_id)) + Not used in current codebase + """ + raise NotImplementedError def find_initial_person(self): - person = self.get_default_person() - if not person: - the_ids = self.get_gramps_ids(PERSON_KEY) - if the_ids: - person = self.get_person_from_gramps_id(min(the_ids)) - return person + """ + Returns first person in the database + """ + raise NotImplementedError - def _validated_id_prefix(self, val, default): - if isinstance(val, basestring) and val: - try: - str_ = val % 1 - except TypeError: # missing conversion specifier - prefix_var = val + "%d" - else: - prefix_var = val # OK as given - else: - prefix_var = default+"%04d" # not a string or empty string - return prefix_var - def set_person_id_prefix(self, val): """ Set the naming template for GRAMPS Person ID values. @@ -1576,7 +1064,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as I%d or I%04d. """ - self.person_prefix = self._validated_id_prefix(val, "I") + raise NotImplementedError def set_source_id_prefix(self, val): """ @@ -1586,7 +1074,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as S%d or S%04d. """ - self.source_prefix = self._validated_id_prefix(val, "S") + raise NotImplementedError def set_object_id_prefix(self, val): """ @@ -1596,7 +1084,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as O%d or O%04d. """ - self.mediaobject_prefix = self._validated_id_prefix(val, "O") + raise NotImplementedError def set_place_id_prefix(self, val): """ @@ -1606,7 +1094,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as P%d or P%04d. """ - self.place_prefix = self._validated_id_prefix(val, "P") + raise NotImplementedError def set_family_id_prefix(self, val): """ @@ -1615,7 +1103,7 @@ class GrampsDbBase(Callback): that contains a C/Python style format string using %d, such as F%d or F%04d. """ - self.family_prefix = self._validated_id_prefix(val, "F") + raise NotImplementedError def set_event_id_prefix(self, val): """ @@ -1625,7 +1113,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as E%d or E%04d. """ - self.event_prefix = self._validated_id_prefix(val, "E") + raise NotImplementedError def set_repository_id_prefix(self, val): """ @@ -1635,7 +1123,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as R%d or R%04d. """ - self.repository_prefix = self._validated_id_prefix(val, "R") + raise NotImplementedError def set_note_id_prefix(self, val): """ @@ -1645,7 +1133,7 @@ class GrampsDbBase(Callback): in a format that contains a C/Python style format string using %d, such as N%d or N%04d. """ - self.note_prefix = self._validated_id_prefix(val, "N") + raise NotImplementedError def transaction_begin(self, msg="", batch=False, no_magic=False): """ @@ -1654,232 +1142,14 @@ class GrampsDbBase(Callback): The transaction has no effect until it is committed using the transaction_commit function of the this database object. """ - if self._LOG_ALL: - LOG.debug("%s: Transaction begin '%s'\n" - % (self.__class__.__name__, str(msg))) - if batch: - # A batch transaction does not store the commits - # Aborting the session completely will become impossible. - self.abort_possible = False - self.undo_history_timestamp = time.time() - # Undo is also impossible after batch transaction - self.undoindex = -1 - self.translist = [None] * _UNDO_SIZE - return Transaction(msg, self.undodb, batch) + raise NotImplementedError def transaction_commit(self, transaction, msg): """ Commit the transaction to the associated UNDO database. """ - if self._LOG_ALL: - LOG.debug("%s: Transaction commit '%s'\n" - % (self.__class__.__name__, str(msg))) + raise NotImplementedError - if not len(transaction) or self.readonly: - return - - transaction.set_description(msg) - transaction.timestamp = time.time() - self.undoindex += 1 - if self.undoindex >= _UNDO_SIZE: - # We overran the undo size. - # Aborting the session completely will become impossible. - self.abort_possible = False - self.undo_history_timestamp = time.time() - self.translist = self.translist[0:-1] + [ transaction ] - else: - self.translist[self.undoindex] = transaction - # Real commit erases all subsequent transactions - # to there's no Redo anymore. - for index in range(self.undoindex+1, _UNDO_SIZE): - self.translist[index] = None - - person_add = self.do_commit(transaction.person_add, self.person_map) - family_add = self.do_commit(transaction.family_add, self.family_map) - source_add = self.do_commit(transaction.source_add, self.source_map) - place_add = self.do_commit(transaction.place_add, self.place_map) - media_add = self.do_commit(transaction.media_add, self.media_map) - event_add = self.do_commit(transaction.event_add, self.event_map) - repository_add = self.do_commit(transaction.repository_add, - self.repository_map) - - note_add = self.do_commit(transaction.note_add, self.note_map) - person_upd = self.do_commit(transaction.person_update, self.person_map) - family_upd = self.do_commit(transaction.family_update, self.family_map) - source_upd = self.do_commit(transaction.source_update, self.source_map) - place_upd = self.do_commit(transaction.place_update, self.place_map) - media_upd = self.do_commit(transaction.media_update, self.media_map) - event_upd = self.do_commit(transaction.event_update, self.event_map) - repository_upd = self.do_commit(transaction.repository_update, - self.repository_map) - note_upd = self.do_commit(transaction.note_update, self.note_map) - - self.__do_emit('person', person_add, person_upd, transaction.person_del) - self.__do_emit('family', family_add, family_upd, transaction.family_del) - self.__do_emit('event', event_add, event_upd, transaction.event_del) - self.__do_emit('source', source_add, source_upd, transaction.source_del) - self.__do_emit('place', place_add, place_upd, transaction.place_del) - self.__do_emit('media', media_add, media_upd, transaction.media_del) - self.__do_emit('repository', repository_add, repository_upd, - transaction.repository_del) - self.__do_emit('note', note_add, note_upd, transaction.note_del) - - self.__do_del(transaction.person_del, self.del_person) - self.__do_del(transaction.family_del, self.del_family) - self.__do_del(transaction.place_del, self.del_place) - self.__do_del(transaction.source_del, self.del_source) - self.__do_del(transaction.event_del, self.del_event) - self.__do_del(transaction.media_del, self.del_media) - self.__do_del(transaction.repository_del, self.del_repository) - self.__do_del(transaction.note_del, self.del_note) - - if self.undo_callback: - self.undo_callback(_("_Undo %s") % transaction.get_description()) - if self.redo_callback: - self.redo_callback(None) - if self.undo_history_callback: - self.undo_history_callback() - - def __do_emit(self, objtype, add_list, upd_list, del_list): - if add_list: - self.emit(objtype + '-add', (add_list, )) - if upd_list: - self.emit(objtype + '-update', (upd_list, )) - if del_list: - self.emit(objtype + '-delete', (del_list, )) - - def __do_del(self, del_list, func): - for handle in del_list: - func(handle) - return del_list - - def do_commit(self, add_list, db_map): - retlist = [] - for (handle, data) in add_list: - db_map[handle] = data - retlist.append(str(handle)) - return retlist - - def undo_available(self): - """ - Return boolean of whether or not there's a possibility of undo. - """ - if self.undoindex == -1 or self.readonly: - return False - return True - - def redo_available(self): - """ - Return boolean of whether or not there's a possibility of redo. - """ - if self.undoindex >= _UNDO_SIZE or self.readonly: - return False - - if self.translist[self.undoindex+1] is None: - return False - - return True - - def undo(self, update_history=True): - """ - Access the last committed transaction, and revert the data to the - state before the transaction was committed. - """ - if not self.undo_available(): - return False - - transaction = self.translist[self.undoindex] - - mapbase = (self.person_map, self.family_map, self.source_map, - self.event_map, self.media_map, self.place_map, - self.repository_map, {}, self.note_map) - - self.undoindex -= 1 - subitems = transaction.get_recnos() - subitems.reverse() - for record_id in subitems: - (key, handle, old_data, new_data) = transaction.get_record(record_id) - if key == REFERENCE_KEY: - self.undo_reference(old_data, handle) - else: - self.undo_data(old_data, handle, mapbase[key], _SIGBASE[key]) - - if self.undo_callback: - if self.undo_available(): - new_transaction = self.translist[self.undoindex] - self.undo_callback(_("_Undo %s") - % new_transaction.get_description()) - else: - self.undo_callback(None) - - if self.redo_callback: - if self. redo_available(): - self.redo_callback(_("_Redo %s") - % transaction.get_description()) - else: - self.redo_callback(None) - - if update_history and self.undo_history_callback: - self.undo_history_callback() - return True - - def redo(self, update_history=True): - """ - Accesse the last undone transaction, and revert the data to the state - before the transaction was undone. - """ - - if not self.redo_available(): - return False - - self.undoindex += 1 - transaction = self.translist[self.undoindex] - mapbase = (self.person_map, self.family_map, self.source_map, - self.event_map, self.media_map, self.place_map, - self.repository_map, {}, self.note_map) - - subitems = transaction.get_recnos() - for record_id in subitems: - (key, handle, old_data, new_data) = transaction.get_record(record_id) - if key == REFERENCE_KEY: - self.undo_reference(new_data, handle) - else: - self.undo_data(new_data, handle, mapbase[key], _SIGBASE[key]) - - if self.undo_callback: - if self.undo_available(): - self.undo_callback(_("_Undo %s") - % transaction.get_description()) - else: - self.undo_callback(None) - - if self.redo_callback: - if self.redo_available(): - new_transaction = self.translist[self.undoindex+1] - self.redo_callback(_("_Redo %s") - % new_transaction.get_description()) - else: - self.redo_callback(None) - - if update_history and self.undo_history_callback: - self.undo_history_callback() - return True - - def undo_reference(self, data, handle): - pass - - def undo_data(self, data, handle, db_map, signal_root): - if data is None: - self.emit(signal_root + '-delete', ([handle], )) - del db_map[handle] - else: - if handle in db_map: - signal = signal_root + '-update' - else: - signal = signal_root + '-add' - db_map[handle] = data - self.emit(signal, ([handle], )) - def set_undo_callback(self, callback): """ Define the callback function that is called whenever an undo operation @@ -1888,7 +1158,7 @@ class GrampsDbBase(Callback): The callback function receives a single argument that is a text string that defines the operation. """ - self.undo_callback = callback + raise NotImplementedError def set_redo_callback(self, callback): """ @@ -1898,26 +1168,31 @@ class GrampsDbBase(Callback): The callback function receives a single argument that is a text string that defines the operation. """ - self.redo_callback = callback + raise NotImplementedError def get_surname_list(self): """ Return the list of locale-sorted surnames contained in the database. """ - return self.surname_list + raise NotImplementedError def build_surname_list(self): """ Build the list of locale-sorted surnames contained in the database. - - The function must be overridden in the derived class. """ raise NotImplementedError def sort_surname_list(self): - self.surname_list.sort(key=locale.strxfrm) + """ + Sort the list of surnames contained in the database by locale ordering. + """ + raise NotImplementedError def add_to_surname_list(self, person, batch_transaction): + """ + Add surname from given person to list of surnames + """ + raise NotImplementedError if batch_transaction: return name = unicode(person.get_primary_name().get_surname()) @@ -1937,172 +1212,163 @@ class GrampsDbBase(Callback): def get_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.bookmarks + raise NotImplementedError def get_family_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.family_bookmarks + raise NotImplementedError def get_event_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.event_bookmarks + raise NotImplementedError def get_place_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.place_bookmarks + raise NotImplementedError def get_source_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.source_bookmarks + raise NotImplementedError def get_media_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.media_bookmarks + raise NotImplementedError def get_repo_bookmarks(self): """Return the list of Person handles in the bookmarks.""" - return self.repo_bookmarks + raise NotImplementedError def get_note_bookmarks(self): """Return the list of Note handles in the bookmarks.""" - return self.note_bookmarks + raise NotImplementedError def set_researcher(self, owner): """Set the information about the owner of the database.""" - self.owner.set_from(owner) + raise NotImplementedError def get_researcher(self): """ Return the Researcher instance, providing information about the owner of the database. """ - return self.owner + raise NotImplementedError def set_default_person_handle(self, handle): """Set the default Person to the passed instance.""" - if (self.metadata is not None) and (not self.readonly): - self.metadata['default'] = str(handle) - self.emit('home-person-changed') + raise NotImplementedError def get_default_person(self): """Return the default Person of the database.""" - person = self.get_person_from_handle(self.get_default_handle()) - if person: - return person - elif (self.metadata is not None) and (not self.readonly): - self.metadata['default'] = None - return None + raise NotImplementedError def get_default_handle(self): """Return the default Person of the database.""" - if self.metadata is not None: - return self.metadata.get('default') - return None + raise NotImplementedError def get_save_path(self): """Return the save path of the file, or "" if one does not exist.""" - return self.path + raise NotImplementedError def set_save_path(self, path): """Set the save path for the database.""" - self.path = path + raise NotImplementedError def get_person_event_types(self): """ Return a list of all Event types associated with Person instances in the database. """ - return list(self.individual_event_names) - + raise NotImplementedError + def get_person_attribute_types(self): """ Return a list of all Attribute types associated with Person instances in the database. """ - return list(self.individual_attributes) - + raise NotImplementedError + def get_family_attribute_types(self): """ Return a list of all Attribute types associated with Family instances in the database. """ - return list(self.family_attributes) - + raise NotImplementedError + def get_family_event_types(self): """ Return a list of all Event types associated with Family instances in the database. """ - return list(self.family_event_names) - + raise NotImplementedError + def get_marker_types(self): """ Return a list of all marker types available in the database. """ - return list(self.marker_names) + raise NotImplementedError def get_media_attribute_types(self): """ Return a list of all Attribute types associated with Media and MediaRef instances in the database. """ - return list(self.media_attributes) + raise NotImplementedError def get_family_relation_types(self): """ Return a list of all relationship types associated with Family instances in the database. """ - return list(self.family_rel_types) + raise NotImplementedError def get_child_reference_types(self): """ Return a list of all child reference types associated with Family instances in the database. """ - return list(self.child_ref_types) + raise NotImplementedError def get_event_roles(self): """ Return a list of all custom event role names associated with Event instances in the database. """ - return list(self.event_role_names) + raise NotImplementedError def get_name_types(self): """ Return a list of all custom names types associated with Person instances in the database. """ - return list(self.name_types) + raise NotImplementedError def get_repository_types(self): """ Return a list of all custom repository types associated with Repository instances in the database. """ - return list(self.repository_types) + raise NotImplementedError def get_note_types(self): """ Return a list of all custom note types associated with Note instances in the database. """ - return list(self.note_types) + raise NotImplementedError def get_source_media_types(self): """ Return a list of all custom source media types associated with Source instances in the database. """ - return list(self.source_media_types) + raise NotImplementedError def get_url_types(self): """ Return a list of all custom names types associated with Url instances in the database. """ - return list(self.url_types) + raise NotImplementedError def remove_person(self, handle, transaction): """ @@ -2111,45 +1377,13 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - - if self.readonly or not handle: - return - 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: - transaction.add(PERSON_KEY, handle, person.serialize(), None) - transaction.person_del.append(str(handle)) + raise NotImplementedError def get_del_func(self, key): - key2del = { - PERSON_KEY: self.del_person, - FAMILY_KEY: self.del_family, - SOURCE_KEY: self.del_source, - EVENT_KEY: self.del_event, - MEDIA_KEY: self.del_media, - PLACE_KEY: self.del_place, - REPOSITORY_KEY: self.del_repository, - NOTE_KEY: self.del_note, - } - return key2del[key] - - def do_remove_object(self, handle, trans, dmap, key, del_list): - if self.readonly or not handle: - return - - handle = str(handle) - self.delete_primary_from_reference_map(handle, trans) - if trans.batch: - del_func = self.get_del_func(key) - del_func(handle) - else: - old_data = dmap.get(handle) - trans.add(key, handle, old_data, None) - del_list.append(handle) + """ + Returns the key of an object to delete + """ + raise NotImplementedError def remove_source(self, handle, transaction): """ @@ -2158,8 +1392,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.source_map, - SOURCE_KEY, transaction.source_del) + raise NotImplementedError def remove_event(self, handle, transaction): """ @@ -2168,8 +1401,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.event_map, - EVENT_KEY, transaction.event_del) + raise NotImplementedError def remove_object(self, handle, transaction): """ @@ -2178,8 +1410,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.media_map, - MEDIA_KEY, transaction.media_del) + raise NotImplementedError def remove_place(self, handle, transaction): """ @@ -2188,8 +1419,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.place_map, - PLACE_KEY, transaction.place_del) + raise NotImplementedError def remove_family(self, handle, transaction): """ @@ -2198,8 +1428,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.family_map, - FAMILY_KEY, transaction.family_del) + raise NotImplementedError def remove_repository(self, handle, transaction): """ @@ -2208,8 +1437,7 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.repository_map, - REPOSITORY_KEY, transaction.repository_del) + raise NotImplementedError def remove_note(self, handle, transaction): """ @@ -2218,282 +1446,229 @@ class GrampsDbBase(Callback): This method must be overridden in the derived class. """ - self.do_remove_object(handle, transaction, self.note_map, - NOTE_KEY, transaction.note_del) + raise NotImplementedError def get_raw_person_data(self, handle): - return self.person_map.get(str(handle)) + """ + Return raw (serialized and pickled) Person object from handle + """ + raise NotImplementedError def get_raw_family_data(self, handle): - return self.family_map.get(str(handle)) + """ + Return raw (serialized and pickled) Family object from handle + """ + raise NotImplementedError def get_raw_object_data(self, handle): - return self.media_map.get(str(handle)) + """ + Return raw (serialized and pickled) Family object from handle + """ + raise NotImplementedError def get_raw_place_data(self, handle): - return self.place_map.get(str(handle)) + """ + Return raw (serialized and pickled) Place object from handle + """ + raise NotImplementedError def get_raw_event_data(self, handle): - return self.event_map.get(str(handle)) + """ + Return raw (serialized and pickled) Event object from handle + """ + raise NotImplementedError def get_raw_source_data(self, handle): - return self.source_map.get(str(handle)) + """ + Return raw (serialized and pickled) Source object from handle + """ + raise NotImplementedError def get_raw_repository_data(self, handle): - return self.repository_map.get(str(handle)) + """ + Return raw (serialized and pickled) Repository object from handle + """ + raise NotImplementedError def get_raw_note_data(self, handle): - return self.note_map.get(str(handle)) + """ + Return raw (serialized and pickled) Note object from handle + """ + raise NotImplementedError def has_person_handle(self, handle): """ Return True if the handle exists in the current Person database. """ - return str(handle) in self.person_map + raise NotImplementedError def has_event_handle(self, handle): """ Return True if the handle exists in the current Event database. """ - return str(handle) in self.event_map + raise NotImplementedError def has_source_handle(self, handle): """ Return True if the handle exists in the current Source database. """ - return str(handle) in self.source_map + raise NotImplementedError def has_place_handle(self, handle): """ Return True if the handle exists in the current Place database. """ - return str(handle) in self.place_map + raise NotImplementedError def has_family_handle(self, handle): """ Return True if the handle exists in the current Family database. """ - return str(handle) in self.family_map + raise NotImplementedError def has_object_handle(self, handle): """ Return True if the handle exists in the current MediaObjectdatabase. """ - return str(handle) in self.media_map + raise NotImplementedError def has_repository_handle(self, handle): """ Return True if the handle exists in the current Repository database. """ - return str(handle) in self.repository_map + raise NotImplementedError def has_note_handle(self, handle): """ Return True if the handle exists in the current Note database. """ - return str(handle) in self.note_map - - def __sortbyplace(self, first, second): - return locale.strcoll(self.place_map.get(str(first))[2], - self.place_map.get(str(second))[2]) - - def __sortbyplace_key(self, place): - return locale.strxfrm(self.place_map.get(str(place))[2]) - - def __sortbysource(self, first, second): - source1 = unicode(self.source_map[str(first)][2]) - source2 = unicode(self.source_map[str(second)][2]) - return locale.strcoll(source1, source2) - - def __sortbysource_key(self, key): - source = unicode(self.source_map[str(key)][2]) - return locale.strxfrm(source) - - def __sortbymedia(self, first, second): - media1 = self.media_map[str(first)][4] - media2 = self.media_map[str(second)][4] - return locale.strcoll(media1, media2) - - def __sortbymedia_key(self, key): - media = self.media_map[str(key)][4] - return locale.strxfrm(media) + raise NotImplementedError def set_mediapath(self, path): """Set the default media path for database, path should be utf-8.""" - if (self.metadata is not None) and (not self.readonly): - self.metadata['mediapath'] = path + raise NotImplementedError def get_mediapath(self): """Return the default media path of the database.""" - if self.metadata is not None: - return self.metadata.get('mediapath', None) - return None - - def set_column_order(self, col_list, name): - if (self.metadata is not None) and (not self.readonly): - self.metadata[name] = col_list + raise NotImplementedError def set_person_column_order(self, col_list): """ Store the Person display common information in the database's metadata. """ - self.set_column_order(col_list, PERSON_COL_KEY) + raise NotImplementedError def set_family_list_column_order(self, col_list): """ Store the Person display common information in the database's metadata. """ - self.set_column_order(col_list, FAMILY_COL_KEY) + raise NotImplementedError def set_child_column_order(self, col_list): """ Store the Person display common information in the database's metadata. """ - self.set_column_order(col_list, CHILD_COL_KEY) + raise NotImplementedError def set_place_column_order(self, col_list): """ Store the Place display common information in the database's metadata. """ - self.set_column_order(col_list, PLACE_COL_KEY) + raise NotImplementedError def set_source_column_order(self, col_list): """ Store the Source display common information in the database's metadata. """ - self.set_column_order(col_list, SOURCE_COL_KEY) + raise NotImplementedError def set_media_column_order(self, col_list): """ Store the Media display common information in the database's metadata. """ - self.set_column_order(col_list, MEDIA_COL_KEY) + raise NotImplementedError def set_event_column_order(self, col_list): """ Store the Event display common information in the database's metadata. """ - self.set_column_order(col_list, EVENT_COL_KEY) + raise NotImplementedError def set_repository_column_order(self, col_list): """ Store the Repository display common information in the database's metadata. """ - self.set_column_order(col_list, REPOSITORY_COL_KEY) + raise NotImplementedError def set_note_column_order(self, col_list): """ Store the Note display common information in the database's metadata. """ - self.set_column_order(col_list, NOTE_COL_KEY) - - def __get_column_order(self, name, default): - if self.metadata is None: - return default - else: - cols = self.metadata.get(name, default) - if len(cols) != len(default): - return cols + default[len(cols):] - else: - return cols + raise NotImplementedError def get_person_column_order(self): """ Return the Person display common information stored in the database's metadata. """ - default = [(1, 1, 100), (1, 2, 100), (1, 3, 150), (0, 4, 150), - (1, 5, 150), (0, 6, 150), (0, 7, 100), (0, 8, 100), - ] - return self.__get_column_order(PERSON_COL_KEY, default) + raise NotImplementedError - def __get_columns(self, key, default): - values = self.__get_column_order(key, default) - new = [] - for val in values: - if len(val) == 2: - for x in default: - if val[1] == x[1]: - new.append((val[0], val[1], x[2])) - break - else: - new.append(val) - return new - def get_family_list_column_order(self): """ Return the Person display common information stored in the database's metadata. """ - default = [(1, 0, 75), (1, 1, 200), (1, 2, 200), (1, 3, 100), - (0, 4, 100)] - return self.__get_columns(FAMILY_COL_KEY, default) + raise NotImplementedError def get_child_column_order(self): """ Return the Person display common information stored in the database's metadata. """ - default = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), - (0, 6), (0, 7)] - return self.__get_column_order(CHILD_COL_KEY, default) + raise NotImplementedError def get_place_column_order(self): """ Return the Place display common information stored in thedatabase's metadata. """ - default = [(1, 0, 250), (1, 1, 75), (1, 11, 100), (0, 3, 100), - (1, 4, 100, ), (0, 5, 150), (1, 6, 150), (0, 7, 150), - (0, 8, 150), (0, 9, 150), (0, 10, 150),(0,2,100)] - return self.__get_columns(PLACE_COL_KEY, default) + raise NotImplementedError def get_source_column_order(self): """ Return the Source display common information stored in the database's metadata. """ - default = [(1, 0, 200), (1, 1, 75), (1, 2, 150), (0, 3, 100), - (1, 4, 150), (0, 5, 100)] - return self.__get_columns(SOURCE_COL_KEY, default) + raise NotImplementedError def get_media_column_order(self): """ Return the MediaObject display common information stored in the database's metadata. """ - default = [(1, 0, 200, ), (1, 1, 75), (1, 2, 100), (1, 3, 200), - (1, 5, 150), (0, 4, 150)] - return self.__get_columns(MEDIA_COL_KEY, default) + raise NotImplementedError def get_event_column_order(self): """ Return the Event display common information stored in the database's metadata. """ - default = [(1, 0, 200), (1, 1, 75), (1, 2, 100), - (0, 6, 230), (1, 3, 150), - (1, 4, 200), (0, 5, 100)] - return self.__get_columns(EVENT_COL_KEY, default) + raise NotImplementedError def get_repository_column_order(self): """ Return the Repository display common information stored in the database's metadata. """ - default = [(1, 0, 200), (1, 1, 75), (0, 5, 100), (0, 6, 100), - (1, 2, 100), (1, 3, 250), (1, 4, 100), (0, 7, 100), - (0, 8, 100), (0, 9, 100), (0, 10, 100), (0, 12, 100)] - return self.__get_columns(REPOSITORY_COL_KEY, default) + raise NotImplementedError def get_note_column_order(self): """ Return the Note display common information stored in the database's metadata. """ - default = [(1, 0, 350), (1, 1, 75), (1, 2, 100), (1, 3, 100)] - return self.__get_columns(NOTE_COL_KEY, default) + raise NotImplementedError def delete_primary_from_reference_map(self, handle, transaction): """ @@ -2502,7 +1677,7 @@ class GrampsDbBase(Callback): This can be used by subclasses to update any additional index tables that might need to be changed. """ - pass + raise NotImplementedError def update_reference_map(self, obj, transaction): """ @@ -2511,13 +1686,13 @@ class GrampsDbBase(Callback): This can be used by subclasses to update any additional index tables that might need to be changed. """ - pass + raise NotImplementedError def reindex_reference_map(self, callback): """ Reindex all primary records in the database. """ - pass + raise NotImplementedError def find_backlink_handles(self, handle, include_classes=None): """ @@ -2539,180 +1714,18 @@ class GrampsDbBase(Callback): Note that this is a generator function, it returns a iterator for use in loops. If you want a list of the results use: - > result_list = [i for i in find_backlink_handles(handle)] + > result_list = list(find_backlink_handles(handle)) """ - - # Make a dictionary of the functions and classes that we need for - # each of the primary object tables. - primary_tables = { - 'Person': {'cursor_func': self.get_person_cursor, - 'class_func': Person}, - 'Family': {'cursor_func': self.get_family_cursor, - 'class_func': Family}, - 'Event': {'cursor_func': self.get_event_cursor, - 'class_func': Event}, - 'Place': {'cursor_func': self.get_place_cursor, - 'class_func': Place}, - 'Source': {'cursor_func': self.get_source_cursor, - 'class_func': Source}, - 'MediaObject': {'cursor_func': self.get_media_cursor, - 'class_func': MediaObject}, - 'Repository': {'cursor_func': self.get_repository_cursor, - 'class_func': Repository}, - 'Note': {'cursor_func': self.get_note_cursor, - 'class_func': Note}, - } - - - # Find which tables to iterate over - if (include_classes is None): - the_tables = primary_tables.keys() - else: - the_tables = include_classes - - # Now we use the functions and classes defined above to loop through - # each of the existing primary object tables - for primary_table_name, funcs in the_tables.iteritems(): - with funcs['cursor_func']() as cursor: - - # Grab the real object class here so that the lookup does - # not happen inside the main loop. - class_func = funcs['class_func'] - for found_handle, val in cursor: - obj = class_func() - obj.unserialize(val) - - # Now we need to loop over all object types - # that have been requests in the include_classes list - for classname in primary_tables: - if obj.has_handle_reference(classname, handle): - yield (primary_table_name, found_handle) - return + raise NotImplementedError def report_bm_change(self): """ Add 1 to the number of bookmark changes during this session. """ - self._bm_changes += 1 + raise NotImplementedError def db_has_bm_changes(self): """ Return whethere there were bookmark changes during the session. """ - return self._bm_changes > 0 - -class Transaction(object): - """ - Define a group of database commits that define a single logical operation. - """ - def __init__(self, msg, db, batch=False, no_magic=False): - """ - Create a new transaction. - - A Transaction instance should not be created directly, but by the - GrampsDbBase class or classes derived from GrampsDbBase. The db - parameter is a list-like interface that stores the commit data. This - could be a simple list, or a RECNO-style database object. - - The batch parameter is set to True for large transactions. For such - transactions, the list of changes is not maintained, and no undo - is possible. - - The no_magic parameter is ignored for non-batch transactions, and - is also of no importance for DB backends other than BSD DB. For - the BSDDB, when this paramter is set to True, some secondary - indices will be removed at the beginning and then rebuilt at - the end of such transaction (only if it is batch). - """ - self.db = db - self.first = None - self.last = None - self.batch = batch - self.no_magic = no_magic - self.length = 0 - self.timestamp = 0 - - self.person_add = [] - self.person_del = [] - self.person_update = [] - - self.family_add = [] - self.family_del = [] - self.family_update = [] - - self.source_add = [] - self.source_del = [] - self.source_update = [] - - self.event_add = [] - self.event_del = [] - self.event_update = [] - - self.media_add = [] - self.media_del = [] - self.media_update = [] - - self.place_add = [] - self.place_del = [] - self.place_update = [] - - self.repository_add = [] - self.repository_del = [] - self.repository_update = [] - - self.note_add = [] - self.note_del = [] - self.note_update = [] - - def get_description(self): - """ - Return the text string that describes the logical operation performed - by the Transaction. - """ - return self.msg - - def set_description(self, msg): - """ - Set the text string that describes the logical operation performed by - the Transaction. - """ - self.msg = msg - - def add(self, obj_type, handle, old_data, new_data): - """ - Add a commit operation to the Transaction. - - The obj_type is a constant that indicates what type of PrimaryObject - is being added. The handle is the object's database handle, and the - data is the tuple returned by the object's serialize method. - """ - self.last = self.db.append( - cPickle.dumps((obj_type, handle, old_data, new_data), 1)) - if self.first is None: - self.first = self.last - - def get_recnos(self): - """ - Return a list of record numbers associated with the transaction. - - While the list is an arbitrary index of integers, it can be used - to indicate record numbers for a database. - """ - return range (self.first, self.last+1) - - def get_record(self, recno): - """ - Return a tuple representing the PrimaryObject type, database handle - for the PrimaryObject, and a tuple representing the data created by - the object's serialize method. - """ - return cPickle.loads(self.db[recno]) - - def __len__(self): - """ - Return the number of commits associated with the Transaction. - """ - if self.last and self.first: - return self.last - self.first + 1 - return 0 - + raise NotImplementedError diff --git a/src/gen/db/dbconst.py b/src/gen/db/dbconst.py index e577cb361..6c1040cff 100644 --- a/src/gen/db/dbconst.py +++ b/src/gen/db/dbconst.py @@ -20,6 +20,10 @@ # $Id$ +""" +Declare constants used by database modules +""" + #------------------------------------------------------------------------- # # standard python modules @@ -31,6 +35,44 @@ # constants # #------------------------------------------------------------------------- +__all__ = ( + ('DBPAGE', 'DBMODE', 'DBCACHE', 'DBLOCKS', 'DBOBJECTS', 'DBUNDO', + 'DBEXT', 'DBMODE_R', 'DBMODE_W', 'DBUNDOFN', 'DBLOCKFN', + 'DBRECOVFN', 'DBLOGNAME', 'DBFLAGS_O', 'DBFLAGS_R', 'DBFLAGS_D', + ) + + + ('PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'EVENT_KEY', + 'MEDIA_KEY', 'PLACE_KEY', 'REPOSITORY_KEY', 'NOTE_KEY', + 'REFERENCE_KEY', 'PERSON_COL_KEY', 'FAMILY_COL_KEY', + 'CHILD_COL_KEY' + ) + + + ('PERSON_COL_KEY', 'FAMILY_COL_KEY', 'CHILD_COL_KEY', + 'PLACE_COL_KEY', 'SOURCE_COL_KEY', 'MEDIA_COL_KEY', + 'EVENT_COL_KEY', 'REPOSITORY_COL_KEY', 'NOTE_COL_KEY' + ) + + + ('TXNADD', 'TXNUPD', 'TXNDEL') + ) + +DBEXT = ".db" # File extension to be used for database files +DBUNDOFN = "undo.db" # File name of 'undo' database +DBLOCKFN = "lock" # File name of lock file +DBRECOVFN = "need_recover" # File name of recovery file +DBLOGNAME = ".GrampsDb" # Name of logger +DBMODE_R = "r" # Read-only access +DBMODE_W = "w" # Full Reaw/Write access +DBPAGE = 16384 # Size of the pages used to hold items in the database +DBMODE = 0666 # Unix mode for database creation +DBCACHE = 0x4000000 # Size of the shared memory buffer pool +DBLOCKS = 25000 # Maximum number of locks supported +DBOBJECTS = 25000 # Maximum number of simultaneously locked objects +DBUNDO = 1000 # Maximum size of undo buffer + +from bsddb.db import DB_CREATE, DB_AUTO_COMMIT, DB_DUP, DB_DUPSORT, DB_RDONLY +DBFLAGS_O = DB_CREATE | DB_AUTO_COMMIT # Default flags for database open +DBFLAGS_R = DB_RDONLY # Flags to open a database read-only +DBFLAGS_D = DB_DUP | DB_DUPSORT # Default flags for duplicate keys PERSON_KEY = 0 FAMILY_KEY = 1 @@ -51,3 +93,5 @@ REPOSITORY_COL_KEY = 'repository_columns' EVENT_COL_KEY = 'event_columns' FAMILY_COL_KEY = 'family_columns' NOTE_COL_KEY = 'note_columns' + +TXNADD, TXNUPD, TXNDEL = 0, 1, 2 diff --git a/src/gen/db/write.py b/src/gen/db/write.py index 87e1f0166..468db9fb1 100644 --- a/src/gen/db/write.py +++ b/src/gen/db/write.py @@ -1102,8 +1102,6 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): if not obj.handle: obj.handle = self.create_id() commit_func(obj, transaction) - if obj.__class__.__name__ == 'Person': - self.genderStats.count_person (obj) return obj.handle def add_person(self, person, transaction, set_gid=True): @@ -1113,9 +1111,11 @@ class GrampsDBDir(GrampsDbRead, Callback, UpdateCallback): If not set_gid, then gramps_id is not set. """ - return self.__add_object(person, transaction, + handle = self.__add_object(person, transaction, self.find_next_person_gramps_id if set_gid else None, self.commit_person) + self.genderStats.count_person(person) + return handle def add_family(self, family, transaction, set_gid=True): """ diff --git a/src/gui/viewmanager.py b/src/gui/viewmanager.py index 60e112f48..ca0ce87e9 100644 --- a/src/gui/viewmanager.py +++ b/src/gui/viewmanager.py @@ -644,7 +644,7 @@ class ViewManager(CLIManager): """ import GrampsDbUtils - if self.dbstate.db.undoindex >= 0: + if self.dbstate.db.has_changed: self.uistate.set_busy_cursor(1) self.uistate.progress.show() self.uistate.push_message(self.dbstate, _("Autobackup...")) diff --git a/src/plugins/import/ImportGedcom.py b/src/plugins/import/ImportGedcom.py index daaaa01b3..3c33be03d 100644 --- a/src/plugins/import/ImportGedcom.py +++ b/src/plugins/import/ImportGedcom.py @@ -48,6 +48,7 @@ from GrampsDbUtils._GedcomStageOne import StageOne from QuestionDialog import ErrorDialog, DBErrorDialog from gen.plug import PluginManager, ImportPlugin from glade import Glade +from libmixin import GrampsDbMixin try: import Config @@ -65,6 +66,11 @@ def importData(database, filename, callback=None): """ Try to handle ANSEL encoded files that are not really ANSEL encoded """ + + if GrampsDbMixin not in database.__class__.__bases__: + database.__class__.__bases__ = (GrampsDbMixin,) + \ + database.__class__.__bases__ + try: ifile = open(filename, "r") except IOError: diff --git a/src/plugins/import/ImportGrdb.py b/src/plugins/import/ImportGrdb.py index a055db2a7..3a36c9cf2 100644 --- a/src/plugins/import/ImportGrdb.py +++ b/src/plugins/import/ImportGrdb.py @@ -48,12 +48,11 @@ __LOG = logging.getLogger(".GrampsDb") from gen.lib import (GenderStats, Source, Person, Family, Event, Place, MediaObject, Repository, Note, Attribute, AttributeType, NoteType) -from gen.db.base import (GrampsDbBase, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP, - Transaction) +from gen.db.write import (GrampsDBDir, KEY_TO_CLASS_MAP, CLASS_TO_KEY_MAP) +from libgrdb import GrampsDbGrdb +from gen.db.txn import GrampsDbTxn as Transaction from gen.db.cursor import GrampsCursor -from gen.db.dbconst import (REFERENCE_KEY, PERSON_COL_KEY, EVENT_COL_KEY, - EVENT_KEY, FAMILY_KEY, SOURCE_KEY, PLACE_KEY, - MEDIA_KEY, REPOSITORY_KEY, PERSON_KEY, NOTE_KEY) +from gen.db.dbconst import * from gen.db.exceptions import FileVersionError from gen.utils import db_copy import const @@ -136,7 +135,7 @@ class GrampsBSDDBDupCursor(GrampsBSDDBAssocCursor): # GrampsBSDDB # #------------------------------------------------------------------------- -class GrampsBSDDB(GrampsDbBase, UpdateCallback): +class GrampsBSDDB(GrampsDbGrdb, UpdateCallback): """ GRAMPS database object for Berkeley DB. This is replaced for internal use by gen/db/dbdir.py However, this class is still used for import of the 2.2.x @@ -146,7 +145,7 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): def __init__(self, use_txn = True): """creates a new GrampsDB""" - GrampsDbBase.__init__(self) + GrampsDbGrdb.__init__(self) #UpdateCallback.__init__(self) self.txn = None self.secondary_connected = False @@ -460,7 +459,6 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): # If secondary indices change, then they should removed # or rebuilt by upgrade as well. In any case, the # self.secondary_connected flag should be set accordingly. - if self.need_upgrade(): self.gramps_upgrade(callback) @@ -471,10 +469,10 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): self.db_is_open = True # Re-set the undo history to a fresh session start - self.undoindex = -1 - self.translist = [None] * len(self.translist) + #self.undoindex = -1 + #self.translist = [None] * len(self.translist) self.abort_possible = True - self.undo_history_timestamp = time.time() + #self.undo_history_timestamp = time.time() return 1 @@ -772,7 +770,6 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): while (ret is not None): (key, data) = ret - print key, data # data values are of the form: # ((primary_object_class_name, primary_object_handle), @@ -1461,8 +1458,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): # Aborting the session completely will become impossible. self.abort_possible = False # Undo is also impossible after batch transaction - self.undoindex = -1 - self.translist = [None] * len(self.translist) + #self.undoindex = -1 + #self.translist = [None] * len(self.translist) transaction = BdbTransaction(msg, self.undodb, batch, no_magic) if transaction.batch: if self.UseTXN: @@ -2665,9 +2662,9 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback): class BdbTransaction(Transaction): def __init__(self, msg, db, batch=False, no_magic=False): - Transaction.__init__(self, msg, db, batch, no_magic) - self.reference_del = [] - self.reference_add = [] + Transaction.__init__(self, msg, db) + self.batch = batch + self.no_magic = no_magic def convert_name_10(name): # Names lost the "sname" attribute @@ -2697,7 +2694,6 @@ def convert_location_11(loc): # #------------------------------------------------------------------------- def importData(database, filename, callback=None, cl=0): - other_database = GrampsBSDDB() # Since we don't want to modify the file being imported, diff --git a/src/plugins/import/ImportXml.py b/src/plugins/import/ImportXml.py index 68cbdc89a..1a45e3b24 100644 --- a/src/plugins/import/ImportXml.py +++ b/src/plugins/import/ImportXml.py @@ -49,6 +49,7 @@ from BasicUtils import UpdateCallback import const from gen.plug import PluginManager, ImportPlugin import libgrampsxml +from libmixin import GrampsDbMixin #------------------------------------------------------------------------- # @@ -83,6 +84,10 @@ EVENT_PERSON_STR = _("%(event_name)s of %(person)s") #------------------------------------------------------------------------- def importData(database, filename, callback=None, cl=0): + if GrampsDbMixin not in database.__class__.__bases__: + database.__class__.__bases__ = (GrampsDbMixin,) + \ + database.__class__.__bases__ + filename = os.path.normpath(filename) basefile = os.path.dirname(filename) database.smap = {} diff --git a/src/plugins/tool/Check.py b/src/plugins/tool/Check.py index 81af55e73..171601335 100644 --- a/src/plugins/tool/Check.py +++ b/src/plugins/tool/Check.py @@ -114,8 +114,8 @@ def _table_low_level(db,table): return True # import gen.db - from gen.db import GrampsDBDirDupCursor - table_cursor = GrampsDBDirDupCursor(table) + from gen.db import GrampsDBDirAssocCursor + table_cursor = GrampsDBDirAssocCursor(table) for handle in dup_handles: print " Duplicates found for handle: %s" % handle try: