From 048151f447d5a3e5d221241c029657bd4e0b5c79 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Fri, 22 Apr 2016 07:52:34 -0400 Subject: [PATCH] 9383: the Family Tree Manager dialog should show the database type --- gramps/cli/argparser.py | 24 ++++++++++++---- gramps/cli/clidbman.py | 4 +-- gramps/gen/const.py | 22 ++------------- gramps/gen/db/generic.py | 4 +-- gramps/grampsapp.py | 22 +++++++++++++-- .../plugins/database/bsddb_support/write.py | 28 +++++++++++++++++-- gramps/plugins/database/dbapi.py | 20 +++++++++++++ .../plugins/database/dbapi_support/mysql.py | 15 ++++++++++ .../database/dbapi_support/postgresql.py | 15 ++++++++++ .../plugins/database/dbapi_support/sqlite.py | 15 ++++++++++ gramps/plugins/database/inmemorydb.py | 7 +++++ 11 files changed, 143 insertions(+), 33 deletions(-) diff --git a/gramps/cli/argparser.py b/gramps/cli/argparser.py index 42039fd39..1381116db 100644 --- a/gramps/cli/argparser.py +++ b/gramps/cli/argparser.py @@ -43,7 +43,8 @@ import logging # gramps modules # #------------------------------------------------------------------------- -from gramps.gen.const import LONGOPTS, SHORTOPTS +from gramps.gen.const import LONGOPTS, SHORTOPTS, PLUGINS_DIR, USER_PLUGINS +from gramps.gen.plug import BasePluginManager from gramps.gen.config import config from gramps.gen.utils.cast import get_type_converter from gramps.gen.const import GRAMPS_LOCALE as glocale @@ -76,6 +77,7 @@ Application options -y, --yes Don't ask to confirm dangerous actions (non-GUI mode only) -q, --quiet Suppress progress indication output (non-GUI mode only) -v, --version Show versions + -b, --databases Show available database backends """) _USAGE = _(""" @@ -152,6 +154,7 @@ class ArgParser(object): -y, --yes Don't ask to confirm dangerous actions -q, --quiet Suppress progress indication output -v, --version Show versions + -b, --databases Show available database backends -h, --help Display the help --usage Display usage information @@ -206,7 +209,6 @@ class ArgParser(object): self.usage = False self.force_unlock = False self.create = None - self.runqml = False self.quiet = False self.auto_accept = False @@ -319,6 +321,20 @@ class ArgParser(object): repr(config.data[section][setting]))) print() sys.exit(0) + elif option in ['-b','--databases']: + default = config.data["behavior"]["database-backend"] + pmgr = BasePluginManager.get_instance() + pmgr.reg_plugins(PLUGINS_DIR, self, None) + pmgr.reg_plugins(USER_PLUGINS, self, None, load_on_reg=True) + for plugin in pmgr.get_reg_databases(): + pdata = pmgr.get_plugin(plugin.id) + mod = pmgr.load_plugin(pdata) + database = getattr(mod, pdata.databaseclass) + summary = database.get_class_summary() + print("Database backend ID:", pdata.id, "(default)" if pdata.id == default else "") + for key in sorted(summary.keys()): + print(" ", "%s:" % key, summary[key]) + sys.exit(0) elif option in ['-c', '--config']: setting_name = value set_value = False @@ -361,8 +377,6 @@ class ArgParser(object): self.force_unlock = True elif option in ['--usage']: self.usage = True - elif option in ['--qml']: - self.runqml = True elif option in ['-y', '--yes']: self.auto_accept = True elif option in ['-q', '--quiet']: @@ -376,7 +390,7 @@ class ArgParser(object): if (len(options) > 0 and self.open is None and self.imports == [] and self.removes == [] and not (self.list or self.list_more or self.list_table or - self.help or self.runqml)): + self.help)): # Extract and convert to unicode the arguments in the list. # The % operator replaces the list elements with repr() of # the list elements, which is OK for latin characters diff --git a/gramps/cli/clidbman.py b/gramps/cli/clidbman.py index f32641b3b..8c0e9e3fb 100644 --- a/gramps/cli/clidbman.py +++ b/gramps/cli/clidbman.py @@ -143,7 +143,7 @@ class CLIDbManager(object): _("Path") _("Family Tree") _("Last accessed") - _("Database backend") + _("Database") _("Locked?") and these details: @@ -168,7 +168,7 @@ class CLIDbManager(object): retval = {_("Unavailable"): "locked"} retval.update({_("Family Tree"): name, _("Path"): dirpath, - _("Database backend"): dbid, + _("Database"): dbid, _("Last accessed"): time_val(dirpath)[1], _("Locked?"): self.is_locked(dirpath), }) diff --git a/gramps/gen/const.py b/gramps/gen/const.py index 23e55b1f6..138df4891 100644 --- a/gramps/gen/const.py +++ b/gramps/gen/const.py @@ -258,30 +258,12 @@ ARABIC_SEMICOLON = "؛" # #------------------------------------------------------------------------- -# Note: Make sure to edit argparser.py _help string too! -# (longName, shortName, type , default, flags, descrip , argDescrip) -POPT_TABLE = [ - ("config", 'c', str, None, 0, "Set config setting(s) and start Gramps", ""), - ("open", 'O', str, None, 0, "Open family tree", "FAMILY_TREE"), - ("create", 'C', str, None, 0, "Create or Open family tree", "FAMILY_TREE"), - ("import", 'i', str, None, 0, "Import file", "FILENAME"), - ("export", 'e', str, None, 0, "Export file", "FILENAME"), - ("format", 'f', str, None, 0, 'Specify format', "FORMAT"), - ("action", 'a', str, None, 0, 'Specify action', "ACTION"), - ("options", 'p', str, None, 0, 'Specify options', "OPTIONS_STRING"), - ("debug", 'd', str, None, 0, 'Enable debug logs', "LOGGER_NAME"), - ("", 'l', None, None, 0, 'List Family Trees', ""), - ("", 'L', None, None, 0, 'List Family Tree Details', ""), - ("show", 's', None, None, 0, "Show config settings", ""), - ("force-unlock", 'u', None, None, 0, 'Force unlock of family tree', ""), - ("version", 'v', None, None, 0, 'Show versions', ""), -] - LONGOPTS = [ "action=", "class=", "config=", "debug=", + "databases", "display=", "disable-sound", "disable-crash-dialog", @@ -321,7 +303,7 @@ LONGOPTS = [ "quiet", ] -SHORTOPTS = "O:C:i:e:f:a:p:d:c:r:lLthuv?syq" +SHORTOPTS = "O:C:i:e:f:a:p:d:c:r:blLthuv?syq" GRAMPS_UUID = uuid.UUID('516cd010-5a41-470f-99f8-eb22f1098ad6') diff --git a/gramps/gen/db/generic.py b/gramps/gen/db/generic.py index e3f9ff030..021277814 100644 --- a/gramps/gen/db/generic.py +++ b/gramps/gen/db/generic.py @@ -1990,7 +1990,7 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback): _("Number of people") _("Version") - _("Schema version") + _("Data version") """ return { _("Number of people"): self.get_number_of_people(), @@ -2003,7 +2003,7 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback): _("Number of repositories"): self.get_number_of_repositories(), _("Number of notes"): self.get_number_of_notes(), _("Number of tags"): self.get_number_of_tags(), - _("Schema version"): ".".join([str(v) for v in self.VERSION]), + _("Data version"): ".".join([str(v) for v in self.VERSION]), } def get_dbname(self): diff --git a/gramps/grampsapp.py b/gramps/grampsapp.py index 594f942ca..067e3f081 100644 --- a/gramps/grampsapp.py +++ b/gramps/grampsapp.py @@ -280,9 +280,19 @@ def show_settings(): bsddb_str = bsddb.__version__ bsddb_db_str = str(bsddb.db.version()).replace(', ', '.')\ .replace('(', '').replace(')', '') + bsddb_location_str = bsddb.__file__ except: bsddb_str = 'not found' bsddb_db_str = 'not found' + bsddb_location_str = 'not found' + + try: + import sqlite3 + sqlite3_version_str = sqlite3.version + sqlite3_location_str = sqlite3.__file__ + except: + sqlite3_version_str = 'not found' + sqlite3_location_str = 'not found' try: from .gen.const import VERSION @@ -335,8 +345,6 @@ def show_settings(): print(' gtk++ : %s' % gtkver_str) print(' pygobject : %s' % pygobjectver_str) print(' pango : %s' % pangover_str) - print(' bsddb : %s' % bsddb_str) - print(' bsddb.db : %s' % bsddb_db_str) print(' cairo : %s' % cairover_str) print(' pycairo : %s' % pycairover_str) print(' osmgpsmap : %s' % osmgpsmap_str) @@ -368,6 +376,16 @@ def show_settings(): for folder in os_path: print(" ", folder) print('') + print("Databases:") + print("-------------------------") + print(' bsddb :') + print(' version : %s' % bsddb_str) + print(' db version : %s' % bsddb_db_str) + print(' location : %s' % bsddb_location_str) + print(' sqlite3 :') + print(' version : %s' % sqlite3_version_str) + print(' location : %s' % sqlite3_location_str) + print('') def run(): error = [] diff --git a/gramps/plugins/database/bsddb_support/write.py b/gramps/plugins/database/bsddb_support/write.py index 626f4ce62..49f7f25f8 100644 --- a/gramps/plugins/database/bsddb_support/write.py +++ b/gramps/plugins/database/bsddb_support/write.py @@ -38,6 +38,7 @@ import bisect from functools import wraps import logging from sys import maxsize, getfilesystemencoding, version_info +from ast import literal_eval as safe_eval from bsddb3 import dbshelve, db from bsddb3.db import DB_CREATE, DB_AUTO_COMMIT, DB_DUP, DB_DUPSORT, DB_RDONLY @@ -208,6 +209,27 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): Gramps database write access object. """ + @classmethod + def get_class_summary(cls): + """ + Return a diction of information about this database. + """ + try: + import bsddb3 as bsddb + bsddb_str = bsddb.__version__ + bsddb_db_str = str(bsddb.db.version()).replace(', ', '.')\ + .replace('(', '').replace(')', '') + except: + bsddb_str = 'not found' + bsddb_db_str = 'not found' + summary = { + "DB-API version": "n/a", + "Database type": cls.__name__, + 'Database version': bsddb_str, + 'Database db version': bsddb_db_str + } + return summary + # Set up dictionary for callback signal handler # --------------------------------------------- # 1. Signals for primary objects @@ -2517,9 +2539,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): if os.path.isfile(bdbversion_file): vers_file = open(bdbversion_file) bsddb_version = vers_file.readline().strip() + bsddb_version = ".".join([str(v) for v in safe_eval(bsddb_version)]) else: bsddb_version = _("Unknown") return { + _("DB-API version"): "n/a", _("Number of people"): self.get_number_of_people(), _("Number of families"): self.get_number_of_families(), _("Number of sources"): self.get_number_of_sources(), @@ -2530,8 +2554,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): _("Number of repositories"): self.get_number_of_repositories(), _("Number of notes"): self.get_number_of_notes(), _("Number of tags"): self.get_number_of_tags(), - _("Schema version"): schema_version, - _("Version"): bsddb_version, + _("Data version"): schema_version, + _("Database db version"): bsddb_version, } def mk_backup_name(database, base): diff --git a/gramps/plugins/database/dbapi.py b/gramps/plugins/database/dbapi.py index 614be98e4..bc2330cfb 100644 --- a/gramps/plugins/database/dbapi.py +++ b/gramps/plugins/database/dbapi.py @@ -40,6 +40,13 @@ class DBAPI(DbGeneric): """ Database backends class for DB-API 2.0 databases """ + @classmethod + def get_class_summary(cls): + summary = { + "DB-API version": "2.0", + "Database type": cls.__name__, + } + return summary def restore(self): """ @@ -1873,3 +1880,16 @@ class DBAPI(DbGeneric): else: obj = self.get_table_func(table,"class_func").create(pickle.loads(row[0])) yield obj + + def get_summary(self): + """ + Returns dictionary of summary item. + Should include, if possible: + + _("Number of people") + _("Version") + _("Schema version") + """ + summary = super().get_summary() + summary.update(self.dbapi.__class__.get_summary()) + return summary diff --git a/gramps/plugins/database/dbapi_support/mysql.py b/gramps/plugins/database/dbapi_support/mysql.py index fbc8197aa..d82ae01d0 100644 --- a/gramps/plugins/database/dbapi_support/mysql.py +++ b/gramps/plugins/database/dbapi_support/mysql.py @@ -3,6 +3,21 @@ import MySQLdb MySQLdb.paramstyle = 'qmark' ## Doesn't work class MySQL(object): + @classmethod + def get_summary(cls): + """ + Return a diction of information about this database + backend. + """ + summary = { + "DB-API version": "2.0", + "Database SQL type": cls.__name__, + "Database SQL module": "MySQLdb", + "Database SQL module version": ".".join([str(v) for v in MySQLdb.version_info]), + "Database SQL module location": MySQLdb.__file__, + } + return summary + def __init__(self, *args, **kwargs): self.connection = MySQLdb.connect(*args, **kwargs) self.cursor = self.connection.cursor() diff --git a/gramps/plugins/database/dbapi_support/postgresql.py b/gramps/plugins/database/dbapi_support/postgresql.py index b1d711b8a..231c7adc0 100644 --- a/gramps/plugins/database/dbapi_support/postgresql.py +++ b/gramps/plugins/database/dbapi_support/postgresql.py @@ -3,6 +3,21 @@ import pg8000 pg8000.paramstyle = 'qmark' class Postgresql(object): + @classmethod + def get_summary(cls): + """ + Return a diction of information about this database + backend. + """ + summary = { + "DB-API version": "2.0", + "Database SQL type": cls.__name__, + "Database SQL module": "pg8000", + "Database SQL module version": pg8000.__version__, + "Database SQL module location": pg8000.__file__, + } + return summary + def __init__(self, *args, **kwargs): self.connection = pg8000.connect(*args, **kwargs) self.cursor = self.connection.cursor() diff --git a/gramps/plugins/database/dbapi_support/sqlite.py b/gramps/plugins/database/dbapi_support/sqlite.py index 07edb535a..c2eae3970 100644 --- a/gramps/plugins/database/dbapi_support/sqlite.py +++ b/gramps/plugins/database/dbapi_support/sqlite.py @@ -6,6 +6,21 @@ import re sqlite3.paramstyle = 'qmark' class Sqlite(object): + @classmethod + def get_summary(cls): + """ + Return a diction of information about this database + backend. + """ + summary = { + "DB-API version": "2.0", + "Database SQL type": cls.__name__, + "Database SQL module": "sqlite3", + "Database SQL module version": sqlite3.version, + "Database SQL module location": sqlite3.__file__, + } + return summary + def __init__(self, *args, **kwargs): self.log = logging.getLogger(".sqlite") self.connection = sqlite3.connect(*args, **kwargs) diff --git a/gramps/plugins/database/inmemorydb.py b/gramps/plugins/database/inmemorydb.py index dc3c49a43..913fa7723 100644 --- a/gramps/plugins/database/inmemorydb.py +++ b/gramps/plugins/database/inmemorydb.py @@ -28,6 +28,13 @@ class InMemoryDB(DBAPI): """ A DB-API 2.0 In-memory SQL database. """ + @classmethod + def get_class_summary(cls): + summary = DBAPI.get_class_summary() + summary.update({ + "Database location": "in memory", + }) + return summary def initialize_backend(self, directory): """