From 875242c8d6f88e91dd839812f11b92a9326d30a2 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 12 Oct 2017 23:15:17 +0100 Subject: [PATCH] New convenience function to return database methods Examples: db.method('get_%s_from_handle', 'Person') db.method('get_%s_from_%s', 'Event', 'gramps_id') Returns None if the method doesn't exist. Formats 'iter_%s' and 'get_number_of_%s' use the plural forms and are not yet implemented. Replaces old get_table_metadata method. Issue #9541. --- gramps/gen/db/base.py | 28 ++++++++++++++++++++++++ gramps/gen/db/generic.py | 10 --------- gramps/gen/lib/test/serialize_test.py | 7 +++--- gramps/gen/merge/diff.py | 8 +++---- gramps/gen/simple/_simpleaccess.py | 17 +++++++------- gramps/gui/clipboard.py | 2 +- gramps/gui/editors/__init__.py | 20 ++++++++++++++--- gramps/gui/editors/editlink.py | 5 +++-- gramps/gui/views/listview.py | 4 +--- gramps/plugins/db/bsddb/read.py | 10 --------- gramps/plugins/webreport/narrativeweb.py | 6 ++--- 11 files changed, 70 insertions(+), 47 deletions(-) diff --git a/gramps/gen/db/base.py b/gramps/gen/db/base.py index 13345f340..832630957 100644 --- a/gramps/gen/db/base.py +++ b/gramps/gen/db/base.py @@ -1433,6 +1433,34 @@ class DbReadBase: """ return False + def method(self, fmt, *args): + """ + Convenience function to return database methods. + + :param fmt: Method format string. + :type fmt: str + :param args: Substitutions arguments. + :type args: str + :returns: Returns a database method or None. + :rtype: method + + Examples:: + + db.method('get_%s_from_handle, 'Person') + Returns the get_person_from_handle method. + + db.method('get_%s_from_%s, 'Event', 'gramps_id') + Returns the get_event_from_gramps_id method. + + db.method('get_%s_handles, 'Attribute') + Returns None. Attribute is not a primary object. + + .. warning:: Formats 'iter_%s' and 'get_number_of_%s' are not yet + implemented. + """ + return getattr(self, fmt % tuple([arg.lower() for arg in args]), None) + + class DbWriteBase(DbReadBase): """ Gramps database object. This object is a base class for all diff --git a/gramps/gen/db/generic.py b/gramps/gen/db/generic.py index 439e3c442..10b295240 100644 --- a/gramps/gen/db/generic.py +++ b/gramps/gen/db/generic.py @@ -779,16 +779,6 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback): else: return None - def get_table_names(self): - """Return a list of valid table names.""" - return list(self._get_table_func()) - - def get_table_metadata(self, table_name): - """Return the metadata for a valid table name.""" - if table_name in self._get_table_func(): - return self._get_table_func(table_name) - return None - def _txn_begin(self): """ Lowlevel interface to the backend transaction. diff --git a/gramps/gen/lib/test/serialize_test.py b/gramps/gen/lib/test/serialize_test.py index 37754fc47..6b6188802 100644 --- a/gramps/gen/lib/test/serialize_test.py +++ b/gramps/gen/lib/test/serialize_test.py @@ -114,9 +114,10 @@ def generate_case(obj): #setattr(DatabaseCheck, name, test2) db = import_as_dict(EXAMPLE, User()) -for table in db.get_table_names(): - for handle in db.get_table_metadata(table)["handles_func"](): - obj = db.get_table_metadata(table)["handle_func"](handle) +for obj_class in ('Person', 'Family', 'Event', 'Place', 'Repository', 'Source', + 'Citation', 'Media', 'Note'): + for handle in db.method('get_%s_handles', obj_class)(): + obj = db.method('get_%s_from_handle', obj_class)(handle) generate_case(obj) if __name__ == "__main__": diff --git a/gramps/gen/merge/diff.py b/gramps/gen/merge/diff.py index 033c6bd62..5fed59304 100644 --- a/gramps/gen/merge/diff.py +++ b/gramps/gen/merge/diff.py @@ -109,10 +109,10 @@ def diff_dbs(db1, db2, user): 'Place', 'Repository', 'Note', 'Tag']: step() - handles_func1 = db1.get_table_metadata(item)["handles_func"] - handles_func2 = db2.get_table_metadata(item)["handles_func"] - handle_func1 = db1.get_table_metadata(item)["handle_func"] - handle_func2 = db2.get_table_metadata(item)["handle_func"] + handles_func1 = db1.method('get_%s_handles', item) + handles_func2 = db2.method('get_%s_handles', item) + handle_func1 = db1.method('get_%s_from_handle', item) + handle_func2 = db2.method('get_%s_from_handle', item) handles1 = sorted([handle for handle in handles_func1()]) handles2 = sorted([handle for handle in handles_func2()]) diff --git a/gramps/gen/simple/_simpleaccess.py b/gramps/gen/simple/_simpleaccess.py index 2b9e38d07..6df4d4839 100644 --- a/gramps/gen/simple/_simpleaccess.py +++ b/gramps/gen/simple/_simpleaccess.py @@ -961,10 +961,10 @@ class SimpleAccess: :param prop: "gramps_id", or "handle" :param value: gramps_id or handle. """ - if object_class in self.dbase.get_table_names(): + func = self.dbase.method('get_%s_from_%s', object_class, prop) + if func: try: - obj = self.dbase.get_table_metadata( - object_class)[prop + "_func"](value) + obj = func(value) except HandleError: # Deals with deleted objects referenced in Note Links obj = None @@ -1021,8 +1021,9 @@ class SimpleAccess: Given a object, return a string describing the object. """ if prop and value: - if self.dbase.get_table_metadata(obj): - obj = self.dbase.get_table_metadata(obj)[prop + "_func"](value) + func = self.dbase.method('get_%s_from_%s', object_class, prop) + if func: + obj = func(value) if isinstance(obj, Person): return "%s [%s]" % (self.name(obj), self.gid(obj)) @@ -1064,6 +1065,6 @@ class SimpleAccess: :param prop: "gramps_id", or "handle" :param value: gramps_id or handle. """ - if object_class in self.dbase.get_table_names(): - return self.dbase.get_table_metadata(object_class) \ - [prop + "_func"](value) + func = self.dbase.method('get_%s_from_%s', object_class, prop) + if func: + return func(value) diff --git a/gramps/gui/clipboard.py b/gramps/gui/clipboard.py index bd09f32e1..10c15148b 100644 --- a/gramps/gui/clipboard.py +++ b/gramps/gui/clipboard.py @@ -1573,7 +1573,7 @@ class MultiTreeView(Gtk.TreeView): o = store.get_value(node, 1) if o._objclass == objclass: my_handle = o._handle - obj = self.dbstate.db.get_table_metadata(objclass)["handle_func"](my_handle) + obj = self.dbstate.db.method('get_%s_from_handle', objclass)(my_handle) if obj: gids.add(obj.gramps_id) menu_item = Gtk.MenuItem(label=_("the object|Create Filter from %s selected...") % glocale.trans_objclass(objclass)) diff --git a/gramps/gui/editors/__init__.py b/gramps/gui/editors/__init__.py index cd3fe1b9f..4e94ecc54 100644 --- a/gramps/gui/editors/__init__.py +++ b/gramps/gui/editors/__init__.py @@ -46,6 +46,8 @@ from .edittaglist import EditTagList from .editurl import EditUrl from .editlink import EditLink from .filtereditor import FilterEditor, EditFilter +from gramps.gen.lib import (Person, Family, Event, Place, Repository, Source, + Citation, Media, Note) # Map from gramps.gen.lib name to Editor: EDITORS = { @@ -60,6 +62,18 @@ EDITORS = { 'Note': EditNote, } +CLASSES = { + 'Person': Person, + 'Event': Event, + 'Family': Family, + 'Media': Media, + 'Source': Source, + 'Citation': Citation, + 'Place': Place, + 'Repository': Repository, + 'Note': Note, + } + def EditObject(dbstate, uistate, track, obj_class, prop=None, value=None, callback=None): """ Generic Object Editor. @@ -69,15 +83,15 @@ def EditObject(dbstate, uistate, track, obj_class, prop=None, value=None, callba """ import logging LOG = logging.getLogger(".Edit") - if obj_class in dbstate.db.get_table_names(): + if obj_class in EDITORS.keys(): if value is None: - obj = dbstate.db.get_table_metadata(obj_class)["class_func"]() + obj = CLASSES[obj_class] try: EDITORS[obj_class](dbstate, uistate, track, obj, callback=callback) except Exception as msg: LOG.warning(str(msg)) elif prop in ("gramps_id", "handle"): - obj = dbstate.db.get_table_metadata(obj_class)[prop + "_func"](value) + obj = dbstate.db.method('get_%s_from_%s', obj_class, prop)(value) if obj: try: EDITORS[obj_class](dbstate, uistate, track, obj, callback=callback) diff --git a/gramps/gui/editors/editlink.py b/gramps/gui/editors/editlink.py index 44724b485..52b482500 100644 --- a/gramps/gui/editors/editlink.py +++ b/gramps/gui/editors/editlink.py @@ -189,8 +189,9 @@ class EditLink(ManagedWindow): if prop == "handle": default = value elif (prop == "gramps_id" and - object_class in self.dbstate.db.get_table_names()): - person = self.dbstate.db.get_table_metadata(object_class)["gramps_id_func"](value) + object_class in OBJECT_MAP.values()): + person = self.dbstate.db.method('get_%s_from_gramps_id', + object_class)(value) if person: default = person.handle d = Select(self.dbstate, self.uistate, self.track, diff --git a/gramps/gui/views/listview.py b/gramps/gui/views/listview.py index b4d83b85d..b827180d3 100644 --- a/gramps/gui/views/listview.py +++ b/gramps/gui/views/listview.py @@ -808,11 +808,9 @@ class ListView(NavigationView): self.build_tree() # Reselect one, if it still exists after rebuild: nav_type = self.navigation_type() - lookup_handle = self.dbstate.db.get_table_metadata(nav_type)['handle_func'] + lookup_handle = getattr(self.dbstate.db, 'get_%s_from_handle' % nav_type) for handle in selected_ids: # Still exist? - # should really use db.has_handle(nav_type, handle) but doesn't - # exist for bsddb try: lookup_handle(handle) # Select it, and stop selecting: diff --git a/gramps/plugins/db/bsddb/read.py b/gramps/plugins/db/bsddb/read.py index 714cf26df..e234e30d0 100644 --- a/gramps/plugins/db/bsddb/read.py +++ b/gramps/plugins/db/bsddb/read.py @@ -478,16 +478,6 @@ class DbBsddbRead(DbReadBase, Callback): else: return None - def get_table_names(self): - """Return a list of valid table names.""" - return list(self._get_table_func()) - - def get_table_metadata(self, table_name): - """Return the metadata for a valid table name.""" - if table_name in self._get_table_func(): - return self._get_table_func(table_name) - return None - def set_prefixes(self, person, media, family, source, citation, place, event, repository, note): self.set_person_id_prefix(person) diff --git a/gramps/plugins/webreport/narrativeweb.py b/gramps/plugins/webreport/narrativeweb.py index 0c2fc8889..7a35cb776 100644 --- a/gramps/plugins/webreport/narrativeweb.py +++ b/gramps/plugins/webreport/narrativeweb.py @@ -1280,9 +1280,9 @@ class NavWebReport(Report): @param: obj_class -- The class of the related object. """ if prop == "gramps_id": - if obj_class in self._db.get_table_names(): - obj = self._db.get_table_metadata(obj_class)[ - "gramps_id_func"](handle) + func = self._db.method('get_%s_from_gramps_id', obj_class) + if func: + obj = func(handle) if obj: handle = obj.handle else: