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.
This commit is contained in:
Nick Hall 2017-10-12 23:15:17 +01:00
parent 8ef49ed303
commit 875242c8d6
11 changed files with 70 additions and 47 deletions

View File

@ -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

View File

@ -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.

View File

@ -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__":

View File

@ -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()])

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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,

View File

@ -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:

View File

@ -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)

View File

@ -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: