فهرست منبع

t.downgrade: downgrade a temporal db from version 3 to 2 (#1449)

* Downgrade a temporal db from version 3 to 2

* Apply suggestions from code review

Co-authored-by: Markus Neteler <neteler@gmail.com>
Markus Metz 4 سال پیش
والد
کامیت
ab4c960306

+ 99 - 2
lib/python/temporal/core.py

@@ -475,7 +475,7 @@ def get_available_temporal_mapsets():
 ###############################################################################
 ###############################################################################
 
 
 
 
-def init(raise_fatal_error=False):
+def init(raise_fatal_error=False, skip_db_version_check=False):
     """This function set the correct database backend from GRASS environmental
     """This function set the correct database backend from GRASS environmental
        variables and creates the grass temporal database structure for raster,
        variables and creates the grass temporal database structure for raster,
        vector and raster3d maps as well as for the space-time datasets strds,
        vector and raster3d maps as well as for the space-time datasets strds,
@@ -516,6 +516,10 @@ def init(raise_fatal_error=False):
                                   exception will be raised in case a fatal
                                   exception will be raised in case a fatal
                                   error occurs in the init process, otherwise
                                   error occurs in the init process, otherwise
                                   sys.exit(1) will be called.
                                   sys.exit(1) will be called.
+     :param skip_db_version_check: Set this True to skip mismatch temporal
+                                   database version check.
+                                   Recommended to be used only for
+                                   downgrade_temporal_database().
     """
     """
     # We need to set the correct database backend and several global variables
     # We need to set the correct database backend and several global variables
     # from the GRASS mapset specific environment variables of g.gisenv and t.connect
     # from the GRASS mapset specific environment variables of g.gisenv and t.connect
@@ -663,8 +667,11 @@ def init(raise_fatal_error=False):
                    " created automatically.\n"
                    " created automatically.\n"
 
 
     if db_exists is True:
     if db_exists is True:
-        # Check the version of the temporal database
         dbif.close()
         dbif.close()
+        if skip_db_version_check is True:
+            return
+
+        # Check the version of the temporal database
         dbif.connect()
         dbif.connect()
         metadata = get_tgis_metadata(dbif)
         metadata = get_tgis_metadata(dbif)
         dbif.close()
         dbif.close()
@@ -705,6 +712,29 @@ def get_database_info_string():
 ###############################################################################
 ###############################################################################
 
 
 
 
+def _create_temporal_database_views(dbif):
+    """Create all views in the temporal database (internal use only)
+
+    Used by downgrade_temporal_database().
+
+    :param dbif: The database interface to be used
+    """
+    template_path = get_sql_template_path()
+
+    for sql_filename in (
+        "raster_views",
+        "raster3d_views",
+        "vector_views",
+        "strds_views",
+        "str3ds_views",
+        "stvds_views",
+    ):
+        sql_filepath = open(
+            os.path.join(template_path, sql_filename + ".sql"), "r"
+        ).read()
+        dbif.execute_transaction(sql_filepath)
+
+
 def create_temporal_database(dbif):
 def create_temporal_database(dbif):
     """This function will create the temporal database
     """This function will create the temporal database
 
 
@@ -844,6 +874,73 @@ def create_temporal_database(dbif):
 ###############################################################################
 ###############################################################################
 
 
 
 
+def downgrade_temporal_database(dbif):
+    """This function will downgrade the temporal database if needed.
+
+    It will downdate all tables and triggers that are requested by
+    currently supported TGIS DB version.
+
+    :param dbif: The database interface to be used
+    """
+    global tgis_database_string
+    global tgis_db_version
+
+    metadata = get_tgis_metadata(dbif)
+
+    msgr = get_tgis_message_interface()
+    if metadata is None:
+        msgr.fatal(
+            _(
+                "Unable to receive temporal database metadata.\n"
+                "Current temporal database info:%(info)s"
+            )
+            % ({"info": get_database_info_string()})
+        )
+    downgrade_db_from = None
+    for entry in metadata:
+        if "tgis_db_version" in entry and entry[1] != str(tgis_db_version):
+            downgrade_db_from = entry[1]
+            break
+
+    if downgrade_db_from is None:
+        msgr.message(_("Temporal database is up-to-date. Operation canceled"))
+        dbif.close()
+        return
+
+    template_path = get_sql_template_path()
+    try:
+        downgrade_db_sql = open(
+            os.path.join(
+                template_path,
+                "downgrade_db_%s_to_%s.sql" % (downgrade_db_from, tgis_db_version),
+            ),
+            "r",
+        ).read()
+    except FileNotFoundError:
+        msgr.fatal(
+            _("Unsupported TGIS DB downgrade scenario: from version %s to %s")
+            % (downgrade_db_from, tgis_db_version)
+        )
+
+    drop_views_sql = open(os.path.join(template_path, "drop_views.sql"), "r").read()
+
+    msgr.message(
+        _("Downgrading temporal database <%s> from version %s to %s...")
+        % (tgis_database_string, downgrade_db_from, tgis_db_version)
+    )
+    # Drop views
+    dbif.execute_transaction(drop_views_sql)
+    # Perform upgrade
+    dbif.execute_transaction(downgrade_db_sql)
+    # Recreate views
+    _create_temporal_database_views(dbif)
+
+    dbif.close()
+
+
+###############################################################################
+
+
 def _create_tgis_metadata_table(content, dbif=None):
 def _create_tgis_metadata_table(content, dbif=None):
     """!Create the temporal gis metadata table which stores all metadata
     """!Create the temporal gis metadata table which stores all metadata
        information about the temporal database.
        information about the temporal database.

+ 83 - 0
lib/temporal/SQL/downgrade_db_3_to_2.sql

@@ -0,0 +1,83 @@
+--#############################################################################
+-- This SQL script downgrades TGIS DB from version 3 to version 2.
+--
+-- Author: Markus Metz
+--#############################################################################
+
+-- raster_metadata_table.sql
+CREATE TEMPORARY TABLE raster_metadata_backup(
+  id VARCHAR NOT NULL,               -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name@mapset) and is used as primary key
+  datatype VARCHAR NOT NULL,
+  cols INTEGER NOT NULL,
+  rows INTEGER NOT NULL,
+  number_of_cells INTEGER NOT NULL,
+  nsres DOUBLE PRECISION NOT NULL,
+  ewres DOUBLE PRECISION NOT NULL,
+  min DOUBLE PRECISION,
+  max DOUBLE PRECISION,
+  PRIMARY KEY (id)
+);
+INSERT INTO raster_metadata_backup SELECT id,datatype,cols,rows,number_of_cells,nsres,ewres,min,max FROM raster_metadata;
+DROP TABLE raster_metadata;
+CREATE TABLE raster_metadata(
+  id VARCHAR NOT NULL,               -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name@mapset) and is used as primary key
+  datatype VARCHAR NOT NULL,
+  cols INTEGER NOT NULL,
+  rows INTEGER NOT NULL,
+  number_of_cells INTEGER NOT NULL,
+  nsres DOUBLE PRECISION NOT NULL,
+  ewres DOUBLE PRECISION NOT NULL,
+  min DOUBLE PRECISION,
+  max DOUBLE PRECISION,
+  PRIMARY KEY (id)
+);
+INSERT INTO raster_metadata SELECT id,datatype,cols,rows,number_of_cells,nsres,ewres,min,max FROM raster_metadata_backup;
+DROP TABLE raster_metadata_backup;
+
+
+-- strds_metadata_table.sql
+CREATE TEMPORARY TABLE strds_metadata_backup(
+  id VARCHAR NOT NULL,          -- Id of the space-time dataset, this is the primary key
+  raster_register VARCHAR,      -- The id of the table in which the raster maps are registered for this dataset
+  number_of_maps INTEGER,       -- The number of registered raster maps
+  max_min DOUBLE PRECISION,     -- The minimal maximum of the registered raster maps
+  min_min DOUBLE PRECISION,     -- The minimal minimum of the registered raster maps
+  max_max DOUBLE PRECISION,     -- The maximal maximum of the registered raster maps
+  min_max DOUBLE PRECISION,     -- The maximal minimum of the registered raster maps
+  nsres_min DOUBLE PRECISION,   -- The lowest north-south resolution of the registered raster maps
+  nsres_max DOUBLE PRECISION,   -- The highest north-south resolution of the registered raster maps
+  ewres_min DOUBLE PRECISION,   -- The lowest east-west resolution of the registered raster maps
+  ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered raster maps
+  aggregation_type VARCHAR,     -- The aggregation type of the dataset (mean, min, max, ...) set by aggregation modules
+  title VARCHAR,                -- Title of the space-time raster dataset
+  description VARCHAR,          -- Detailed description of the space-time raster dataset
+  command VARCHAR,              -- The command that was used to create the space time raster dataset
+  PRIMARY KEY (id)
+);
+INSERT INTO strds_metadata_backup SELECT id,raster_register,number_of_maps,max_min,min_min,max_max,min_max,nsres_min,nsres_max,ewres_min,ewres_max,aggregation_type,title,description,command FROM strds_metadata;
+DROP TABLE strds_metadata;
+CREATE TABLE strds_metadata(
+  id VARCHAR NOT NULL,          -- Id of the space-time dataset, this is the primary key
+  raster_register VARCHAR,      -- The id of the table in which the raster maps are registered for this dataset
+  number_of_maps INTEGER,       -- The number of registered raster maps
+  max_min DOUBLE PRECISION,     -- The minimal maximum of the registered raster maps
+  min_min DOUBLE PRECISION,     -- The minimal minimum of the registered raster maps
+  max_max DOUBLE PRECISION,     -- The maximal maximum of the registered raster maps
+  min_max DOUBLE PRECISION,     -- The maximal minimum of the registered raster maps
+  nsres_min DOUBLE PRECISION,   -- The lowest north-south resolution of the registered raster maps
+  nsres_max DOUBLE PRECISION,   -- The highest north-south resolution of the registered raster maps
+  ewres_min DOUBLE PRECISION,   -- The lowest east-west resolution of the registered raster maps
+  ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered raster maps
+  aggregation_type VARCHAR,     -- The aggregation type of the dataset (mean, min, max, ...) set by aggregation modules
+  title VARCHAR,                -- Title of the space-time raster dataset
+  description VARCHAR,          -- Detailed description of the space-time raster dataset
+  command VARCHAR,              -- The command that was used to create the space time raster dataset
+  PRIMARY KEY (id)
+);
+INSERT INTO strds_metadata SELECT id,raster_register,number_of_maps,max_min,min_min,max_max,min_max,nsres_min,nsres_max,ewres_min,ewres_max,aggregation_type,title,description,command FROM strds_metadata_backup;
+DROP TABLE strds_metadata_backup;
+
+-- tgis_metadata
+UPDATE tgis_metadata
+  SET value = '2'
+  WHERE key = 'tgis_db_version';

