Reorganise DBAPI plugins

Add SQLite and PostgreSQL plugins.
Remove DBAPI and InMemoryDb plugins.
This commit is contained in:
Nick Hall 2017-07-28 23:42:55 +01:00
parent 1513315d05
commit 63bb36ea44
13 changed files with 105 additions and 140 deletions

View File

@ -601,6 +601,11 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
# run backend-specific code: # run backend-specific code:
self._initialize(directory) self._initialize(directory)
# We use the existence of the person table as a proxy for the database
# being new
if not self.dbapi.table_exists("person"):
self._create_schema()
# Load metadata # Load metadata
self.name_formats = self._get_metadata('name_formats') self.name_formats = self._get_metadata('name_formats')
self.owner = self._get_metadata('researcher', default=Researcher()) self.owner = self._get_metadata('researcher', default=Researcher())

View File

@ -129,8 +129,8 @@ def import_as_dict(filename, user, skp_imp_adds=True):
""" """
Import the filename into a InMemoryDB and return it. Import the filename into a InMemoryDB and return it.
""" """
db = make_database("inmemorydb") db = make_database("sqlite")
db.load(None) db.load(":memory:")
db.set_feature("skip-import-additions", skp_imp_adds) db.set_feature("skip-import-additions", skp_imp_adds)
status = import_from_filename(db, filename, user) status = import_from_filename(db, filename, user)
return db if status else None return db if status else None

View File

@ -809,7 +809,7 @@ class DbManager(CLIDbManager, ManagedWindow):
new_text = "%s %s" % (name, _("(Converted #%d)") % count) new_text = "%s %s" % (name, _("(Converted #%d)") % count)
new_path, newname = self._create_new_db(new_text, edit_entry=False) new_path, newname = self._create_new_db(new_text, edit_entry=False)
## Create a new database of correct type: ## Create a new database of correct type:
dbase = make_database("dbapi") dbase = make_database(config.get('database.backend'))
dbase.write_version(new_path) dbase.write_version(new_path)
dbase.load(new_path) dbase.load(new_path)
## import from XML ## import from XML

View File

@ -79,48 +79,12 @@ class DBAPI(DbGeneric):
version_file.write(str(self.VERSION[0])) version_file.write(str(self.VERSION[0]))
versionpath = os.path.join(directory, str(DBBACKEND)) versionpath = os.path.join(directory, str(DBBACKEND))
_LOG.debug("Write database backend file to 'dbapi'") _LOG.debug("Write database backend file")
with open(versionpath, "w") as version_file: with open(versionpath, "w") as version_file:
version_file.write("dbapi") version_file.write(self.__class__.__name__.lower())
def _initialize(self, directory): def _initialize(self, directory):
# Run code from directory raise NotImplementedError
from gramps.gen.utils.configmanager import ConfigManager
config_file = os.path.join(directory, 'settings.ini')
config_mgr = ConfigManager(config_file)
config_mgr.register('database.dbtype', 'sqlite')
config_mgr.register('database.dbname', 'gramps')
config_mgr.register('database.host', 'localhost')
config_mgr.register('database.user', 'user')
config_mgr.register('database.password', 'password')
config_mgr.register('database.port', 'port')
config_mgr.load() # load from settings.ini
dbtype = config_mgr.get('database.dbtype')
if dbtype == "sqlite":
from gramps.plugins.db.dbapi.sqlite import Sqlite
path_to_db = os.path.join(directory, 'sqlite.db')
self.dbapi = Sqlite(path_to_db)
else:
dbkwargs = {}
for key in config_mgr.get_section_settings('database'):
# Use all parameters except dbtype as keyword arguments
if key == 'dbtype':
continue
dbkwargs[key] = config_mgr.get('database.' + key)
if dbtype == "postgresql":
from gramps.plugins.db.dbapi.postgresql import Postgresql
self.dbapi = Postgresql(**dbkwargs)
else:
raise AttributeError(("invalid DB-API dbtype: '%s'. " +
"Should be 'sqlite' or 'postgresql'")
% dbtype)
# We use the existence of the person table as a proxy for the database
# being new
if not self.dbapi.table_exists("person"):
self._create_schema()
def _create_schema(self): def _create_schema(self):
""" """

View File

