Source code for gramps.plugins.db.dbapi.sqlite

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2015-2016 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2016-2017 Nick Hall
#
# 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.
#

"""
Backend for SQLite database.
"""

#-------------------------------------------------------------------------
#
# standard python modules
#
#-------------------------------------------------------------------------
import sqlite3
import os
import re
import logging

#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.plugins.db.dbapi.dbapi import DBAPI
from gramps.gen.db.dbconst import ARRAYSIZE
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext

sqlite3.paramstyle = 'qmark'

#-------------------------------------------------------------------------
#
# SQLite class
#
#-------------------------------------------------------------------------
[docs] class SQLite(DBAPI):
[docs] def get_summary(self): """ Return a dictionary of information about this database backend. """ summary = super().get_summary() summary.update({ _("Database version"): sqlite3.sqlite_version, _("Database module version"): sqlite3.version, _("Database module location"): sqlite3.__file__, }) return summary
def _initialize(self, directory, username, password): 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 # #-------------------------------------------------------------------------
[docs] class Connection: """ The Sqlite class is an interface between the DBAPI class which is the Gramps backend for the DBAPI interface and the sqlite3 python module. """ def __init__(self, *args, **kwargs): """ Create a new Sqlite instance. This connects to a sqlite3 database and creates a cursor instance. :param args: arguments to be passed to the sqlite3 connect class at creation. :type args: list :param kwargs: arguments to be passed to the sqlite3 connect class at creation. :type kwargs: list """ self.log = logging.getLogger(".sqlite") self.__connection = sqlite3.connect(*args, **kwargs) self.__cursor = self.__connection.cursor() self.__connection.create_function("regexp", 2, regexp) self.__collations = [] self.check_collation(glocale)
[docs] def check_collation(self, locale): """ Checks that a collation exists and if not creates it. :param locale: Locale to be checked. :param type: A GrampsLocale object. """ collation = locale.get_collation() if collation not in self.__collations: self.__connection.create_collation(collation, locale.strcoll)
[docs] def execute(self, *args, **kwargs): """ Executes an SQL statement. :param args: arguments to be passed to the sqlite3 execute statement :type args: list :param kwargs: arguments to be passed to the sqlite3 execute statement :type kwargs: list """ self.log.debug(args) self.__cursor.execute(*args, **kwargs)
[docs] def fetchone(self): """ Fetches the next row of a query result set, returning a single sequence, or None when no more data is available. """ return self.__cursor.fetchone()
[docs] def fetchall(self): """ Fetches the next set of rows of a query result, returning a list. An empty list is returned when no more rows are available. """ return self.__cursor.fetchall()
[docs] def begin(self): """ Start a transaction manually. This transactions usually persist until the next COMMIT or ROLLBACK command. """ self.log.debug("BEGIN TRANSACTION;") self.execute("BEGIN TRANSACTION;")
[docs] def commit(self): """ Commit the current transaction. """ self.log.debug("COMMIT;") self.__connection.commit()
[docs] def rollback(self): """ Roll back any changes to the database since the last call to commit(). """ self.log.debug("ROLLBACK;") self.__connection.rollback()
[docs] def table_exists(self, table): """ Test whether the specified SQL database table exists. :param table: table name to check. :type table: str :returns: True if the table exists, false otherwise. :rtype: bool """ self.execute("SELECT COUNT(*) " "FROM sqlite_master " "WHERE type='table' AND name='%s';" % table) return self.fetchone()[0] != 0
[docs] def close(self): """ Close the current database. """ self.log.debug("closing database...") self.__connection.close()
[docs] def cursor(self): """ Return a new cursor. """ return Cursor(self.__connection)
#------------------------------------------------------------------------- # # Cursor class # #------------------------------------------------------------------------- class Cursor: def __init__(self, connection): self.__connection = connection def __enter__(self): self.__cursor = self.__connection.cursor() self.__cursor.arraysize = ARRAYSIZE return self def __exit__(self, *args, **kwargs): self.__cursor.close() def execute(self, *args, **kwargs): """ Executes an SQL statement. :param args: arguments to be passed to the sqlite3 execute statement :type args: list :param kwargs: arguments to be passed to the sqlite3 execute statement :type kwargs: list """ self.__cursor.execute(*args, **kwargs) def fetchmany(self): """ Fetches the next set of rows of a query result, returning a list. An empty list is returned when no more rows are available. """ return self.__cursor.fetchmany()
[docs] def regexp(expr, value): """ A user defined function that can be called from within an SQL statement. This function has two parameters. :param expr: pattern to look for. :type expr: str :param value: the string to search. :type value: list :returns: True if the expr exists within the value, false otherwise. :rtype: bool """ return re.search(expr, value, re.MULTILINE) is not None