+ 29 - 0
lib/temporal/SQL/drop_views.sql

@@ -0,0 +1,29 @@
+--#############################################################################
+-- This SQL script drops all existing vies (used by upgrade_temporal_database())
+--
+-- Author: Martin Landa landa.martin <at> gmail <dot> com
+--#############################################################################
+
+-- raster_views
+DROP VIEW raster_view_abs_time;
+DROP VIEW raster_view_rel_time;
+
+-- raster3d_views
+DROP VIEW raster3d_view_abs_time;
+DROP VIEW raster3d_view_rel_time;
+
+-- vector_views
+DROP VIEW vector_view_abs_time;
+DROP VIEW vector_view_rel_time;
+
+-- strds_views
+DROP VIEW strds_view_abs_time;
+DROP VIEW strds_view_rel_time;
+
+-- str3ds_views
+DROP VIEW str3ds_view_abs_time;
+DROP VIEW str3ds_view_rel_time;
+
+-- stvds_views
+DROP VIEW stvds_view_abs_time;
+DROP VIEW stvds_view_rel_time;

+ 1 - 0
temporal/Makefile

@@ -3,6 +3,7 @@ MODULE_TOPDIR = ..
 SUBDIRS = \
 SUBDIRS = \
 	t.connect \
 	t.connect \
 	t.create \
 	t.create \
