From f8eee36ae16b0af4dde9c2891809f92833748021 Mon Sep 17 00:00:00 2001
From: Danijel Schorlemmer <ds@gfz-potsdam.de>
Date: Fri, 19 Mar 2021 23:58:51 +0100
Subject: [PATCH] Added initial Spatialite database class

---
 Makefile                |  2 +-
 exposurelib/database.py | 84 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 exposurelib/database.py

diff --git a/Makefile b/Makefile
index 7ccccb8a..8b250680 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SOURCES=exposurespatialite tests setup.py
+SOURCES=exposurelib tests setup.py
 LENGTH=96
 
 check: $(SOURCES)
diff --git a/exposurelib/database.py b/exposurelib/database.py
new file mode 100644
index 00000000..773cdb45
--- /dev/null
+++ b/exposurelib/database.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2021:
+#   Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 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 Affero
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/.
+
+import logging
+import sqlite3
+
+
+logger = logging.getLogger(__name__)
+
+
+class SpatialiteDatabase:
+    """The SpatialiteDatabase class represents a Spatialite database. It manages the
+    database connection and cursor. Upon connection, the Spatialite extension is loaded.
+
+    Args:
+        database_filepath (str):
+            File path for the Spatialite database file.
+        spatialite_filepath (str):
+            File path of the Spatialite extension.
+
+    Attributes:
+        database_filepath (str):
+            Spatialite database file path.
+        spatialite_filepath (str):
+            File path to the Spatialite extension.
+        connection (sqlite3.Connection):
+            Database connection
+        cursor (sqlite3.Cursor):
+            Database cursor
+    """
+
+    def __init__(self, database_filepath, spatialite_filepath="mod_spatialite"):
+        self.database_filepath = database_filepath
+        self.spatialite_filepath = spatialite_filepath
+
+        self.connection = None
+        self.cursor = None
+
+    def connect(self, init_spatial_metadata=True):
+        """Connects to a database, loads the Spatialite extension and
+        initializes it if requested. If the database file does not exist,
+        it will be automatically created.
+
+        Args:
+            init_spatial_metadata (Bool):
+                Defines if the spatial metadata should be initialized. This is not
+                necessary if an existing Spatialite database is opened.
+        """
+
+        # Connect (if exists) or create SQLite database
+        logger.debug("Connecting to database at %s" % self.database_filepath)
+        self.connection = sqlite3.connect(self.database_filepath)
+        logger.debug("Connection to database established")
+
+        # Load and initialize the Spatialite extension
+        self.connection.enable_load_extension(True)
+        sql_statement = "SELECT load_extension('%s');" % self.spatialite_filepath
+        self.connection.execute(sql_statement)
+        if init_spatial_metadata:
+            self.connection.execute("SELECT InitSpatialMetaData(1);")
+            logger.debug("Spatialite extension loaded and initialized")
+
+        # Debug output
+        versions = self.connection.execute("SELECT sqlite_version(), spatialite_version()")
+        for row in versions:
+            logger.debug("SQLite version: %s" % row[0])
+            logger.debug("Spatialite version: %s" % row[1])
+
+        self.cursor = self.connection.cursor()
-- 
GitLab