@ -1,58 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2016 Douglas S. Blank <doug.blank@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
from gramps.plugins.db.dbapi.dbapi import DBAPI
from gramps.plugins.db.dbapi.sqlite import Sqlite
from gramps.gen.db import DBBACKEND
from gramps.gen.db.generic import DbGeneric, LOG
import os
import glob
class InMemoryDB(DBAPI):
"""
A DB-API 2.0 In-memory SQL database.
"""
def _initialize(self, directory):
"""
Create an in-memory sqlite database.
"""
self.dbapi = Sqlite(":memory:")
self._create_schema()
def write_version(self, directory):
"""Write files for a newly created DB."""
versionpath = os.path.join(directory, DBBACKEND)
LOG.debug("Write database backend file to 'inmemorydb'")
with open(versionpath, "w") as version_file:
version_file.write("inmemorydb")
def load(self, directory, callback=None, mode=None,
force_schema_upgrade=False,
force_bsddb_upgrade=False,
force_bsddb_downgrade=False,
force_python_upgrade=False,
update=True):
DbGeneric.load(self, directory,
callback,
mode,
force_schema_upgrade,
force_bsddb_upgrade,
force_bsddb_downgrade,
force_python_upgrade)

View File

@ -22,15 +22,15 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
register(DATABASE, register(DATABASE,
id = 'inmemorydb', id='postgresql',
name = _("In-Memory"), name=_('PostgreSQL'),
name_accell = _("In-_Memory Database"), name_accell=_('_PostgreSQL Database'),
description = _("In-Memory Database"), description=_('PostgreSQL Database'),
version = '1.0.0', version='1.0.0',
gramps_target_version = "5.0", gramps_target_version='5.0',
status = STABLE, status=STABLE,
fname = 'inmemorydb.py', fname='postgresql.py',
databaseclass = 'InMemoryDB', databaseclass='PostgreSQL',
authors=['Doug Blank'], authors=['Doug Blank'],
authors_email=["doug.blank@gmail.com"], authors_email=['doug.blank@gmail.com']
) )

View File