+	t.downgrade \
 	t.support \
 	t.support \
 	t.topology \
 	t.topology \
 	t.list \
 	t.list \

+ 7 - 0
temporal/t.downgrade/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = t.downgrade
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(TEST_DST)

+ 28 - 0
temporal/t.downgrade/t.downgrade.html

@@ -0,0 +1,28 @@
+<h2>DESCRIPTION</h2>
+
+This module downgrades the TGIS DB version.
+
+At time it only downgrades TGIS DB from version 3 (after introducing band
+reference support ("image collections"), see
+<a href="https://github.com/OSGeo/grass/pull/63">PR #63</a>) to version 3
+(with band reference support).
+
+<h2>EXAMPLE</h2>
+
+<div class="code"><pre>
+t.downgrade
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="https://grass.osgeo.org/grass-stable/manuals/t.info.html">t.info</a>
+</em>
+
+<h2>AUTHORS</h2>
+
+Martin Landa, Markus Neteler, Markus Metz
+
+<!--
+<p><i>Last changed: $Date$</i>
+-->

+ 47 - 0
temporal/t.downgrade/t.downgrade.py

@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:       t.downgrade
+# AUTHOR(S):    Martin Landa, Markus Neteler, Markus Metz
+# PURPOSE:      Downgrade of TGRASS DB
+# COPYRIGHT:    (C) 2019-2021 by Martin Landa, and the GRASS Development Team
+#
+#  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.
+#
+############################################################################
+
+#%module
+#% description: Downgrades the version of a space time dataset (TGRASS DB).
+#% keyword: temporal
+#% keyword: metadata
+#% keyword: time
+#%end
+
+import grass.script as gs
+
+
+def main():
+    # lazy imports
+    import grass.temporal as tgis
+
+    tgis.init(skip_db_version_check=True)
+
+    dbif = tgis.SQLDatabaseInterfaceConnection()
+    dbif.connect()
+
+    tgis.downgrade_temporal_database(dbif)
+
+    return 0
+
+if __name__ == "__main__":
+    gs.parser()
+    main()