@ -2,7 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2015-2016 Douglas S. Blank <doug.blank@gmail.com> # Copyright (C) 2015-2016 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2016 Nick Hall # Copyright (C) 2016-2017 Nick Hall
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -19,12 +19,17 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# #
"""
Backend for PostgreSQL database.
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Standard python modules # Standard python modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import psycopg2 import psycopg2
import os
import re import re
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -32,12 +37,43 @@ import re
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.plugins.db.dbapi.dbapi import DBAPI
from gramps.gen.utils.configmanager import ConfigManager
from gramps.gen.db.dbconst import ARRAYSIZE from gramps.gen.db.dbconst import ARRAYSIZE
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
psycopg2.paramstyle = 'format' psycopg2.paramstyle = 'format'
class Postgresql: #-------------------------------------------------------------------------
#
# PostgreSQL class
#
#-------------------------------------------------------------------------
class PostgreSQL(DBAPI):
def _initialize(self, directory):
config_file = os.path.join(directory, 'settings.ini')
config_mgr = ConfigManager(config_file)
config_mgr.register('database.dbname', 'gramps')
config_mgr.register('database.host', 'localhost')
config_mgr.register('database.user', 'user')
config_mgr.register('database.password', 'password')
config_mgr.register('database.port', 'port')
config_mgr.load()
dbkwargs = {}
for key in config_mgr.get_section_settings('database'):
dbkwargs[key] = config_mgr.get('database.' + key)
self.dbapi = Connection(**dbkwargs)
#-------------------------------------------------------------------------
#
# Connection class
#
#-------------------------------------------------------------------------
class Connection:
@classmethod @classmethod
def get_summary(cls): def get_summary(cls):
""" """
@ -140,6 +176,11 @@ class Postgresql:
return Cursor(self.__connection) return Cursor(self.__connection)
#-------------------------------------------------------------------------
#
# Cursor class
#
#-------------------------------------------------------------------------
class Cursor: class Cursor:
def __init__(self, connection): def __init__(self, connection):
self.__connection = connection self.__connection = connection

View File

@ -22,15 +22,15 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
register(DATABASE, register(DATABASE,
id = 'dbapi', id='sqlite',
name = _("DB-API"), name=_('SQLite'),
name_accell = _("DB-_API Database"), name_accell=_('_SQLite Database'),
description = _("DB-API Database"), description=_('SQLite Database'),
version = '1.0.32', version='1.0.0',
gramps_target_version = "5.0", gramps_target_version='5.0',
status = STABLE, status=STABLE,
fname = 'dbapi.py', fname='sqlite.py',
databaseclass = 'DBAPI', databaseclass='SQLite',
authors=['Doug Blank'], authors=['Doug Blank'],
authors_email=["doug.blank@gmail.com"], authors_email=['doug.blank@gmail.com']
) )

View File

@ -2,7 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2015-2016 Douglas S. Blank <doug.blank@gmail.com> # Copyright (C) 2015-2016 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2016 Nick Hall # Copyright (C) 2016-2017 Nick Hall
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
# #
""" """
Backend for sqlite database. Backend for SQLite database.
""" """
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -29,14 +29,16 @@ Backend for sqlite database.
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import sqlite3 import sqlite3
import logging import os
import re import re
import logging
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.plugins.db.dbapi.dbapi import DBAPI
from gramps.gen.db.dbconst import ARRAYSIZE from gramps.gen.db.dbconst import ARRAYSIZE
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
@ -44,10 +46,25 @@ sqlite3.paramstyle = 'qmark'
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Sqlite class # SQLite class
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class Sqlite: class SQLite(DBAPI):
def _initialize(self, directory):
if directory == ':memory:':
path_to_db = ':memory:'
else:
path_to_db = os.path.join(directory, 'sqlite.db')
self.dbapi = Connection(path_to_db)
#-------------------------------------------------------------------------
#
# Connection class
#
#-------------------------------------------------------------------------
class Connection:
""" """
The Sqlite class is an interface between the DBAPI class which is the Gramps The Sqlite class is an interface between the DBAPI class which is the Gramps
backend for the DBAPI interface and the sqlite3 python module. backend for the DBAPI interface and the sqlite3 python module.

View File

@ -47,8 +47,8 @@ class DbRandomTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.db = make_database("inmemorydb") cls.db = make_database("sqlite")
cls.db.load(None) cls.db.load(":memory:")
def setUp(self): def setUp(self):
self.handles = {'Person': [], 'Family': [], 'Event': [], 'Place': [], self.handles = {'Person': [], 'Family': [], 'Event': [], 'Place': [],
@ -709,8 +709,8 @@ class DbEmptyTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.db = make_database("inmemorydb") cls.db = make_database("sqlite")
cls.db.load(None) cls.db.load(":memory:")
################################################################ ################################################################
# #
@ -806,8 +806,8 @@ class DbPersonTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.db = make_database("inmemorydb") cls.db = make_database("sqlite")
cls.db.load(None) cls.db.load(":memory:")
def __add_person(self, gender, first_name, surname, trans): def __add_person(self, gender, first_name, surname, trans):
person = Person() person = Person()

View File

@ -361,7 +361,7 @@ class DbTestClassBase(object):
msg="Callback Manager disconnect cb check") msg="Callback Manager disconnect cb check")
params = [('BsdDb', 'bsddb'), ('DbApi', 'dbapi')] params = [('BsdDb', 'bsddb'), ('SQLite', 'sqlite')]
for name, param in params: for name, param in params:
cls_name = "TestMyTestClass_%s" % (name, ) cls_name = "TestMyTestClass_%s" % (name, )

View File

@ -552,13 +552,13 @@ gramps/gui/widgets/reorderfam.py
gramps/gui/widgets/styledtextbuffer.py gramps/gui/widgets/styledtextbuffer.py
gramps/gui/widgets/styledtexteditor.py gramps/gui/widgets/styledtexteditor.py
gramps/gui/widgets/validatedmaskedentry.py gramps/gui/widgets/validatedmaskedentry.py
gramps/plugins/db/dbapi/dbapi.gpr.py
gramps/plugins/db/bsddb/bsddb.gpr.py gramps/plugins/db/bsddb/bsddb.gpr.py
gramps/plugins/db/bsddb/read.py gramps/plugins/db/bsddb/read.py
gramps/plugins/db/bsddb/undoredo.py gramps/plugins/db/bsddb/undoredo.py
gramps/plugins/db/bsddb/upgrade.py gramps/plugins/db/bsddb/upgrade.py
gramps/plugins/db/bsddb/write.py gramps/plugins/db/bsddb/write.py
gramps/plugins/db/dbapi/inmemorydb.gpr.py gramps/plugins/db/dbapi/postgresql.gpr.py
gramps/plugins/db/dbapi/sqlite.gpr.py
gramps/plugins/docgen/asciidoc.py gramps/plugins/docgen/asciidoc.py
gramps/plugins/docgen/docgen.gpr.py gramps/plugins/docgen/docgen.gpr.py
gramps/plugins/docgen/gtkprint.glade gramps/plugins/docgen/gtkprint.glade

View File

@ -378,10 +378,6 @@ gramps/gui/widgets/valuetoolitem.py
# #
gramps/plugins/__init__.py gramps/plugins/__init__.py
# #
# plugins/db directory
#
gramps/plugins/db/dbapi/inmemorydb.py
#
# plugins/docgen directory # plugins/docgen directory
# #
gramps/plugins/docgen/__init__.py gramps/plugins/docgen/__init__.py