[GRASS-SVN] r58564 - in grass/trunk: lib/python/temporal lib/temporal/SQL temporal temporal/t.rast.aggregate temporal/t.rast.aggregate.ds temporal/t.rast.gapfill temporal/t.rast.import temporal/t.rast.series temporal/t.rast3d.univar temporal/t.register temporal/t.remove temporal/t.support temporal/t.unregister

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Dec 30 18:41:37 PST 2013


Author: huhabla
Date: 2013-12-30 18:41:37 -0800 (Mon, 30 Dec 2013)
New Revision: 58564

Added:
   grass/trunk/lib/temporal/SQL/postgresql_delete_trigger.sql
   grass/trunk/lib/temporal/SQL/postgresql_indexes.sql
   grass/trunk/lib/temporal/SQL/sqlite3_indexes.sql
   grass/trunk/temporal/t.register/test.t.register.raster.file.timezone.sh
Removed:
   grass/trunk/lib/temporal/SQL/map_stds_register_table_template.sql
   grass/trunk/lib/temporal/SQL/stds_raster3d_register_trigger_template.sql
   grass/trunk/lib/temporal/SQL/stds_raster_register_trigger_template.sql
   grass/trunk/lib/temporal/SQL/stds_vector_register_trigger_template.sql
   grass/trunk/lib/temporal/SQL/test.temporal.py
Modified:
   grass/trunk/lib/python/temporal/abstract_dataset.py
   grass/trunk/lib/python/temporal/abstract_map_dataset.py
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
   grass/trunk/lib/python/temporal/base.py
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/datetime_math.py
   grass/trunk/lib/python/temporal/extract.py
   grass/trunk/lib/python/temporal/mapcalc.py
   grass/trunk/lib/python/temporal/metadata.py
   grass/trunk/lib/python/temporal/register.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/temporal_extent.py
   grass/trunk/lib/python/temporal/unittests_register.py
   grass/trunk/lib/temporal/SQL/map_tables_template.sql
   grass/trunk/lib/temporal/SQL/raster3d_metadata_table.sql
   grass/trunk/lib/temporal/SQL/raster3d_views.sql
   grass/trunk/lib/temporal/SQL/raster_metadata_table.sql
   grass/trunk/lib/temporal/SQL/raster_views.sql
   grass/trunk/lib/temporal/SQL/sqlite3_delete_trigger.sql
   grass/trunk/lib/temporal/SQL/stds_map_register_table_template.sql
   grass/trunk/lib/temporal/SQL/stds_tables_template.sql
   grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql
   grass/trunk/lib/temporal/SQL/str3ds_views.sql
   grass/trunk/lib/temporal/SQL/strds_metadata_table.sql
   grass/trunk/lib/temporal/SQL/strds_views.sql
   grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql
   grass/trunk/lib/temporal/SQL/stvds_views.sql
   grass/trunk/lib/temporal/SQL/update_stds_spatial_temporal_extent_template.sql
   grass/trunk/lib/temporal/SQL/update_str3ds_metadata_template.sql
   grass/trunk/lib/temporal/SQL/vector_metadata_table.sql
   grass/trunk/lib/temporal/SQL/vector_views.sql
   grass/trunk/temporal/benchmark.sh
   grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
   grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py
   grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py
   grass/trunk/temporal/t.rast.import/test.t.rast.import.relative.sh
   grass/trunk/temporal/t.rast.series/t.rast.series.py
   grass/trunk/temporal/t.rast3d.univar/test.t.rast3d.univar.sh
   grass/trunk/temporal/t.register/t.register.py
   grass/trunk/temporal/t.remove/t.remove.py
   grass/trunk/temporal/t.support/t.support.py
   grass/trunk/temporal/t.support/test.t.support.sh
   grass/trunk/temporal/t.unregister/t.unregister.py
Log:
Modifications are:
- Removed the creation of a register table for each registered map, which speeds things up massively
- Added modification time to space time datasets
- Added aggregation type to space time datasets that will be set by t.rast.aggregate
- Keeping the SQL scripts as simple as possible
- Removed foreign primary keys and created indexes for primary keys in sqlite3 (postgreql does this automagically)
- Using delete trigger instead of foreign primary keys in postgresql backend
- Removed unneeded SQL scripts
- Using Python dateutil module for time string parsing if installed, or a much more simpler parser without time zone support
- Added GRASS environmental variables to allow registration of maps from different mapsets in a space time dataset
- Simplified code for map registration
- Code cleanup ...



Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -148,6 +148,13 @@
         """
 
     @abstractmethod
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+
+    @abstractmethod
     def get_type(self):
         """!Return the type of this class as string
 
@@ -224,6 +231,8 @@
         self.temporal_extent.set_id(ident)
         self.spatial_extent.set_id(ident)
         self.metadata.set_id(ident)
+        if self.is_stds() is False:
+            self.stds_register.set_id(ident)
 
     def get_id(self):
         """!Return the unique identifier of the dataset
@@ -257,23 +266,20 @@
 
     def get_absolute_time(self):
         """!Returns the start time, the end
-           time and the timezone of the map as tuple
+           time of the map as tuple
 
-           @attention: The timezone is currently not used.
-
            The start time is of type datetime.
 
            The end time is of type datetime in case of interval time,
            or None on case of a time instance.
 
-           @return A tuple of (start_time, end_time, timezone)
+           @return A tuple of (start_time, end_time)
         """
 
         start = self.absolute_time.get_start_time()
         end = self.absolute_time.get_end_time()
-        tz = self.absolute_time.get_timezone()
 
-        return (start, end, tz)
+        return (start, end)
 
     def get_relative_time(self):
         """!Returns the start time, the end
@@ -353,6 +359,8 @@
         self.temporal_extent.select(dbif)
         self.spatial_extent.select(dbif)
         self.metadata.select(dbif)
+        if self.is_stds() is False:
+            self.stds_register.select(dbif)
 
         if connected:
             dbif.close()
@@ -379,7 +387,7 @@
             @return The SQL insert statement in case execute=False, or an empty string otherwise
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to insert dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -391,6 +399,8 @@
         statement += self.temporal_extent.get_insert_statement_mogrified(dbif)
         statement += self.spatial_extent.get_insert_statement_mogrified(dbif)
         statement += self.metadata.get_insert_statement_mogrified(dbif)
+        if self.is_stds() is False:
+            statement += self.stds_register.get_insert_statement_mogrified(dbif)
 
         if execute:
             dbif.execute_transaction(statement)
@@ -414,7 +424,7 @@
            @return The SQL update statement in case execute=False, or an empty string otherwise
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                                  {"ds":self.get_id(), "type":self.get_type()})
@@ -430,6 +440,9 @@
                                                                         ident)
         statement += self.metadata.get_update_statement_mogrified(dbif, ident)
 
+        if self.is_stds() is False:
+            statement += self.stds_register.get_update_statement_mogrified(dbif, ident)
+
         if execute:
             dbif.execute_transaction(statement)
             if connected:
@@ -452,7 +465,7 @@
            @return The SQL update statement in case execute=False, or an empty string otherwise
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -467,6 +480,9 @@
             dbif, ident)
         statement += self.metadata.get_update_all_statement_mogrified(dbif, ident)
 
+        if self.is_stds() is False:
+            statement += self.stds_register.get_update_all_statement_mogrified(dbif, ident)
+
         if execute:
             dbif.execute_transaction(statement)
             if connected:

Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -15,7 +15,6 @@
 from abstract_dataset import *
 from datetime_math import *
 
-
 class AbstractMapDataset(AbstractDataset):
     """!This is the base class for all maps (raster, vector, raster3d).
 
@@ -52,27 +51,6 @@
            @return The new space time dataset instance
         """
 
-    @abstractmethod
-    def get_stds_register(self):
-        """!Return the space time dataset register table name
-
-            Maps can be registered in several different space time datasets.
-            This method returns the name of the register table in the
-            temporal database.
-
-            @return The name of the stds register table
-        """
-
-    @abstractmethod
-    def set_stds_register(self, name):
-        """!Set the space time dataset register table name.
-
-           This table stores all space time datasets in
-           which this map is registered.
-
-           @param name The name of the register table
-        """
-
     def check_resolution_with_current_region(self):
         """!Check if the raster or voxel resolution is
            finer than the current resolution
@@ -141,7 +119,7 @@
         start = ""
 
         if self.is_time_absolute():
-            start_time, end_time, tz = self.get_absolute_time()
+            start_time, end_time = self.get_absolute_time()
             start = datetime_to_grass_datetime_string(start_time)
             if end_time is not None:
                 end = datetime_to_grass_datetime_string(end_time)
@@ -212,6 +190,7 @@
         self.temporal_extent.print_self()
         self.spatial_extent.print_self()
         self.metadata.print_self()
+        self.stds_register.print_self()
 
     def print_info(self):
         """!Print information about this object in human readable style"""
@@ -244,9 +223,9 @@
                     string += "\n | ............................ "
                     count = 0
                 if count == 0:
-                    string += ds["id"]
+                    string += ds
                 else:
-                    string += ",%s" % ds["id"]
+                    string += ",%s" % ds
                 count += 1
         print " | Registered datasets ........ " + string
         print " +----------------------------------------------------------------------------+"
@@ -263,9 +242,9 @@
         if datasets is not None:
             for ds in datasets:
                 if count == 0:
-                    string += ds["id"]
+                    string += ds
                 else:
-                    string += ",%s" % ds["id"]
+                    string += ",%s" % ds
                 count += 1
             print "registered_datasets=" + string
 
@@ -278,7 +257,9 @@
 
            This functions assures that the timestamp is written to the
            grass file system based database in addition to the temporal
-           database entry.
+           database entry. The stds register table will be created as well.
+           Hence maps can only be registered in a space time dataset, when
+           they were inserted in the temporal database beforehand.
 
            @param dbif The database interface to be used
            @param execute If True the SQL statements will be executed.
@@ -287,8 +268,9 @@
            @return The SQL insert statement in case execute=False, or an
                    empty string otherwise
         """
-        self.write_timestamp_to_grass()
-        return AbstractDataset.insert(self, dbif, execute)
+        if get_enable_timestamp_write():
+            self.write_timestamp_to_grass()
+        return AbstractDataset.insert(self, dbif=dbif, execute=execute)
 
     def update(self, dbif=None, execute=True):
         """!Update the map content in the database from the internal structure
@@ -305,7 +287,8 @@
            @return The SQL insert statement in case execute=False, or an
                    empty string otherwise
         """
-        self.write_timestamp_to_grass()
+        if get_enable_timestamp_write():
+            self.write_timestamp_to_grass()
         return AbstractDataset.update(self, dbif, execute)
 
     def update_all(self, dbif=None, execute=True):
@@ -323,7 +306,8 @@
             @return The SQL insert statement in case execute=False, or an
                     empty string otherwise
         """
-        self.write_timestamp_to_grass()
+        if get_enable_timestamp_write():
+            self.write_timestamp_to_grass()
         return AbstractDataset.update_all(self, dbif, execute)
 
     def set_time_to_absolute(self):
@@ -334,7 +318,7 @@
         """!Set the temporal type to relative"""
         self.base.set_ttype("relative")
 
-    def set_absolute_time(self, start_time, end_time=None, timezone=None):
+    def set_absolute_time(self, start_time, end_time=None):
         """!Set the absolute time with start time and end time
 
             The end time is optional and must be set to None in case of time
@@ -347,7 +331,6 @@
                              map
            @param end_time a datetime object specifying the end time of the
                            map, None in case or time instance
-           @param timezone Thee timezone of the map (not used)
 
            @return True for success and False otherwise
         """
@@ -401,12 +384,10 @@
         self.base.set_ttype("absolute")
         self.absolute_time.set_start_time(start_time)
         self.absolute_time.set_end_time(end_time)
-        self.absolute_time.set_timezone(timezone)
 
         return True
 
-    def update_absolute_time(self, start_time, end_time=None,
-                             timezone=None, dbif=None):
+    def update_absolute_time(self, start_time, end_time=None, dbif=None):
         """!Update the absolute time
 
            The end time is optional and must be set to None in case of time
@@ -420,17 +401,16 @@
                   the map
            @param end_time a datetime object specifying the end time of the
                   map, None in case or time instance
-           @param timezone Thee timezone of the map (not used)
            @param dbif The database interface to be used
            """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
 
 
-        if self.set_absolute_time(start_time, end_time, timezone):
+        if self.set_absolute_time(start_time, end_time):
             dbif, connected = init_dbif(dbif)
             self.absolute_time.update_all(dbif)
             self.base.update(dbif)
@@ -438,7 +418,8 @@
             if connected:
                 dbif.close()
 
-            self.write_timestamp_to_grass()
+            if get_enable_timestamp_write():
+                self.write_timestamp_to_grass()
 
     def set_relative_time(self, start_time, end_time, unit):
         """!Set the relative time interval
@@ -514,7 +495,7 @@
            @param unit The relative time unit
            @param dbif The database interface to be used
         """
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -527,7 +508,8 @@
             if connected:
                 dbif.close()
 
-            self.write_timestamp_to_grass()
+            if get_enable_timestamp_write():
+                self.write_timestamp_to_grass()
 
     def set_temporal_extent(self, extent):
         """!Convenient method to set the temporal extent from a temporal extent object
@@ -550,11 +532,11 @@
            (datetime.datetime(2000, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0))
 
            >>> map1 = tgis.VectorDataset("A at P")
-           >>> check = map1.set_absolute_time(datetime.datetime(2000,5,5), datetime.datetime(2005,6,6), None)
+           >>> check = map1.set_absolute_time(datetime.datetime(2000,5,5), datetime.datetime(2005,6,6))
            >>> print map1.get_temporal_extent_as_tuple()
            (datetime.datetime(2000, 5, 5, 0, 0), datetime.datetime(2005, 6, 6, 0, 0))
            >>> map2 = tgis.RasterDataset("B at P")
-           >>> check = map2.set_absolute_time(datetime.datetime(1990,1,1), datetime.datetime(1999,8,1), None)
+           >>> check = map2.set_absolute_time(datetime.datetime(1990,1,1), datetime.datetime(1999,8,1))
            >>> print map2.get_temporal_extent_as_tuple()
            (datetime.datetime(1990, 1, 1, 0, 0), datetime.datetime(1999, 8, 1, 0, 0))
            >>> map2.set_temporal_extent(map1.get_temporal_extent())
@@ -573,9 +555,8 @@
         elif issubclass(type(extent), AbsoluteTemporalExtent):
             start = extent.get_start_time()
             end = extent.get_end_time()
-            tz = extent.get_timezone()
 
-            self.set_absolute_time(start, end, tz)
+            self.set_absolute_time(start, end)
 
     def temporal_buffer(self, increment, update=False, dbif=None):
         """!Create a temporal buffer based on an increment
@@ -655,7 +636,7 @@
         """
 
         if self.is_time_absolute():
-            start, end, tz = self.get_absolute_time()
+            start, end = self.get_absolute_time()
 
             new_start = decrement_datetime_by_string(start, increment)
             if end == None:
@@ -664,9 +645,9 @@
                 new_end = increment_datetime_by_string(end, increment)
 
             if update:
-                self.update_absolute_time(new_start, new_end, tz, dbif=dbif)
+                self.update_absolute_time(new_start, new_end, dbif=dbif)
             else:
-                self.set_absolute_time(new_start, new_end, tz)
+                self.set_absolute_time(new_start, new_end)
         else:
             start, end, unit = self.get_relative_time()
             new_start = start - increment
@@ -774,7 +755,7 @@
     def check_for_correct_time(self):
         """!Check for correct time"""
         if self.is_time_absolute():
-            start, end, tz = self.get_absolute_time()
+            start, end= self.get_absolute_time()
         else:
             start, end, unit = self.get_relative_time()
 
@@ -820,7 +801,7 @@
            @return The SQL statements if execute=False, else an empty string,
                    None in case of a failure
         """
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to delete dataset <%(ds)s> of type %(type)s from the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -837,11 +818,6 @@
             statement += self.unregister(
                 dbif=dbif, update=update, execute=False)
 
-            # Remove the strds register table
-            if self.get_stds_register() is not None:
-                statement += "DROP TABLE IF EXISTS " + self.get_stds_register() + ";\n"
-
-
             self.msgr.verbose(_("Delete %s dataset <%s> from temporal database")
                          % (self.get_type(), self.get_id()))
 
@@ -851,6 +827,7 @@
 
         if execute:
             dbif.execute_transaction(statement)
+            statement = ""
 
         # Remove the timestamp from the file system
         self.remove_timestamp_from_grass()
@@ -860,9 +837,6 @@
         if connected:
             dbif.close()
 
-        if execute:
-            return ""
-
         return statement
 
     def unregister(self, dbif=None, update=True, execute=True):
@@ -883,16 +857,16 @@
 
 
         if self.get_layer() is not None:
-            self.msgr.debug(1, _("Unregister %(type)s map <%(map)s> with "
+            self.msgr.debug(1, "Unregister %(type)s map <%(map)s> with "
                            "layer %(layer)s from space time datasets" % \
                          {'type':self.get_type(), 'map':self.get_map_id(),
-                          'layer':self.get_layer()}))
+                          'layer':self.get_layer()})
         else:
-            self.msgr.debug(1, _("Unregister %(type)s map <%(map)s> "
+            self.msgr.debug(1, "Unregister %(type)s map <%(map)s> "
                            "from space time datasets"
-                         % {'type':self.get_type(), 'map':self.get_map_id()}))
+                         % {'type':self.get_type(), 'map':self.get_map_id()})
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to unregister dataset <%(ds)s> of type %(type)s from the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -901,60 +875,144 @@
         dbif, connected = init_dbif(dbif)
 
         # Get all datasets in which this map is registered
-        rows = self.get_registered_datasets(dbif)
+        datasets = self.get_registered_datasets(dbif)
 
         # For each stds in which the map is registered
-        if rows is not None:
-            for row in rows:
-                # Create a space time dataset object to remove the map
-                # from its register
-                stds = self.get_new_stds_instance(row["id"])
-                stds.metadata.select(dbif)
-                statement += stds.unregister_map(self, dbif, False)
-                # Take care to update the space time dataset after
-                # the map has been unregistered
-                if update == True and execute == True:
-                    stds.update_from_registered_maps(dbif)
+        if datasets is not None:
+            for dataset in datasets:
+                    # Create a space time dataset object to remove the map
+                    # from its register
+                    stds = self.get_new_stds_instance(dataset)
+                    stds.metadata.select(dbif)
+                    statement += stds.unregister_map(self, dbif, False)
+                    # Take care to update the space time dataset after
+                    # the map has been unregistered
+                    if update == True and execute == True:
+                        stds.update_from_registered_maps(dbif)
 
         if execute:
             dbif.execute_transaction(statement)
+            statement = ""
 
         if connected:
             dbif.close()
 
-        if execute:
-            return ""
-
         return statement
 
     def get_registered_datasets(self, dbif=None):
         """!Return all space time dataset ids in which this map is registered
-           as dictionary like rows with column "id" or None if this map is not
+           as as a list of strings, or None if this map is not
            registered in any space time dataset.
 
            @param dbif The database interface to be used
-           @return The SQL rows with the ids of all space time datasets in
+           @return A list of ids of all space time datasets in
                    which this map is registered
         """
         dbif, connected = init_dbif(dbif)
 
-        rows = None
+        self.stds_register.select(dbif)
+        datasets = self.stds_register.get_registered_stds()
 
-        try:
-            if self.get_stds_register() is not None:
-                # Select all stds tables in which this map is registered
-                sql = "SELECT id FROM " + self.get_stds_register()
-                dbif.cursor.execute(sql)
-                rows = dbif.cursor.fetchall()
-        except:
-            self.msgr.error(_("Unable to select space time dataset register table "
-                         "<%s>") % (self.get_stds_register()))
+        if datasets is not None and datasets != "" and datasets.find("@") >= 0:
+            datasets = datasets.split(",")
+        else:
+            datasets = None
 
         if connected:
-            dbif.close()
+            dbif.close
 
-        return rows
+        return datasets
 
+    def add_dataset_to_register(self, stds_id, dbif=None, execute=True):
+        """!Add a new space time dataset to the register
+
+           @param stds_id The id of the space time dataset to be registered
+           @param dbif The database interface to be used
+           @param execute If True the SQL INSERT table statements
+                          will be executed.
+                          If False the prepared SQL statements are
+                          returned and must be executed by the caller.
+
+           @return The SQL statements if execute=False, else an empty string
+        """
+        dbif, connected = init_dbif(dbif=dbif)
+
+        datasets = self.get_registered_datasets(dbif=dbif)
+
+        if stds_id is None or stds_id == "":
+            return ""
+
+        # Check if no datasets are present
+        if datasets is None:
+            datasets = []
+
+        # Check if the dataset is already present
+        if stds_id in datasets:
+            if connected:
+                dbif.close
+            return ""
+
+        datasets.append(stds_id)
+
+        self.stds_register.set_registered_stds(",".join(datasets))
+
+        statement = ""
+
+        if execute is True:
+            self.stds_register.update(dbif=dbif)
+        else:
+            statement = self.stds_register.get_update_statement_mogrified(dbif=dbif)
+
+        if connected:
+            dbif.close
+
+        return statement
+
+
+    def remove_dataset_from_register(self, stds_id, dbif=None, execute=True):
+        """!Remove a space time dataset from the register
+
+           @param stds_id The id of the space time dataset to removed from the registered
+           @param dbif The database interface to be used
+           @param execute If True the SQL INSERT table statements
+                          will be executed.
+                          If False the prepared SQL statements are
+                          returned and must be executed by the caller.
+
+           @return The SQL statements if execute=False, else an empty string
+        """
+        dbif, connected = init_dbif(dbif)
+
+        datasets = self.get_registered_datasets(dbif=dbif)
+
+        # Check if no datasets are present
+        if datasets is None:
+            if connected:
+                dbif.close
+            return ""
+
+        # Check if the dataset is already present
+        if stds_id not in datasets:
+            if connected:
+                dbif.close
+            return ""
+
+        datasets.remove(stds_id)
+
+        self.stds_register.set_registered_stds(",".join(datasets))
+
+        statement = ""
+
+        if execute is True:
+            self.stds_register.update(dbif=dbif)
+        else:
+            statement = self.stds_register.get_update_statement_mogrified(dbif=dbif)
+
+        if connected:
+            dbif.close
+
+        return statement
+
 ###############################################################################
 
 if __name__ == "__main__":

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -125,7 +125,7 @@
         """
         self.metadata.print_history()
 
-    def set_initial_values(self, temporal_type, semantic_type,
+    def set_initial_values(self, temporal_type, semantic_type=None,
                            title=None, description=None):
         """!Set the initial values of the space time dataset
 
@@ -157,6 +157,13 @@
         self.metadata.set_description(description)
         self.metadata.set_command(self.create_command_string())
 
+    def set_aggregation_type(self, aggregation_type):
+        """!Set the aggregation type of the space time dataset
+
+           @param aggregation_type The aggregation type of the space time dataset
+        """
+        self.metadata.set_aggregation_type(aggregation_type)
+
     def update_command_string(self, dbif=None):
         """!Append the current command string to any existing command string
            in the metadata class and calls metadata update
@@ -296,6 +303,70 @@
                 self.msgr.fatal(_("Unsupported temporal unit: %s") % (unit))
             self.relative_time.set_unit(unit)
 
+    def insert(self, dbif=None, execute=True):
+        """!Insert the space time dataset content into the database from the internal
+           structure
+
+           The map register table will be created, so that maps
+           can be registered.
+
+           @param dbif The database interface to be used
+           @param execute If True the SQL statements will be executed.
+                          If False the prepared SQL statements are
+                          returned and must be executed by the caller.
+           @return The SQL insert statement in case execute=False, or an
+                   empty string otherwise
+        """
+
+        dbif, connected = init_dbif(dbif)
+
+        # We need to create the register table if it does not exists
+        stds_register_table = self.get_map_register()
+
+        # Create the map register table
+        sql_path = get_sql_template_path()
+        statement = ""
+
+        # We need to create the map register table
+        if stds_register_table is None:
+            # Create table name
+            stds_register_table = self.create_map_register_name()
+            # Assure that the table and index do not exist
+            #dbif.execute_transaction("DROP INDEX IF EXISTS %s; DROP TABLE IF EXISTS   %s;"%(stds_register_table + "_index", stds_register_table))
+
+            # Read the SQL template
+            sql = open(os.path.join(sql_path,
+                                    "stds_map_register_table_template.sql"),
+                                    'r').read()
+            map_type = self.get_new_map_instance(None).get_type()
+            stds_name = self.get_name() + "_" + self.get_mapset()
+
+            # Create a raster, raster3d or vector tables
+            sql = sql.replace("GRASS_MAP", map_type)
+            sql = sql.replace("SPACETIME_NAME", stds_name)
+            statement += sql
+
+            if dbif.dbmi.__name__ == "sqlite3":
+                statement += "CREATE INDEX %s_index ON %s (id);"%(stds_register_table, stds_register_table)
+
+            # Set the map register table name
+            self.set_map_register(stds_register_table)
+
+            self.msgr.debug(1, _("Created register table <%s> for space "
+                           "time %s  dataset <%s>") %
+                          (stds_register_table, self.get_new_map_instance(None).get_type(), self.get_id()))
+
+        statement += AbstractDataset.insert(self, dbif=dbif, execute=False)
+
+        if execute:
+            dbif.execute_transaction(statement)
+            statement = ""
+
+        if connected:
+            dbif.close()
+
+        return statement
+
     def get_map_time(self):
         """!Return the type of the map time, interval, point, mixed or invalid
         """
@@ -329,7 +400,7 @@
         for i in range(len(maps)):
             # Check for point and interval data
             if maps[i].is_time_absolute():
-                start, end, tz = maps[i].get_absolute_time()
+                start, end = maps[i].get_absolute_time()
             if maps[i].is_time_relative():
                 start, end, unit = maps[i].get_relative_time()
 
@@ -1131,7 +1202,7 @@
             map = first.get_new_instance(None)
             map.set_spatial_extent_from_values(0,0,0,0,0,0)
             if first.is_time_absolute():
-                map.set_absolute_time(start, next, None)
+                map.set_absolute_time(start, next)
             else:
                 map.set_relative_time(start, next, first.get_relative_time_unit())
 
@@ -1495,7 +1566,7 @@
                    granularity
 
         """
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to shift dataset <%(ds)s> of type %(type)s in the temporal database."
             " The mapset of the dataset does not match the current mapset")%\
             ({"ds":self.get_id()}, {"type":self.get_type()}))
@@ -1662,7 +1733,7 @@
 
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to snap dataset <%(ds)s> of type %(type)s in the temporal database."
             " The mapset of the dataset does not match the current mapset")%\
             ({"ds":self.get_id()}, {"type":self.get_type()}))
@@ -1738,7 +1809,7 @@
             datasets = map.get_registered_datasets(dbif)
             if datasets:
                 for dataset in datasets:
-                    datatsets_to_modify[dataset["id"]] = dataset["id"]
+                    datatsets_to_modify[dataset] = dataset
 
         self.update_from_registered_maps(dbif)
 
@@ -1762,13 +1833,16 @@
            @param dbif The database interface to be used
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to rename dataset <%(ds)s> of type %(type)s in the temporal database."
             " The mapset of the dataset does not match the current mapset")%\
             ({"ds":self.get_id()}, {"type":self.get_type()}))
 
         dbif, connected = init_dbif(dbif)
 
+        if dbif.dbmi.__name__ != "sqlite3":
+            self.msgr.fatal(_("Renaming of space time datasets is not supported for PostgreSQL."))
+
         # SELECT all needed information from the database
         self.select(dbif)
 
@@ -1790,16 +1864,22 @@
         # Get the update statement, we update the table entry of the old
         # identifier
         statement = self.update(dbif, execute=False, ident=old_ident)
+
         # We need to rename the raster register table
-        statement += "ALTER TABLE %s RENAME TO \"%s\";\n" % \
-                     (old_map_register_table, new_map_register_table)
+        statement += "ALTER TABLE %s RENAME TO \"%s\";\n" % (old_map_register_table, 
+                                                             new_map_register_table)
 
+        # We need to take care of the stds index in the sqlite3 database
+        if dbif.dbmi.__name__ == "sqlite3":
+            statement += "DROP INDEX %s_index;\n" % (old_map_register_table)
+            statement += "CREATE INDEX %s_index ON %s (id);"%(new_map_register_table, 
+                                                              new_map_register_table)
+
         # We need to rename the space time dataset in the maps register table
         if maps:
             for map in maps:
-                map.select()
-                statement += "UPDATE %s SET id = \"%s\" WHERE id = \"%s\";\n"%\
-                             (map.get_stds_register(), ident, old_ident)
+                map.remove_dataset_from_register(stds_id=old_ident, dbif=dbif)
+                map.add_dataset_to_register(stds_id=ident, dbif=dbif)
 
         # Execute the accumulated statements
         dbif.execute_transaction(statement)
@@ -1829,7 +1909,7 @@
                     (self.get_new_map_instance(ident=None).get_type(),
                      self.get_id()))
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to delete dataset <%(ds)s> of type %(type)s from the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -1871,6 +1951,42 @@
 
         return statement
 
+    def is_map_registered(self, map_id, dbif=None):
+        """!Check if a map is registered in the space time dataset
+        
+           @param map_id The map id
+           @param dbif The database interface to be used
+           @return True if success, False otherwise
+        """
+        stds_register_table = self.get_map_register()
+        
+        dbif, connected = init_dbif(dbif)
+        
+        is_registered = False
+        
+        # Check if map is already registered
+        if stds_register_table is not None:
+            if dbif.dbmi.paramstyle == "qmark":
+                sql = "SELECT id FROM " + \
+                    stds_register_table + " WHERE id = (?)"
+            else:
+                sql = "SELECT id FROM " + \
+                    stds_register_table + " WHERE id = (%s)"
+            try:
+                dbif.cursor.execute(sql, (map_id,))
+                row = dbif.cursor.fetchone()
+            except:
+                self.msgr.warning(_("Error in register table request"))
+                raise
+            
+            if row is not None and row[0] == map_id:
+                is_registered = True
+                
+        if connected == True:
+            dbif.close()
+
+        return is_registered
+        
     def register_map(self, map, dbif=None):
         """!Register a map in the space time dataset.
 
@@ -1880,14 +1996,14 @@
             In case the map is already registered this function
             will break with a warning and return False.
 
-            This method raises a ScriptError in case of a fatal error
+            This method raises a FatalError exception in case of a fatal error
 
            @param map The AbstractMapDataset object that should be registered
            @param dbif The database interface to be used
            @return True if success, False otherwise
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to register map in dataset <%(ds)s> of type %(type)s."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -1896,19 +2012,19 @@
 
         if map.is_in_db(dbif) == False:
             dbif.close()
-            self.msgr.fatal(_("Only maps with absolute or relative valid time can "
-                         "be registered"))
+            self.msgr.fatal(_("Only a map that was inserted in the temporal database"
+                              " can be registered in a space time dataset"))
 
         if map.get_layer():
-            self.msgr.verbose(_("Register %s map <%s> with layer %s in space "
-                           "time %s dataset <%s>") % (map.get_type(),
-                                                      map.get_map_id(),
-                                                      map.get_layer(),
-                                                      map.get_type(),
-                                                      self.get_id()))
+            self.msgr.debug(1, "Register %s map <%s> with layer %s in space "
+                           "time %s dataset <%s>" % (map.get_type(),
+                                                     map.get_map_id(),
+                                                     map.get_layer(),
+                                                     map.get_type(),
+                                                     self.get_id()))
         else:
-            self.msgr.verbose(_("Register %s map <%s> in space time %s "
-                           "dataset <%s>") % (map.get_type(), map.get_map_id(),
+            self.msgr.debug(1, "Register %s map <%s> in space time %s "
+                           "dataset <%s>" % (map.get_type(), map.get_map_id(),
                                               map.get_type(), self.get_id()))
 
         # First select all data from the database
@@ -1921,17 +2037,12 @@
             else:
                 self.msgr.fatal(_("Map <%s> has invalid time") % (map.get_map_id()))
 
+        # Get basic info
         map_id = map.base.get_id()
-        map_name = map.base.get_name()
         map_mapset = map.base.get_mapset()
-        map_register_table = map.get_stds_register()
         map_rel_time_unit = map.get_relative_time_unit()
         map_ttype = map.get_temporal_type()
 
-        #print "Map register table", map_register_table
-
-        # Get basic info
-        stds_name = self.base.get_name()
         stds_mapset = self.base.get_mapset()
         stds_register_table = self.get_map_register()
         stds_ttype = self.get_temporal_type()
@@ -1985,128 +2096,20 @@
             self.msgr.fatal(_("Only maps from the same mapset can be registered"))
 
         # Check if map is already registered
-        if stds_register_table is not None:
-            if dbif.dbmi.paramstyle == "qmark":
-                sql = "SELECT id FROM " + \
-                    stds_register_table + " WHERE id = (?)"
+        if self.is_map_registered(map_id, dbif=dbif):
+            if map.get_layer() is not None:
+                self.msgr.warning(_("Map <%(map)s> with layer %(l)s is already "
+                                "registered.") % {'map': map.get_map_id(),
+                                                    'l': map.get_layer()})
             else:
-                sql = "SELECT id FROM " + \
-                    stds_register_table + " WHERE id = (%s)"
-            try:
-                dbif.cursor.execute(sql, (map_id,))
-                row = dbif.cursor.fetchone()
-            except:
-                self.msgr.warning(_("Error in strds_register_table request"))
-                raise
+                self.msgr.warning(_("Map <%s> is already registered.") % (
+                                map.get_map_id()))
+            return False
 
-            if row is not None and row[0] == map_id:
-                if connected == True:
-                    dbif.close()
-
-                if map.get_layer() is not None:
-                    self.msgr.warning(_("Map <%(map)s> with layer %(l)s is already "
-                                   "registered.") % {'map': map.get_map_id(),
-                                                     'l': map.get_layer()})
-                else:
-                    self.msgr.warning(_("Map <%s> is already registered.") % (
-                                 map.get_map_id()))
-                return False
-
-        # Create tables
-        sql_path = get_sql_template_path()
-
-        # We need to create the map raster register table precedes we can
-        # register the map
-        if map_register_table is None:
-            # Create a unique id
-            uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
-
-            map_register_table = uuid_rand + "_" + \
-                self.get_type() + "_register"
-
-            # Read the SQL template
-            sql = open(os.path.join(sql_path,
-                                    "map_stds_register_table_template.sql"),
-                                    'r').read()
-            # Create the raster, raster3d and vector tables
-            sql = sql.replace("GRASS_MAP", map.get_type())
-            sql = sql.replace("MAP_NAME", map_name + "_" + map_mapset)
-            sql = sql.replace("TABLE_NAME", uuid_rand)
-            sql = sql.replace("MAP_ID", map_id)
-            sql = sql.replace("STDS", self.get_type())
-
-            statement += sql
-
-            # Set the stds register table name and put it into the DB
-            map.set_stds_register(map_register_table)
-            statement += map.metadata.get_update_statement_mogrified(dbif)
-
-            if map.get_layer():
-                self.msgr.debug(1, _("Created register table <%s> for "
-                               "%s map <%s> with layer %s") %
-                                (map_register_table, map.get_type(),
-                                 map.get_map_id(), map.get_layer()))
-            else:
-                self.msgr.debug(1, _("Created register table <%s> for %s map <%s>") %
-                                (map_register_table, map.get_type(),
-                                 map.get_map_id()))
-
-        # We need to create the table and register it
-        if stds_register_table is None:
-            # Create table name
-            stds_register_table = self.create_map_register_name()
-            # Assure that the table and index do not exist
-            dbif.execute_transaction("DROP INDEX IF EXISTS %s; DROP TABLE IF EXISTS  %s;"%(stds_register_table + "_index", stds_register_table))
-
-            # Read the SQL template
-            sql = open(os.path.join(sql_path,
-                                    "stds_map_register_table_template.sql"),
-                                    'r').read()
-            # Create the raster, raster3d and vector tables
-            sql = sql.replace("GRASS_MAP", map.get_type())
-            sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset)
-            sql = sql.replace("SPACETIME_ID", self.base.get_id())
-            sql = sql.replace("STDS", self.get_type())
-            statement += sql
-
-            # Set the map register table name and put it into the DB
-            self.set_map_register(stds_register_table)
-            statement += self.metadata.get_update_statement_mogrified(dbif)
-
-            self.msgr.debug(1, _("Created register table <%s> for space "
-                           "time %s  dataset <%s>") %
-                          (stds_register_table, map.get_type(), self.get_id()))
-
-        # We need to execute the statement at this time
-        if statement != "":
-            dbif.execute_transaction(statement)
-
-        statement = ""
-
-        # Register the stds in the map stds register table
-        # Check if the entry is already there
-        if dbif.dbmi.paramstyle == "qmark":
-            sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
-        else:
-            sql = "SELECT id FROM " + map_register_table + " WHERE id = %s"
-        try:
-            dbif.cursor.execute(sql, (self.base.get_id(),))
-            row = dbif.cursor.fetchone()
-        except:
-            row = None
-
-        # In case of no entry make a new one
-        if row is None:
-            if dbif.dbmi.paramstyle == "qmark":
-                sql = "INSERT INTO " + map_register_table + \
-                    " (id) " + "VALUES (?);\n"
-            else:
-                sql = "INSERT INTO " + map_register_table + \
-                    " (id) " + "VALUES (%s);\n"
-
-            statement += dbif.mogrify_sql_statement(
-                (sql, (self.base.get_id(),)))
-
+        # Register the stds in the map stds register table column
+        statement += map.add_dataset_to_register(stds_id=self.base.get_id(), 
+                                                 dbif=dbif, execute=False)
+        
         # Now put the raster name in the stds map register table
         if dbif.dbmi.paramstyle == "qmark":
             sql = "INSERT INTO " + stds_register_table + \
@@ -2114,6 +2117,7 @@
         else:
             sql = "INSERT INTO " + stds_register_table + \
                 " (id) " + "VALUES (%s);\n"
+                
 
         statement += dbif.mogrify_sql_statement((sql, (map_id,)))
 
@@ -2145,7 +2149,7 @@
                    string, None in case of a failure
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to unregister map from dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -2154,53 +2158,29 @@
 
         dbif, connected = init_dbif(dbif)
 
-        # First select needed data from the database
-        map.metadata.select(dbif)
-
-        map_id = map.get_id()
-        map_register_table = map.get_stds_register()
-        stds_register_table = self.get_map_register()
-
         # Check if the map is registered in the space time raster dataset
-        if map_register_table is not None:
-            if dbif.dbmi.paramstyle == "qmark":
-                sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
+        if self.is_map_registered(map.get_id(), dbif) is False:
+            if map.get_layer() is not None:
+                self.msgr.warning(_("Map <%(map)s> with layer %(l)s is not "
+                                "registered in space time dataset "
+                                "<%(base)s>") % {'map': map.get_map_id(),
+                                'l': map.get_layer(), 'base': self.base.get_id()})
             else:
-                sql = "SELECT id FROM " + map_register_table + " WHERE id = %s"
-            try:
-                dbif.cursor.execute(sql, (self.base.get_id(),))
-                row = dbif.cursor.fetchone()
-            except:
-                row = None
+                self.msgr.warning(_("Map <%(map)s> is not registered in space "
+                                "time dataset <%(base)s>") % {'map': map.get_map_id(),
+                                'base': self.base.get_id()})
+            if connected == True:
+                dbif.close()
+            return ""
 
-            # Break if the map is not registered
-            if row is None:
-                if map.get_layer() is not None:
-                    self.msgr.warning(_("Map <%(map)s> with layer %(l)s is not "
-                                   "registered in space time dataset "
-                                   "<%(base)s>") % {'map': map.get_map_id(),
-                                                    'l': map.get_layer(),
-                                                    'base': self.base.get_id()})
-                else:
-                    self.msgr.warning(_("Map <%(map)s> is not registered in space "
-                                   "time dataset <%(base)s>") % {
-                                   'map': map.get_map_id(),
-                                   'base': self.base.get_id()})
-                if connected == True:
-                    dbif.close()
-                return ""
-
-        # Remove the space time raster dataset from the raster dataset register
-        if map_register_table is not None:
-            if dbif.dbmi.paramstyle == "qmark":
-                sql = "DELETE FROM " + map_register_table + " WHERE id = ?;\n"
-            else:
-                sql = "DELETE FROM " + map_register_table + " WHERE id = %s;\n"
-
-            statement += dbif.mogrify_sql_statement(
-                (sql, (self.base.get_id(),)))
-
-        # Remove the raster map from the space time raster dataset register
+        # Remove the space time dataset from the dataset register
+        # We need to execute the statement here, otherwise the space time dataset will not be
+        # removed correctly
+        map.remove_dataset_from_register(self.base.get_id(), 
+                                                      dbif=dbif, execute=True)
+        
+        # Remove the map from the space time dataset register
+        stds_register_table = self.get_map_register()
         if stds_register_table is not None:
             if dbif.dbmi.paramstyle == "qmark":
                 sql = "DELETE FROM " + stds_register_table + " WHERE id = ?;\n"
@@ -2208,10 +2188,11 @@
                 sql = "DELETE FROM " + \
                     stds_register_table + " WHERE id = %s;\n"
 
-            statement += dbif.mogrify_sql_statement((sql, (map_id,)))
+            statement += dbif.mogrify_sql_statement((sql, ( map.get_id(),)))
 
         if execute:
             dbif.execute_transaction(statement)
+            statement = ""
 
         if connected:
             dbif.close()
@@ -2219,13 +2200,10 @@
         # decrease the counter
         self.map_counter -= 1
 
-        if execute:
-            return ""
-
         return statement
 
     def update_from_registered_maps(self, dbif=None):
-        """!This methods updates the spatial and temporal extent as well as
+        """!This methods updates the modification time, the spatial and temporal extent as well as
            type specific metadata. It should always been called after maps
            are registered or unregistered/deleted from the space time dataset.
 
@@ -2236,14 +2214,10 @@
            will be used. If the end time is earlier than the maximum start
            time, it will be replaced by the maximum start time.
 
-           An other solution to automate this is to use the deactivated trigger
-           in the SQL files. But this will result in a huge performance issue
-           in case many maps are registered (>1000).
-
            @param dbif The database interface to be used
         """
 
-        if self.get_mapset() != get_current_mapset():
+        if get_enable_mapset_check() is True and self.get_mapset() != get_current_mapset():
             self.msgr.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
@@ -2301,7 +2275,7 @@
         self.select()
 
         if self.is_time_absolute():
-            start_time, end_time, tz = self.get_absolute_time()
+            start_time, end_time = self.get_absolute_time()
         else:
             start_time, end_time, unit = self.get_relative_time()
 
@@ -2418,6 +2392,10 @@
             self.temporal_extent.set_map_time(None)
             self.temporal_extent.set_granularity(None)
         self.temporal_extent.update_all(dbif)
+        
+        # Set the modification time
+        self.base.set_mtime(datetime.now())
+        self.base.update(dbif)
 
         if connected:
             dbif.close()

Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/base.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -523,7 +523,6 @@
 
 ###############################################################################
 
-
 class DatasetBase(SQLDatabaseInterface):
     """!This is the base class for all maps and spacetime datasets storing
         basic identification information
@@ -552,15 +551,15 @@
          | Name: ...................... soil
          | Mapset: .................... PERMANENT
          | Creator: ................... soeren
+         | Temporal type: ............. absolute
          | Creation time: ............. 2001-01-01 00:00:00
-         | Temporal type: ............. absolute
         >>> t.print_shell_info()
         id=soil at PERMANENT
         name=soil
         mapset=PERMANENT
         creator=soeren
+        temporal_type=absolute
         creation_time=2001-01-01 00:00:00
-        temporal_type=absolute
 
         \endcode
     """
@@ -597,9 +596,6 @@
         self.set_creator(creator)
         self.set_ctime(ctime)
         self.set_ttype(ttype)
-        # Commented out for performance reasons
-        #self.set_mtime(mtime)
-        #self.set_revision(revision)
 
     def set_id(self, ident):
         """!Convenient method to set the unique identifier (primary key)
@@ -676,17 +672,6 @@
         else:
             self.D["temporal_type"] = ttype
 
-#    def set_mtime(self, mtime=None):
-#       """!Set the modification time of the map, if nothing set the current time is used"""
-#       if mtime == None:
-#            self.D["modification_time"] = datetime.now()
-#       else:
-#            self.D["modification_time"] = mtime
-
-#    def set_revision(self, revision=1):
-#       """!Set the revision of the map: if nothing set revision 1 will assumed"""
-#       self.D["revision"] = revision
-
     def get_id(self):
         """!Convenient method to get the unique identifier (primary key)
 
@@ -766,22 +751,6 @@
         else:
             return None
 
-#    def get_mtime(self):
-#       """!Get the modification time of the map, datatype is datetime
-#          @return None if not found"""
-#       if self.D.has_key("modification_time"):
-#           return self.D["modification_time"]
-#       else:
-#           return None
-
-#    def get_revision(self):
-#       """!Get the revision of the map
-#          @return None if not found"""
-#       if self.D.has_key("revision"):
-#           return self.D["revision"]
-#       else:
-#           return None
-
     # Properties of this class
     id = property(fget=get_id, fset=set_id)
     map_id = property(fget=get_map_id, fset=None)
@@ -801,10 +770,8 @@
         if self.get_layer():
             print " | Layer:...................... " + str(self.get_layer())
         print " | Creator: ................... " + str(self.get_creator())
+        print " | Temporal type: ............. " + str(self.get_ttype())
         print " | Creation time: ............. " + str(self.get_ctime())
-        print " | Temporal type: ............. " + str(self.get_ttype())
-#        print " | Modification time: ......... " + str(self.get_mtime())
-#        print " | Revision in database: ...... " + str(self.get_revision())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
@@ -814,10 +781,8 @@
         if self.get_layer():
             print "layer=" + str(self.get_layer())
         print "creator=" + str(self.get_creator())
+        print "temporal_type=" + str(self.get_ttype())
         print "creation_time=" + str(self.get_ctime())
-        print "temporal_type=" + str(self.get_ttype())
-#        print "modification_time=" + str(self.get_mtime())
-#        print "revision=" + str(self.get_revision())
 
 ###############################################################################
 
@@ -872,7 +837,7 @@
     \code
 
     >>> init()
-    >>> t = STDSBase("stds", "soil at PERMANENT", semantic_type="average", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute")
+    >>> t = STDSBase("stds", "soil at PERMANENT", semantic_type="average", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute", mtime=datetime(2001,1,1))
     >>> t.semantic_type
     'average'
     >>> t.print_info()
@@ -881,31 +846,41 @@
      | Name: ...................... soil
      | Mapset: .................... PERMANENT
      | Creator: ................... soeren
+     | Temporal type: ............. absolute
      | Creation time: ............. 2001-01-01 00:00:00
-     | Temporal type: ............. absolute
+     | Modification time:.......... 2001-01-01 00:00:00
      | Semantic type:.............. average
     >>> t.print_shell_info()
     id=soil at PERMANENT
     name=soil
     mapset=PERMANENT
     creator=soeren
+    temporal_type=absolute
     creation_time=2001-01-01 00:00:00
-    temporal_type=absolute
+    modification_time=2001-01-01 00:00:00
     semantic_type=average
 
     \endcode
     """
     def __init__(self, table=None, ident=None, name=None, mapset=None,
                  semantic_type=None, creator=None, ctime=None,
-                 ttype=None):
+                 ttype=None, mtime=None):
         DatasetBase.__init__(self, table, ident, name, mapset, creator,
                               ctime, ttype)
 
         self.set_semantic_type(semantic_type)
+        self.set_mtime(mtime)
 
     def set_semantic_type(self, semantic_type):
         """!Set the semantic type of the space time dataset"""
         self.D["semantic_type"] = semantic_type
+        
+    def set_mtime(self, mtime=None):
+       """!Set the modification time of the space time dataset, if nothing set the current time is used"""
+       if mtime == None:
+            self.D["modification_time"] = datetime.now()
+       else:
+            self.D["modification_time"] = mtime
 
     def get_semantic_type(self):
         """!Get the semantic type of the space time dataset
@@ -914,6 +889,14 @@
             return self.D["semantic_type"]
         else:
             return None
+            
+    def get_mtime(self):
+       """!Get the modification time of the space time dataset, datatype is datetime
+          @return None if not found"""
+       if self.D.has_key("modification_time"):
+           return self.D["modification_time"]
+       else:
+           return None
 
     semantic_type = property(fget=get_semantic_type, fset=set_semantic_type)
 
@@ -921,12 +904,14 @@
         """!Print information about this class in human readable style"""
         DatasetBase.print_info(self)
         #      0123456789012345678901234567890
+        print " | Modification time:.......... " + str(self.get_mtime())
         print " | Semantic type:.............. " + str(
             self.get_semantic_type())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         DatasetBase.print_shell_info(self)
+        print "modification_time=" + str(self.get_mtime())
         print "semantic_type=" + str(self.get_semantic_type())
 
 ###############################################################################
@@ -963,6 +948,101 @@
 
 ###############################################################################
 
+class AbstractSTDSRegister(SQLDatabaseInterface):
+    """!This is the base class for all maps to store the space time datasets
+       as comma separated string in which they are registered
+
+        Usage:
+
+        \code
+
+        >>> init()
+        >>> t = AbstractSTDSRegister("raster", "soil at PERMANENT", "A at P,B at P,C at P")
+        >>> t.id
+        'soil at PERMANENT'
+        >>> t.registered_stds
+        'A at P,B at P,C at P'
+
+        \endcode
+    """
+
+    def __init__(self, table=None, ident=None, registered_stds=None):
+        """!Constructor
+
+            @param table The name of the temporal database table
+                          that should be used to store the values
+            @param ident The unique identifier must be a combination of
+                          the dataset name, layer name and the mapset
+                          "name at mapset" or "name:layer at mapset"
+                          used as as primary key in the temporal database
+            @param stds A comma separted list of space time dataset ids
+        """
+
+        SQLDatabaseInterface.__init__(self, table, ident)
+
+        self.set_id(ident)
+        self.set_registered_stds(registered_stds)
+
+    def set_id(self, ident):
+        """!Convenient method to set the unique identifier (primary key)
+
+           @param ident The unique identifier must be a combination
+                         of the dataset name, layer name and the mapset
+                         "name at mapset" or "name:layer at mapset"
+        """
+        self.ident = ident
+        self.D["id"] = ident
+
+    def set_registered_stds(self, registered_stds):
+        """!Get the comma separated list of space time datasets ids
+           in which this map is registered
+           @param registered_stds A comma separated list of space time dataset ids
+                                  in which this map is registered
+        """
+        self.D["registered_stds"] = registered_stds
+
+    def get_id(self):
+        """!Convenient method to get the unique identifier (primary key)
+
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
+        else:
+            return None
+
+    def get_registered_stds(self):
+        """!Get the comma separated list of space time datasets ids
+           in which this map is registered
+           @return None if not found"""
+        if "registered_stds" in self.D:
+            return self.D["registered_stds"]
+        else:
+            return None
+
+    # Properties of this class
+    id = property(fget=get_id, fset=set_id)
+    registered_stds = property(fget=get_registered_stds, fset=set_registered_stds)
+
+###############################################################################
+
+class RasterSTDSRegister(AbstractSTDSRegister):
+    """!Time stamped raster map base information class"""
+    def __init__(self, ident=None, registered_stds=None):
+        AbstractSTDSRegister.__init__(self, "raster_stds_register", ident, registered_stds)
+
+class Raster3DSTDSRegister(AbstractSTDSRegister):
+    """!Time stamped 3D raster map base information class"""
+    def __init__(self, ident=None, registered_stds=None):
+        AbstractSTDSRegister.__init__(self, "raster3d_stds_register", ident, registered_stds)
+
+class VectorSTDSRegister(AbstractSTDSRegister):
+    """!Time stamped vector map base information class"""
+    def __init__(self, ident=None, registered_stds=None):
+        AbstractSTDSRegister.__init__(self, "vector_stds_register", ident, registered_stds)
+
+###############################################################################
+
 if __name__ == "__main__":
     import doctest
     doctest.testmod()

Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/core.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -34,7 +34,13 @@
 
 @author Soeren Gebbert
 """
+import sys, traceback
 import os
+import locale
+# i18N
+import gettext
+gettext.install('grasslibs', os.path.join(os.getenv("GISBASE"), 'locale'))
+
 import grass.script.core as core
 from datetime import datetime
 from c_libraries_interface import *
@@ -51,9 +57,26 @@
 except:
     pass
 
-# Uncomment this to raise and exception in case of a fatal error
-# core.set_raise_on_error(True)
+###############################################################################
 
+# Profiling function provided by the temporal framework
+def profile_function(func):
+    do_profiling = os.getenv("GRASS_TGIS_PROFILE")
+    
+    if do_profiling is not None:
+        import cProfile, pstats, StringIO
+        pr = cProfile.Profile()
+        pr.enable()
+        func()
+        pr.disable()
+        s = StringIO.StringIO()
+        sortby = 'cumulative'
+        ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
+        ps.print_stats()
+        print s.getvalue()
+    else:
+        func()
+
 # Global variable that defines the backend
 # of the temporal GIS
 # It can either be "sqlite" or "pg"
@@ -62,12 +85,12 @@
 # The version of the temporal framework
 # this value must be an integer larger than 0
 # Increase this value in case of backward incompatible changes in the TGIS API
-tgis_version=1
+tgis_version=2
 # The version of the temporal database since framework and database version can differ
 # this value must be an integer larger than 0
 # Increase this value in case of backward incompatible changes
 # temporal database SQL layout
-tgis_db_version=1
+tgis_db_version=2
 
 # We need to access the current mapset quite often in the framework, so we make
 # global variable that will be initiated when init() is called
@@ -101,6 +124,54 @@
 
 ###############################################################################
 
+# If this global variable is set True, then maps can only be registered in space time datasets
+# with the same mapset. In addition, only maps in the current mapset can be inserted, updated or deleted from
+# the temporal database. 
+# Overwrite this global variable by: g.gisenv set="TGIS_DISABLE_MAPSET_CHECK=True"
+# ATTENTION: Be aware to face corrupted temporal database in case this global variable is set to False.
+#            This feature is highly experimental and violates the grass permission guidance.
+enable_mapset_check = True
+# If this global variable is set True, the timestamps of maps will be written as textfiles
+# for each map that will be inserted or updated in the temporal database using the C-library 
+# timestamp interface.
+# Overwrite this global variable by: g.gisenv set="TGIS_DISABLE_TIMESTAMP_WRITE=True"
+# ATTENTION: Be aware to face corrupted temporal database in case this global variable is set to False.
+#            This feature is highly experimental and violates the grass permission guidance.
+enable_timestamp_write = True
+
+def get_enable_mapset_check():
+    """!Return True if the mapsets should be checked while insert, updatem delete requests
+       and space time dataset registration.
+       
+       If this global variable is set True, then maps can only be registered in space time datasets
+       with the same mapset. In addition, only maps in the current mapset can be inserted, updated or deleted from
+       the temporal database. 
+       Overwrite this global variable by: g.gisenv set="TGIS_DISABLE_MAPSET_CHECK=True"
+       
+       ATTENTION: Be aware to face corrupted temporal database in case this global variable is set to False.
+                  This feature is highly experimental and violates the grass permission guidance.
+    """
+    global enable_mapset_check
+    return enable_mapset_check
+    
+def get_enable_timestamp_write():
+    """!Return True if the map timestamps should be written to the spatial database metadata as well.
+    
+       If this global variable is set True, the timestamps of maps will be written as textfiles
+       for each map that will be inserted or updated in the temporal database using the C-library 
+       timestamp interface.
+       Overwrite this global variable by: g.gisenv set="TGIS_DISABLE_TIMESTAMP_WRITE=True"
+       
+       ATTENTION: Be aware that C-libraries can not access timestamp informations if they are not
+                  written as spatial database metadata, hence modules that make use of timestamps 
+                  using the C-library interface will not work with maps that were created without 
+                  writing the timestamps.
+    """
+    global enable_timestamp_write
+    return enable_timestamp_write
+
+###############################################################################
+
 # The global variable that stores the PyGRASS Messenger object that
 # provides a fast and exit safe interface to the C-library message functions
 message_interface=None
@@ -159,6 +230,15 @@
 
 ###############################################################################
 
+def get_tgis_db_version():
+    """!Get the verion number of the temporal framework
+       @return The version number of the temporal framework as string
+    """
+    global tgis_db_version
+    return tgis_db_version
+
+###############################################################################
+
 def get_tgis_metadata(dbif=None):
     """!Return the tgis metadata table as a list of rows (dicts)
                or None if not present
@@ -190,6 +270,9 @@
        @param kv dictionary generated by grass.script.parse_command("t.connect", flags="pg")
        @param grassenv Grass environemntal variables created by grass.script.gisenv()
     """
+
+    global temporal_dbmi_init_string
+
     if kv == None:
         kv = core.parse_command("t.connect", flags="pg")
     if grassenv == None:
@@ -207,6 +290,7 @@
             string = string.replace(
                 "$LOCATION_NAME", grassenv["LOCATION_NAME"])
             string = string.replace("$MAPSET", grassenv["MAPSET"])
+            temporal_dbmi_init_string = string
             return string
         else:
             msgr.fatal(_("Unable to initialize the temporal GIS DBMI "
@@ -215,6 +299,7 @@
     elif tgis_backend == "pg":
         if "database" in kv:
             string = kv["database"]
+            temporal_dbmi_init_string = string
             return string
     else:
         msgr.fatal(_("Unable to initialize the temporal GIS DBMI "
@@ -230,35 +315,65 @@
 
 ###############################################################################
 
-def init(raise_on_error=False):
-    """!This function set the correct database backend from the environmental variables
+def init():
+    """!This function set the correct database backend from GRASS environmental variables
        and creates the grass location database structure for raster,
        vector and raster3d maps as well as for the space-time datasets strds,
-       str3ds and stvds in case it not exists.
+       str3ds and stvds in case it does not exists.
+       
+       Several global variables are initiated and the messenger and C-library interface
+       subprocesses are spawned.
+       
+       The following g.gisenv variables are checked:
+        - TGIS_RAISE_ON_ERROR
+        - TGIS_DISABLE_MAPSET_CHECK
+        - TGIS_DISABLE_TIMESTAMP_WRITE
+        
+       The following environmental variables are checked:
+        - GRASS_TGIS_PROFILE
 
         ATTENTION: This functions must be called before any spatio-temporal processing
                    can be started
-
-       @param raise_on_error If True raise a FatalError exception in case of a fatal error,
-                             call sys.exit(1) otherwise
-
     """
     # We need to set the correct database backend from the environment variables
     global tgis_backend
-
+    global enable_mapset_check
+    global enable_timestamp_write
+    
     core.run_command("t.connect", flags="c")
     kv = core.parse_command("t.connect", flags="pg")
     grassenv = core.gisenv()
+    raise_on_error = False
 
+    # Check the g.gisenv variable TGIS_RAISE_ON_ERROR
+    if grassenv.has_key("TGIS_RAISE_ON_ERROR"):
+        if grassenv["TGIS_RAISE_ON_ERROR"] == "True" or grassenv["TGIS_RAISE_ON_ERROR"] == "1":
+            raise_on_error = True
+            
     # Set the global variable current_mapset for fast mapset access
     _set_current_mapset(grassenv["MAPSET"])
     # Start the GRASS message interface server
     _init_tgis_message_interface(raise_on_error)
     # Start the C-library interface server
     _init_tgis_c_library_interface()
-
+    
     msgr = get_tgis_message_interface()
+    msgr.debug(1, "Inititate the temporal database")
+    
+    if raise_on_error is True:
+        msgr.warning("TGIS_RAISE_ON_ERROR is True")
 
+    # Set the mapset check and the timestamp write
+    if grassenv.has_key("TGIS_DISABLE_MAPSET_CHECK"):
+        if grassenv["TGIS_DISABLE_MAPSET_CHECK"] == "True" or grassenv["TGIS_DISABLE_MAPSET_CHECK"] == "1":
+            enable_mapset_check = False
+            msgr.warning("TGIS_DISABLE_MAPSET_CHECK is True")
+
+    if grassenv.has_key("TGIS_DISABLE_TIMESTAMP_WRITE"):
+        if grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"] == "True" or grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"] == "1":
+            enable_timestamp_write = False
+            msgr.warning("TGIS_DISABLE_TIMESTAMP_WRITE is True")
+
     if "driver" in kv:
         if kv["driver"] == "sqlite":
             tgis_backend = kv["driver"]
@@ -309,35 +424,24 @@
         if dbif.cursor.fetchone()[0]:
             db_exists = True
 
-    if db_exists:
-        # Check if we have to add the command column
-        add_command_col = True
-        rows = get_tgis_metadata(dbif)
-        if rows:
-            for row in rows:
-                if row["key"] == "tgis_db_version":
-                    version = int(row["value"])
-                    if version >= 1:
-                        add_command_col = False
-
-        if add_command_col:
-            # Try to add the command column to the space time dataset metadata tables
-            # this is due backward compatibility with old databases
-            try:
-                dbif.cursor.execute('ALTER TABLE strds_metadata ADD COLUMN command VARCHAR;')
-            except:
-                pass
-            try:
-                dbif.cursor.execute('ALTER TABLE str3ds_metadata ADD COLUMN command VARCHAR;')
-            except:
-                pass
-            try:
-                dbif.cursor.execute('ALTER TABLE stvds_metadata ADD COLUMN command VARCHAR;')
-            except:
-                pass
-
     if db_exists == True:
+        
+        # Check the version of the temporal database
+        # This version works only with database of version 2
         dbif.close()
+        dbif.connect()
+        metadata = get_tgis_metadata(dbif)
+        dbif.close()
+        if metadata is None:
+            msgr.fatal(_("Unable to receiving temporal database metadata. Your temporal database is not supported."))
+        
+        for entry in metadata:
+            if "tgis_version" in entry and entry[1] != str(get_tgis_version()):
+                msgr.fatal(_("Unsupported temporal database. Version mismatch.\n"
+                "Supported temporal API version is: %(api)i")%({"api":get_tgis_version()}))
+            if "tgis_db_version" in entry and entry[1] != str(get_tgis_db_version()):
+                msgr.fatal(_("Unsupported temporal database. Version mismatch.\n"
+                "Supported temporal database version is: %(tdb)i")%( {"tdb":get_tgis_db_version()}))
         return
 
     create_temporal_database(dbif, database)
@@ -415,10 +519,19 @@
         tgis_dir = os.path.dirname(database)
         if not os.path.exists(tgis_dir):
             os.makedirs(tgis_dir)
-        # Sqlite needs some trigger to emulate the foreign keys
-        sqlite3_delete_trigger_sql = open(os.path.join(template_path,
-                                                       "sqlite3_delete_trigger.sql"),
-                                                       'r').read()
+        # Set up the trigger that takes care of
+        # the correct deletion of entries across the different tables
+        delete_trigger_sql = open(os.path.join(template_path,
+                                               "sqlite3_delete_trigger.sql"),
+                                               'r').read()
+        indexes_sql = open(os.path.join(template_path, "sqlite3_indexes.sql"), 'r').read()
+    else:
+        # Set up the trigger that takes care of
+        # the correct deletion of entries across the different tables
+        delete_trigger_sql = open(os.path.join(template_path,
+                                            "postgresql_delete_trigger.sql"),
+                                            'r').read()
+        indexes_sql = open(os.path.join(template_path, "postgresql_indexes.sql"), 'r').read()
 
     # Connect now to the database
     if not dbif.connected:
@@ -446,8 +559,10 @@
     dbif.execute_transaction(str3ds_metadata_sql)
     dbif.execute_transaction(str3ds_views_sql)
 
-    if tgis_backend == "sqlite":
-        dbif.execute_transaction(sqlite3_delete_trigger_sql)
+    # The delete trigger
+    dbif.execute_transaction(delete_trigger_sql)
+    # The indexes
+    dbif.execute_transaction(indexes_sql)
 
     # Create the tgis metadata table to store the database
     # initial configuration
@@ -455,7 +570,6 @@
     metadata = {}
     metadata["tgis_version"] = tgis_version
     metadata["tgis_db_version"] = tgis_db_version
-    metadata["has_command_column"] = True
     metadata["creation_time"] = datetime.today()
     _create_tgis_metadata_table(metadata, dbif)
 
@@ -502,7 +616,7 @@
         else:
             self.dbmi = psycopg2
 
-        msgr = get_tgis_message_interface()
+        self.msgr = get_tgis_message_interface()
 
     def rollback(self):
         """
@@ -521,7 +635,6 @@
            Supported backends are sqlite3 and postgresql
         """
         self.database = get_temporal_dbmi_init_string()
-        #print "Connect to",  self.database
         if self.dbmi.__name__ == "sqlite3":
             self.connection = self.dbmi.connect(self.database,
                     detect_types = self.dbmi.PARSE_DECLTYPES | self.dbmi.PARSE_COLNAMES)
@@ -680,8 +793,7 @@
         except:
             if connected:
                 self.close()
-            msgr.error(_("Unable to execute transaction:\n %(sql)s" % \
-                         {"sql":statement}))
+            self.msgr.error(_("Unable to execute transaction:\n %(sql)s" % {"sql":statement}))
             raise
 
         if connected:

Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/datetime_math.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -15,6 +15,12 @@
 from core import *
 import copy
 
+try:
+    import dateutil.parser as parser
+    has_dateutil = True
+except:
+    has_dateutil = False
+
 DAY_IN_SECONDS = 86400
 SECOND_AS_DAY = 1.1574074074074073e-05
 
@@ -708,6 +714,24 @@
         @return datetime object or an error message string in case of an error
     """
 
+    global has_dateutil
+        
+    if has_dateutil:
+        # First check if there is only a single number, which specifies relative time.
+        # dateutil will interprete a single number as a valid time string, so we have
+        # to catch this case beforehand
+        try:
+            value = int(time_string)
+            return _("Time string seems to specify relative time")
+        except ValueError:
+            pass
+        
+        try:
+            time_object = parser.parse(time_string)
+        except Exception as inst:
+            time_object = str(inst)
+        return time_object
+        
     # BC is not supported
     if time_string.find("bc") > 0:
         return _("Dates Before Christ are not supported")
@@ -732,12 +756,14 @@
 def string_to_datetime(time_string):
     """!Convert a string into a datetime object
 
-        Supported ISO string formats are:
+        In case datutil is not installed the supported ISO string formats are:
         - YYYY-mm-dd
         - YYYY-mm-dd HH:MM:SS
+        - Time zones are not supported
+        
+        If dateutil is installed, all string formats of the dateutil module
+        are supported, as well as time zones
 
-        Time zones are not supported
-
         @param time_string The time string to convert
         @return datetime object or None in case the string 
                          could not be converted
@@ -754,23 +780,47 @@
 
     return time_object
 
-
-
 ###############################################################################
 
 
 def datetime_to_grass_datetime_string(dt):
-    """!Convert a python datetime object into a GRASS datetime string"""
-
+    """!Convert a python datetime object into a GRASS datetime string
+    
+    @code
+    
+    >>> import grass.temporal as tgis
+    >>> import dateutil.parser as parser
+    >>> dt = parser.parse("2011-01-01 10:00:00 +01:30")
+    >>> tgis.datetime_to_grass_datetime_string(dt)
+    '01 jan 2011 10:00:00 +0090'
+    >>> dt = parser.parse("2011-01-01 10:00:00 +02:30")
+    >>> tgis.datetime_to_grass_datetime_string(dt)
+    '01 jan 2011 10:00:00 +0150'
+    >>> dt = parser.parse("2011-01-01 10:00:00 +12:00")
+    >>> tgis.datetime_to_grass_datetime_string(dt)
+    '01 jan 2011 10:00:00 +0720'
+    >>> dt = parser.parse("2011-01-01 10:00:00 -01:30")
+    >>> tgis.datetime_to_grass_datetime_string(dt)
+    '01 jan 2011 10:00:00 -0090'
+    
+    @endcode
+    """
     # GRASS datetime month names
     month_names = ["", "jan", "feb", "mar", "apr", "may", "jun",
                    "jul", "aug", "sep", "oct", "nov", "dec"]
 
     # Check for time zone info in the datetime object
     if dt.tzinfo is not None:
+        
+        tz = dt.tzinfo.utcoffset(0)
+        if tz.seconds > 86400 / 2:
+            tz = (tz.seconds - 86400) / 60
+        else:
+            tz = tz.seconds/60
+            
         string = "%.2i %s %.2i %.2i:%.2i:%.2i %+.4i" % (dt.day,
                  month_names[dt.month], dt.year,
-                 dt.hour, dt.minute, dt.second, dt.tzinfo._offset.seconds / 60)
+                 dt.hour, dt.minute, dt.second, tz)
     else:
         string = "%.2i %s %.4i %.2i:%.2i:%.2i" % (dt.day, month_names[
             dt.month], dt.year, dt.hour, dt.minute, dt.second)

Modified: grass/trunk/lib/python/temporal/extract.py
===================================================================
--- grass/trunk/lib/python/temporal/extract.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/extract.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -210,12 +210,7 @@
                                 continue
 
                     # Set the time stamp
-                    if old_map.is_time_absolute():
-                        start, end, tz = old_map.get_absolute_time()
-                        new_map.set_absolute_time(start, end, tz)
-                    else:
-                        start, end, unit = old_map.get_relative_time()
-                        new_map.set_relative_time(start, end, unit)
+                    new_map.set_temporal_extent(old_map.get_temporal_extent())
 
                     # Insert map in temporal database
                     new_map.insert(dbif)

Modified: grass/trunk/lib/python/temporal/mapcalc.py
===================================================================
--- grass/trunk/lib/python/temporal/mapcalc.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/mapcalc.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -238,8 +238,8 @@
 
             # Set the time stamp
             if sample_map_list[i].is_time_absolute():
-                start, end, tz = sample_map_list[i].get_absolute_time()
-                new_map.set_absolute_time(start, end, tz)
+                start, end = sample_map_list[i].get_absolute_time()
+                new_map.set_absolute_time(start, end)
             else:
                 start, end, unit = sample_map_list[i].get_relative_time()
                 new_map.set_relative_time(start, end, unit)
@@ -422,7 +422,7 @@
        * start_second() - The second of the start time [0 - 59]
     """
 
-    start, end, tz = current.get_absolute_time()
+    start, end = current.get_absolute_time()
     msgr = get_tgis_message_interface()
 
     if expr.find("start_year()") >= 0:
@@ -505,7 +505,7 @@
        null()
     """
 
-    start, end, tz = current.get_absolute_time()
+    start, end = current.get_absolute_time()
     msgr = get_tgis_message_interface()
 
     if expr.find("end_year()") >= 0:
@@ -608,7 +608,7 @@
     if expr.find("td()") >= 0:
         td = "null()"
         if is_time_absolute:
-            start, end, tz = current.get_absolute_time()
+            start, end = current.get_absolute_time()
             if end != None:
                 td = time_delta_to_relative_time(end - start)
         else:
@@ -630,8 +630,8 @@
     time, and in relative units in case of relative time."""
     if expr.find("start_time()") >= 0:
         if is_time_absolute:
-            start1, end, tz = first.get_absolute_time()
-            start, end, tz = current.get_absolute_time()
+            start1, end = first.get_absolute_time()
+            start, end = current.get_absolute_time()
             x = time_delta_to_relative_time(start - start1)
         else:
             start1, end, unit = first.get_relative_time()
@@ -656,8 +656,8 @@
     if expr.find("end_time()") >= 0:
         x = "null()"
         if is_time_absolute:
-            start1, end, tz = first.get_absolute_time()
-            start, end, tz = current.get_absolute_time()
+            start1, end = first.get_absolute_time()
+            start, end = current.get_absolute_time()
             if end:
                 x = time_delta_to_relative_time(end - start1)
         else:

Modified: grass/trunk/lib/python/temporal/metadata.py
===================================================================
--- grass/trunk/lib/python/temporal/metadata.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/metadata.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -271,8 +271,7 @@
 
         The metadata includes the datatype, number of cols, rows and cells and
         the north-south and east west resolution of the map. Additionally the
-        minimum and maximum values and the name of the space time raster dataset
-        register table is stored.
+        minimum and maximum valuesare stored.
 
         Usage:
 
@@ -298,7 +297,6 @@
         0.0
         >>> meta.max
         100.0
-        >>> meta.strds_register
         >>> meta.print_info()
          +-------------------- Metadata information ----------------------------------+
          | Datatype:................... CELL
@@ -309,7 +307,6 @@
          | East-west resolution:....... 0.1
          | Minimum value:.............. 0.0
          | Maximum value:.............. 100.0
-         | STRDS register table ....... None
         >>> meta.print_shell_info()
         datatype=CELL
         cols=100
@@ -319,11 +316,10 @@
         ewres=0.1
         min=0.0
         max=100.0
-        strds_register=None
 
         @endcode
     """
-    def __init__(self, ident=None, strds_register=None, datatype=None,
+    def __init__(self, ident=None, datatype=None,
 		 cols=None, rows=None, number_of_cells=None, nsres=None,
 		 ewres=None, min=None, max=None):
 
@@ -331,34 +327,15 @@
                                       cols, rows, number_of_cells, nsres,
                                       ewres, min, max)
 
-        self.set_strds_register(strds_register)
-
-    def set_strds_register(self, strds_register):
-        """!Set the space time raster dataset register table name"""
-        self.D["strds_register"] = strds_register
-
-    def get_strds_register(self):
-        """!Get the space time raster dataset register table name
-           @return None if not found"""
-        if "strds_register" in self.D:
-            return self.D["strds_register"]
-        else:
-            return None
-
-    strds_register = property(fget=get_strds_register, fset=set_strds_register)
-
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
         RasterMetadataBase.print_info(self)
-        print " | STRDS register table ....... " + str(
-            self.get_strds_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         RasterMetadataBase.print_shell_info(self)
-        print "strds_register=" + str(self.get_strds_register())
 
 ###############################################################################
 
@@ -403,7 +380,6 @@
         0.0
         >>> meta.max
         100.0
-        >>> meta.str3ds_register
         >>> meta.print_info()
          +-------------------- Metadata information ----------------------------------+
          | Datatype:................... FCELL
@@ -416,7 +392,6 @@
          | Maximum value:.............. 100.0
          | Number of depths:........... 100
          | Top-Bottom resolution:...... 0.1
-         | STR3DS register table ...... None
         >>> meta.print_shell_info()
         datatype=FCELL
         cols=100
@@ -426,13 +401,12 @@
         ewres=0.1
         min=0.0
         max=100.0
-        str3ds_register=None
         depths=100
         tbres=0.1
 
         @endcode
     """
-    def __init__(self, ident=None, str3ds_register=None, datatype=None,
+    def __init__(self, ident=None, datatype=None,
 		 cols=None, rows=None, depths=None, number_of_cells=None,
 		 nsres=None, ewres=None, tbres=None, min=None, max=None):
 
@@ -440,14 +414,9 @@
 				datatype, cols, rows, number_of_cells, nsres,
 				ewres, min, max)
 
-        self.set_str3ds_register(str3ds_register)
         self.set_tbres(tbres)
         self.set_depths(depths)
 
-    def set_str3ds_register(self, str3ds_register):
-        """!Set the space time raster3d dataset register table name"""
-        self.D["str3ds_register"] = str3ds_register
-
     def set_depths(self, depths):
         """!Set the number of depths"""
         if depths is not None:
@@ -462,14 +431,6 @@
         else:
             self.D["tbres"] = None
 
-    def get_str3ds_register(self):
-        """!Get the space time raster3d dataset register table name
-           @return None if not found"""
-        if "str3ds_register" in self.D:
-            return self.D["str3ds_register"]
-        else:
-            return None
-
     def get_depths(self):
         """!Get number of depths
            @return None if not found"""
@@ -488,7 +449,6 @@
 
     depths = property(fget=get_depths, fset=set_depths)
     tbres = property(fget=get_tbres, fset=set_tbres)
-    str3ds_register = property(fget=get_str3ds_register, fset=set_str3ds_register)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
@@ -498,13 +458,10 @@
         #      0123456789012345678901234567890
         print " | Number of depths:........... " + str(self.get_depths())
         print " | Top-Bottom resolution:...... " + str(self.get_tbres())
-        print " | STR3DS register table ...... " + str(
-                                                self.get_str3ds_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         RasterMetadataBase.print_shell_info(self)
-        print "str3ds_register=" + str(self.get_str3ds_register())
         print "depths=" + str(self.get_depths())
         print "tbres=" + str(self.get_tbres())
 
@@ -558,7 +515,6 @@
         12
         >>> meta.print_info()
          +-------------------- Metadata information ----------------------------------+
-         | STVDS register table ....... None
          | Is map 3d .................. True
          | Number of points ........... 1
          | Number of lines ............ 2
@@ -573,7 +529,6 @@
          | Number of holes ............ 11
          | Number of volumes .......... 12
         >>> meta.print_shell_info()
-        stvds_register=None
         is_3d=True
         points=1
         lines=2
@@ -591,7 +546,7 @@
         @endcode
     """
     def __init__(
-        self, ident=None, stvds_register=None, is_3d=False,
+        self, ident=None, is_3d=False,
         number_of_points=None, number_of_lines=None, number_of_boundaries=None,
         number_of_centroids=None, number_of_faces=None, number_of_kernels=None,
         number_of_primitives=None, number_of_nodes=None, number_of_areas=None,
@@ -600,7 +555,6 @@
         SQLDatabaseInterface.__init__(self, "vector_metadata", ident)
 
         self.set_id(ident)
-        self.set_stvds_register(stvds_register)
         self.set_3d_info(is_3d)
         self.set_number_of_points(number_of_points)
         self.set_number_of_lines(number_of_lines)
@@ -620,10 +574,6 @@
         self.ident = ident
         self.D["id"] = ident
 
-    def set_stvds_register(self, stvds_register):
-        """!Set the space time vector dataset register table name"""
-        self.D["stvds_register"] = stvds_register
-
     def set_3d_info(self, is_3d):
         """!Set True if the vector map is three dimensional"""
         self.D["is_3d"] = is_3d
@@ -685,14 +635,6 @@
         else:
             return None
 
-    def get_stvds_register(self):
-        """!Get the space time vector dataset register table name
-           @return None if not found"""
-        if "stvds_register" in self.D:
-            return self.D["stvds_register"]
-        else:
-            return None
-
     def get_3d_info(self):
         """!Return True if the map is three dimensional,
            False if not and None if not info was found"""
@@ -799,8 +741,6 @@
 
     # Set the properties
     id  = property(fget=get_id, fset=set_id)
-    stvds_register  = property(fget=get_stvds_register,
-                               fset=set_stvds_register)
     is_3d  = property(fget=get_3d_info, fset=set_3d_info)
     number_of_points = property(fget=get_number_of_points,
                                 fset=set_number_of_points)
@@ -831,8 +771,6 @@
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " +-------------------- Metadata information ----------------------------------+"
-        print " | STVDS register table ....... " + str(
-            self.get_stvds_register())
         print " | Is map 3d .................. " + str(self.get_3d_info())
         print " | Number of points ........... " + str(self.get_number_of_points())
         print " | Number of lines ............ " + str(self.get_number_of_lines())
@@ -849,7 +787,6 @@
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        print "stvds_register=" + str(self.get_stvds_register())
         print "is_3d=" + str(self.get_3d_info())
         print "points=" + str(self.get_number_of_points())
         print "lines=" + str(self.get_number_of_lines())
@@ -1068,6 +1005,7 @@
          | Minimum value max:.......... None
          | Maximum value min:.......... None
          | Maximum value max:.......... None
+         | Aggregation type:........... None
          | Number of registered maps:.. None
          |
          | Title:
@@ -1076,6 +1014,7 @@
          | Soils 1950 - 2010
          | Command history:
         >>> meta.print_shell_info()
+        aggregation_type=None
         number_of_maps=None
         nsres_min=None
         nsres_max=None
@@ -1088,7 +1027,7 @@
 
         @endcode
     """
-    def __init__(self, table=None, ident=None, title=None, description=None):
+    def __init__(self, table=None, ident=None, title=None, description=None, aggregation_type=None):
 
         STDSMetadataBase.__init__(self, table, ident, title, description)
 
@@ -1101,7 +1040,21 @@
         self.D["nsres_max"] = None
         self.D["ewres_min"] = None
         self.D["ewres_max"] = None
+        self.D["aggregation_type"] = aggregation_type
 
+    def set_aggregation_type(self, aggregation_type):
+        """!Set the aggregation type of the dataset (mean, min, max, ...)"""
+        self.D["aggregation_type"] = aggregation_type
+
+    def get_aggregation_type(self):
+        """!Get the aggregation type of the dataset (mean, min, max, ...)
+           @return None if not found
+        """
+        if "aggregation_type" in self.D:
+            return self.D["aggregation_type"]
+        else:
+            return None
+            
     def get_max_min(self):
         """!Get the minimal maximum of all registered maps,
            this value is set in the database
@@ -1190,6 +1143,8 @@
     min_max = property(fget=get_min_max)
     max_min = property(fget=get_max_min)
     max_max = property(fget=get_max_max)
+    aggregation_type = property(fset=set_aggregation_type, 
+                                fget=get_aggregation_type)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
@@ -1202,10 +1157,12 @@
         print " | Minimum value max:.......... " + str(self.get_min_max())
         print " | Maximum value min:.......... " + str(self.get_max_min())
         print " | Maximum value max:.......... " + str(self.get_max_max())
+        print " | Aggregation type:........... " + str(self.get_aggregation_type())
         STDSMetadataBase.print_info(self)
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
+        print "aggregation_type=" + str(self.get_aggregation_type())
         STDSMetadataBase.print_shell_info(self)
         print "nsres_min=" + str(self.get_nsres_min())
         print "nsres_max=" + str(self.get_nsres_max())
@@ -1264,6 +1221,7 @@
          | Minimum value max:.......... None
          | Maximum value min:.......... None
          | Maximum value max:.......... None
+         | Aggregation type:........... None
          | Number of registered maps:.. None
          |
          | Title:
@@ -1272,6 +1230,7 @@
          | Soils 1950 - 2010
          | Command history:
         >>> meta.print_shell_info()
+        aggregation_type=None
         number_of_maps=None
         nsres_min=None
         nsres_max=None
@@ -1372,6 +1331,7 @@
          | Minimum value max:.......... None
          | Maximum value min:.......... None
          | Maximum value max:.......... None
+         | Aggregation type:........... None
          | Number of registered maps:.. None
          |
          | Title:
@@ -1380,6 +1340,7 @@
          | Soils 1950 - 2010
          | Command history:
         >>> meta.print_shell_info()
+        aggregation_type=None
         number_of_maps=None
         nsres_min=None
         nsres_max=None

Modified: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/register.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -239,9 +239,10 @@
 
             # Save the datasets that must be updated
             datasets = map.get_registered_datasets(dbif)
-            if datasets:
+            if datasets is not None:
                 for dataset in datasets:
-                    datatsets_to_modify[dataset["id"]] = dataset["id"]
+                    if dataset != "":
+                        datatsets_to_modify[dataset] = dataset
 
                 if name and map.get_temporal_type() != sp.get_temporal_type():
                     dbif.close()
@@ -398,7 +399,7 @@
             msgr.debug(1, _("Set absolute valid time for map <%s> to %s - %s") %
                          (map.get_map_id(), str(start_time), str(end_time)))
 
-        map.set_absolute_time(start_time, end_time, None)
+        map.set_absolute_time(start_time, end_time)
     else:
         start_time = int(start)
         end_time = None

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -73,7 +73,6 @@
          | East-west resolution:....... 10.0
          | Minimum value:.............. 1.0
          | Maximum value:.............. 1.0
-         | STRDS register table ....... None
 
         >>> newmap = rmap.get_new_instance("new at PERMANENT")
         >>> isinstance(newmap, RasterDataset)
@@ -83,12 +82,11 @@
         True
         >>> rmap.get_type()
         'raster'
-        >>> rmap.get_stds_register()
         >>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
         ...                        end_time=datetime(2012,1,1))
         True
         >>> rmap.get_absolute_time()
-        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> rmap.get_temporal_extent_as_tuple()
         (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> rmap.get_name()
@@ -114,6 +112,13 @@
         AbstractMapDataset.__init__(self)
         self.reset(ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return False
+        
     def get_type(self):
         return 'raster'
 
@@ -126,16 +131,6 @@
         are stored with the type of this class"""
         return SpaceTimeRasterDataset(ident)
 
-    def get_stds_register(self):
-        """!Return the space time dataset register table name in which stds
-        are listed in which this map is registered"""
-        return self.metadata.get_strds_register()
-
-    def set_stds_register(self, name):
-        """!Set the space time dataset register table name in which stds
-        are listed in which this map is registered"""
-        self.metadata.set_strds_register(name)
-
     def spatial_overlapping(self, dataset):
         """!Return True if the spatial extents 2d overlap"""
         return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
@@ -199,6 +194,7 @@
         self.relative_time = RasterRelativeTime(ident=ident)
         self.spatial_extent = RasterSpatialExtent(ident=ident)
         self.metadata = RasterMetadata(ident=ident)
+        self.stds_register = RasterSTDSRegister(ident=ident)
 
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
@@ -229,7 +225,7 @@
             return False
 
         if len(dates) == 2:
-            self.set_absolute_time(dates[0], dates[1], None)
+            self.set_absolute_time(dates[0], dates[1])
         else:
             self.set_relative_time(dates[0], dates[1], dates[2])
 
@@ -380,7 +376,6 @@
          | Maximum value:.............. 1.0
          | Number of depths:........... 10
          | Top-Bottom resolution:...... 10.0
-         | STR3DS register table ...... None
 
         >>> newmap = r3map.get_new_instance("new at PERMANENT")
         >>> isinstance(newmap, Raster3DDataset)
@@ -390,12 +385,11 @@
         True
         >>> r3map.get_type()
         'raster3d'
-        >>> r3map.get_stds_register()
         >>> r3map.set_absolute_time(start_time=datetime(2001,1,1),
         ...                        end_time=datetime(2012,1,1))
         True
         >>> r3map.get_absolute_time()
-        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> r3map.get_temporal_extent_as_tuple()
         (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> r3map.get_name()
@@ -418,6 +412,13 @@
         AbstractMapDataset.__init__(self)
         self.reset(ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return False
+        
     def get_type(self):
         return "raster3d"
 
@@ -430,16 +431,6 @@
         are stored with the type of this class"""
         return SpaceTimeRaster3DDataset(ident)
 
-    def get_stds_register(self):
-        """!Return the space time dataset register table name in
-        which stds are listed in which this map is registered"""
-        return self.metadata.get_str3ds_register()
-
-    def set_stds_register(self, name):
-        """!Set the space time dataset register table name in
-        which stds are listed in which this map is registered"""
-        self.metadata.set_str3ds_register(name)
-
     def spatial_overlapping(self, dataset):
         """!Return True if the spatial extents overlap"""
         if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
@@ -518,6 +509,7 @@
         self.relative_time = Raster3DRelativeTime(ident=ident)
         self.spatial_extent = Raster3DSpatialExtent(ident=ident)
         self.metadata = Raster3DMetadata(ident=ident)
+        self.stds_register = Raster3DSTDSRegister(ident=ident)
 
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
@@ -548,7 +540,7 @@
             return False
 
         if len(dates) == 2:
-            self.set_absolute_time(dates[0], dates[1], None)
+            self.set_absolute_time(dates[0], dates[1])
         else:
             self.set_relative_time(dates[0], dates[1], dates[2])
 
@@ -679,7 +671,6 @@
          | End time:................... None
         >>> vmap.metadata.print_info()
          +-------------------- Metadata information ----------------------------------+
-         | STVDS register table ....... None
          | Is map 3d .................. True
          | Number of points ........... 100
          | Number of lines ............ 0
@@ -701,12 +692,11 @@
         True
         >>> vmap.get_type()
         'vector'
-        >>> vmap.get_stds_register()
         >>> vmap.set_absolute_time(start_time=datetime(2001,1,1),
         ...                        end_time=datetime(2012,1,1))
         True
         >>> vmap.get_absolute_time()
-        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> vmap.get_temporal_extent_as_tuple()
         (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
         >>> vmap.get_name()
@@ -729,6 +719,13 @@
         AbstractMapDataset.__init__(self)
         self.reset(ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return False
+        
     def get_type(self):
         return "vector"
 
@@ -741,16 +738,6 @@
         are stored with the type of this class"""
         return SpaceTimeVectorDataset(ident)
 
-    def get_stds_register(self):
-        """!Return the space time dataset register table name in
-        which stds are listed in which this map is registered"""
-        return self.metadata.get_stvds_register()
-
-    def set_stds_register(self, name):
-        """!Set the space time dataset register table name in
-        which stds are listed in which this map is registered"""
-        self.metadata.set_stvds_register(name)
-
     def get_layer(self):
         """!Return the layer"""
         return self.base.get_layer()
@@ -798,6 +785,7 @@
         self.relative_time = VectorRelativeTime(ident=ident)
         self.spatial_extent = VectorSpatialExtent(ident=ident)
         self.metadata = VectorMetadata(ident=ident)
+        self.stds_register = VectorSTDSRegister(ident=ident)
 
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
@@ -826,7 +814,7 @@
             return False
 
         if len(dates) == 2:
-            self.set_absolute_time(dates[0], dates[1], None)
+            self.set_absolute_time(dates[0], dates[1])
         else:
             self.set_relative_time(dates[0], dates[1], dates[2])
 
@@ -920,6 +908,13 @@
     def __init__(self, ident):
         AbstractSpaceTimeDataset.__init__(self, ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return True
+        
     def get_type(self):
         return "strds"
 
@@ -993,6 +988,13 @@
     def __init__(self, ident):
         AbstractSpaceTimeDataset.__init__(self, ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return True
+        
     def get_type(self):
         return "str3ds"
 
@@ -1085,6 +1087,13 @@
     def __init__(self, ident):
         AbstractSpaceTimeDataset.__init__(self, ident)
 
+    def is_stds(self):
+        """!Return True if this class is a space time dataset
+
+           @return True if this class is a space time dataset, False otherwise
+        """
+        return True
+        
     def get_type(self):
         return "stvds"
 

Modified: grass/trunk/lib/python/temporal/temporal_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_extent.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/temporal_extent.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -198,8 +198,7 @@
             return RelativeTemporalExtent(start_time=start, end_time=end,
                                           unit=self.get_unit())
         elif issubclass(type(self), AbsoluteTemporalExtent):
-            return AbsoluteTemporalExtent(start_time=start, end_time=end,
-                                          timezone=self.get_timezone())
+            return AbsoluteTemporalExtent(start_time=start, end_time=end)
         elif issubclass(type(self), AbstractTemporalExtent):
             return AbstractTemporalExtent(start_time=start, end_time=end)
 
@@ -384,8 +383,7 @@
             return RelativeTemporalExtent(start_time=start, end_time=end,
                                           unit=self.get_unit())
         elif issubclass(type(self), AbsoluteTemporalExtent):
-            return AbsoluteTemporalExtent(start_time=start, end_time=end,
-                                          timezone=self.get_timezone())
+            return AbsoluteTemporalExtent(start_time=start, end_time=end)
         elif issubclass(type(self), AbstractTemporalExtent):
             return AbstractTemporalExtent(start_time=start, end_time=end)
 
@@ -1053,64 +1051,37 @@
 
         start_time and end_time must be of type datetime
     """
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None,
-                 timezone=None):
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
 
         AbstractTemporalExtent.__init__(
             self, table, ident, start_time, end_time)
 
-        self.set_timezone(timezone)
-
-    def set_timezone(self, timezone):
-        """!Set the timezone of the map, the timezone is of type string.
-           Timezones are not supported yet, instead the timezone
-           is set in the datetime string as offset in minutes.
-        """
-        self.D["timezone"] = timezone
-
-    def get_timezone(self):
-        """!Get the timezone of the map
-           Timezones are not supported yet, instead the timezone
-           is set in the datetime string as offset in minutes.
-           @return None if not found"""
-        if "timezone" in self.D:
-            return self.D["timezone"]
-        else:
-            return None
-
-    timezone = property(fget=get_timezone, fset=set_timezone)
-
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " +-------------------- Absolute time -----------------------------------------+"
         AbstractTemporalExtent.print_info(self)
-        #print " | Timezone:................... " + str(self.get_timezone())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         AbstractTemporalExtent.print_shell_info(self)
-        #print "timezone=" + str(self.get_timezone())
 
 ###############################################################################
 
 class RasterAbsoluteTime(AbsoluteTemporalExtent):
-    def __init__(self, ident=None, start_time=None, end_time=None,
-                 timezone=None):
+    def __init__(self, ident=None, start_time=None, end_time=None):
         AbsoluteTemporalExtent.__init__(self, "raster_absolute_time",
-            ident, start_time, end_time, timezone)
+            ident, start_time, end_time)
 
 class Raster3DAbsoluteTime(AbsoluteTemporalExtent):
-    def __init__(self, ident=None, start_time=None, end_time=None,
-                 timezone=None):
+    def __init__(self, ident=None, start_time=None, end_time=None):
         AbsoluteTemporalExtent.__init__(self, "raster3d_absolute_time",
-            ident, start_time, end_time, timezone)
+            ident, start_time, end_time)
 
 class VectorAbsoluteTime(AbsoluteTemporalExtent):
-    def __init__(self, ident=None, start_time=None, end_time=None,
-                 timezone=None):
+    def __init__(self, ident=None, start_time=None, end_time=None):
         AbsoluteTemporalExtent.__init__(self, "vector_absolute_time",
-            ident, start_time, end_time, timezone)
+            ident, start_time, end_time)
 
 ###############################################################################
 
@@ -1154,9 +1125,9 @@
         @endcode
     """
     def __init__(self, table=None, ident=None, start_time=None, end_time=None,
-                 granularity=None, timezone=None, map_time=None):
+                 granularity=None, map_time=None):
         AbsoluteTemporalExtent.__init__(
-            self, table, ident, start_time, end_time, timezone)
+            self, table, ident, start_time, end_time)
 
         self.set_granularity(granularity)
         self.set_map_time(map_time)
@@ -1221,23 +1192,23 @@
 
 class STRDSAbsoluteTime(STDSAbsoluteTime):
     def __init__(self, ident=None, start_time=None, end_time=None,
-                 granularity=None, timezone=None):
+                 granularity=None):
         STDSAbsoluteTime.__init__(self, "strds_absolute_time",
-            ident, start_time, end_time, granularity, timezone)
+            ident, start_time, end_time, granularity)
 
 
 class STR3DSAbsoluteTime(STDSAbsoluteTime):
     def __init__(self, ident=None, start_time=None, end_time=None,
-                 granularity=None, timezone=None):
+                 granularity=None):
         STDSAbsoluteTime.__init__(self, "str3ds_absolute_time",
-            ident, start_time, end_time, granularity, timezone)
+            ident, start_time, end_time, granularity)
 
 
 class STVDSAbsoluteTime(STDSAbsoluteTime):
     def __init__(self, ident=None, start_time=None, end_time=None,
-                 granularity=None, timezone=None):
+                 granularity=None):
         STDSAbsoluteTime.__init__(self, "stvds_absolute_time",
-            ident, start_time, end_time, granularity, timezone)
+            ident, start_time, end_time, granularity)
 
 ###############################################################################
 
@@ -1278,7 +1249,7 @@
 
         AbstractTemporalExtent.__init__(
             self, table, ident, start_time, end_time)
-        self.D["unit"] = unit
+        self.set_unit(unit)
 
     def set_unit(self, unit):
         """!Set the unit of the relative time. Valid units are:

Modified: grass/trunk/lib/python/temporal/unittests_register.py
===================================================================
--- grass/trunk/lib/python/temporal/unittests_register.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/python/temporal/unittests_register.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -20,7 +20,7 @@
     def setUpClass(cls):
         """!Initiate the temporal GIS and set the region
         """
-        tgis.init(True)
+        tgis.init()
         grass.overwrite = True
         grass.use_temp_region()
         ret = grass.run_command("g.region", n=80.0, s=0.0, e=120.0, 
@@ -51,19 +51,19 @@
 
         map = tgis.RasterDataset("register_map_1@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 2))
 
         map = tgis.RasterDataset("register_map_2@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 2))
         self.assertEqual(end, datetime.datetime(2001, 1, 3))
 
         strds = tgis.SpaceTimeRasterDataset("register_test@" + tgis.get_current_mapset())
         strds.select()
-        start, end, tz = strds.get_absolute_time()
+        start, end = strds.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 3))
 
@@ -79,13 +79,13 @@
 
         map = tgis.RasterDataset("register_map_1@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 2))
 
         map = tgis.RasterDataset("register_map_2@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 2))
         self.assertEqual(end, datetime.datetime(2001, 1, 3))
 
@@ -98,12 +98,12 @@
 
         map = tgis.RasterDataset("register_map_1@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1, 10, 30, 1))
 
         map = tgis.RasterDataset("register_map_2@" + tgis.get_current_mapset())
         map.select()
-        start, end, tz = map.get_absolute_time()
+        start, end = map.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1, 18, 30, 1))
 
     def test_relative_time_strds(self):
@@ -140,6 +140,8 @@
         self.assertEqual(start, 0)
         self.assertEqual(end, 2)
         self.assertEqual(unit, "day")
+        
+        strds.print_info()
 
         ret = grass.run_command("t.remove", input="register_test") 
         self.assertEqual(ret, 0)

Deleted: grass/trunk/lib/temporal/SQL/map_stds_register_table_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/map_stds_register_table_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/map_stds_register_table_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,23 +0,0 @@
---#############################################################################
--- This SQL script generates the table listing all STDS in
--- which the GRASS_MAP map is registered
---
--- This table is map specific and created for each GRASS_MAP map which is registered 
--- in a STDS. TABLE_NAME is a placeholder for the table name which must be unique.
--- A uuid is used as unique identifier across mapsets.
---
--- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
---#############################################################################
-
---PRAGMA foreign_keys = ON;
-
--- TABLE_NAME is a placeholder for specific table name (SQL compliant)
--- MAP_ID is a placeholder for specific map id: name at mapset
--- GRASS_MAP is a placeholder for specific map type: raster, raster3d or vector
--- STDS is a placeholder for specific space-time dataset type: strds, str3ds, stvds
-
--- This table stores the names of the space-time datasets in which this map is registered 
-CREATE TABLE  TABLE_NAME_STDS_register (
-  id VARCHAR NOT NULL, -- This column is a primary foreign key storing the STDS names
-  FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE ON UPDATE CASCADE
-);

Modified: grass/trunk/lib/temporal/SQL/map_tables_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/map_tables_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/map_tables_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -12,7 +12,6 @@
 
 -- GRASS_MAP is a placeholder for specific map type: raster, raster3d or vector
 
---PRAGMA foreign_keys = ON;
 
 CREATE TABLE  GRASS_MAP_base (
   id VARCHAR NOT NULL,                  -- The id (PK) is the unique identifier for all tables, it is based on name (layer) and mapset (name(:layer)@mapset) and is used as primary key
@@ -22,39 +21,29 @@
   creator VARCHAR NOT NULL,
   temporal_type VARCHAR,                -- The temporal type of the grass map "absolute" or "relative" or NULL in case no time stamp is available
   creation_time TIMESTAMP NOT NULL,      -- The time of creation of the grass map
--- Uncommented due to performance issues
---  modification_time TIMESTAMP NOT NULL,  -- The time of the last modification of the grass map
---  revision SMALLINT NOT NULL,           -- The revision number
   PRIMARY KEY (id)
 );
 
-CREATE INDEX GRASS_MAP_base_index ON GRASS_MAP_base (id);
-
 -- Relative valid time interval with start and end time
 CREATE TABLE  GRASS_MAP_relative_time (
-  id VARCHAR NOT NULL,          -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreign key
+  id VARCHAR NOT NULL,          -- The id (PK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreign key
   start_time INTEGER,  -- The relative valid start time in 
   end_time INTEGER,    -- The relative valid end time in 
   unit VARCHAR,                 -- The relative time unit, available are "years, months, days, minutes, seconds"
-  FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX GRASS_MAP_relative_time_index ON GRASS_MAP_relative_time (id, start_time, end_time);
-
 CREATE TABLE  GRASS_MAP_absolute_time (
-  id VARCHAR NOT NULL,   -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreign key
+  id VARCHAR NOT NULL,   -- The id (PK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary key
   start_time TIMESTAMP,  --  Start of the valid time, can be NULL if no time information is available
   end_time TIMESTAMP,    --  End of the valid time, can be NULL if no time information is available or valid time is a single point in time
-  timezone VARCHAR,      -- The timezone of the valid time stored as string. This is currently not in use. Instead the timezone is set in the datetime strings 
-  FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX GRASS_MAP_absolute_time_index ON GRASS_MAP_absolute_time (id, start_time, end_time);
-
 -- The spatial extent of a raster map
 
 CREATE TABLE  GRASS_MAP_spatial_extent (
-  id VARCHAR NOT NULL,                  -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreigen key
+  id VARCHAR NOT NULL,                  -- The id (PK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary key
   -- below is the spatial extent of the map
   north DOUBLE PRECISION NOT NULL,
   south DOUBLE PRECISION NOT NULL,
@@ -63,7 +52,13 @@
   top DOUBLE PRECISION NOT NULL,
   bottom DOUBLE PRECISION NOT NULL,
   proj VARCHAR,
-  FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX GRASS_MAP_spatial_extent_index ON GRASS_MAP_spatial_extent (id);
+-- We have a specific table that stores the space time dataset ids in which the maps a registered
+
+CREATE TABLE  GRASS_MAP_stds_register (
+  id VARCHAR NOT NULL,                  -- The id (PK) is the unique identifier for all tables, it is based on name (layer) and mapset (name(:layer)@mapset) and is used as primary key
+  registered_stds VARCHAR,              -- This column stores the names of all space time datasets in which a specific map is registered
+  PRIMARY KEY (id)
+);

Added: grass/trunk/lib/temporal/SQL/postgresql_delete_trigger.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/postgresql_delete_trigger.sql	                        (rev 0)
+++ grass/trunk/lib/temporal/SQL/postgresql_delete_trigger.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -0,0 +1,77 @@
+--#############################################################################
+-- Create trigger for automated deletion of dependent rows
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+CREATE OR REPLACE FUNCTION delete_strds_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM strds_absolute_time WHERE id = OLD.id;
+DELETE FROM strds_relative_time WHERE id = OLD.id;
+DELETE FROM strds_spatial_extent WHERE id = OLD.id;
+DELETE FROM strds_metadata WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION delete_raster_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM raster_absolute_time WHERE id = OLD.id;
+DELETE FROM raster_relative_time WHERE id = OLD.id;
+DELETE FROM raster_spatial_extent WHERE id = OLD.id;
+DELETE FROM raster_metadata WHERE id = OLD.id;
+DELETE FROM raster_stds_register WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION delete_str3ds_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM str3ds_absolute_time WHERE id = OLD.id;
+DELETE FROM str3ds_relative_time WHERE id = OLD.id;
+DELETE FROM str3ds_spatial_extent WHERE id = OLD.id;
+DELETE FROM str3ds_metadata WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION delete_raster3d_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM raster3d_absolute_time WHERE id = OLD.id;
+DELETE FROM raster3d_relative_time WHERE id = OLD.id;
+DELETE FROM raster3d_spatial_extent WHERE id = OLD.id;
+DELETE FROM raster3d_metadata WHERE id = OLD.id;
+DELETE FROM raster3d_stds_register WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION delete_stvds_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM stvds_absolute_time WHERE id = OLD.id;
+DELETE FROM stvds_relative_time WHERE id = OLD.id;
+DELETE FROM stvds_spatial_extent WHERE id = OLD.id;
+DELETE FROM stvds_metadata WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION delete_vector_base() RETURNS TRIGGER AS $$
+BEGIN
+DELETE FROM vector_absolute_time WHERE id = OLD.id;
+DELETE FROM vector_relative_time WHERE id = OLD.id;
+DELETE FROM vector_spatial_extent WHERE id = OLD.id;
+DELETE FROM vector_metadata WHERE id = OLD.id;
+DELETE FROM vector_stds_register WHERE id = OLD.id;
+RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE TRIGGER delete_strds_base AFTER DELETE ON strds_base FOR EACH ROW EXECUTE PROCEDURE delete_strds_base();
+CREATE TRIGGER delete_raster_base AFTER DELETE ON raster_base FOR EACH ROW EXECUTE PROCEDURE delete_raster_base();
+CREATE TRIGGER delete_str3ds_base AFTER DELETE ON str3ds_base FOR EACH ROW EXECUTE PROCEDURE delete_str3ds_base();
+CREATE TRIGGER delete_raster3d_base AFTER DELETE ON raster3d_base FOR EACH ROW EXECUTE PROCEDURE delete_raster3d_base();
+CREATE TRIGGER delete_stvds_base AFTER DELETE ON stvds_base FOR EACH ROW EXECUTE PROCEDURE delete_stvds_base();
+CREATE TRIGGER delete_vector_base AFTER DELETE ON vector_base FOR EACH ROW EXECUTE PROCEDURE delete_vector_base();
+

Added: grass/trunk/lib/temporal/SQL/postgresql_indexes.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/postgresql_indexes.sql	                        (rev 0)
+++ grass/trunk/lib/temporal/SQL/postgresql_indexes.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -0,0 +1,14 @@
+--#############################################################################
+-- This SQL script generates the postgresql indexes
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+CREATE INDEX raster_relative_time_index ON raster_relative_time (start_time, end_time);
+CREATE INDEX raster_absolute_time_index ON raster_absolute_time (start_time, end_time);
+
+CREATE INDEX raster3d_relative_time_index ON raster3d_relative_time (start_time, end_time);
+CREATE INDEX raster3d_absolute_time_index ON raster3d_absolute_time (start_time, end_time);
+
+CREATE INDEX vector_relative_time_index ON vector_relative_time (start_time, end_time);
+CREATE INDEX vector_absolute_time_index ON vector_absolute_time (start_time, end_time);

Modified: grass/trunk/lib/temporal/SQL/raster3d_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/raster3d_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/raster3d_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -5,13 +5,11 @@
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
 
---PRAGMA foreign_keys = ON;
 
 -- The metadata table reflects most of the raster3d metadata available in grass
 
 CREATE TABLE  raster3d_metadata (
-  id VARCHAR NOT NULL,                  -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreign key
-  str3ds_register VARCHAR, -- The name of the table storing all space-time raster3d datasets in which this map is registered
+  id VARCHAR NOT NULL,                  -- The id (PK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary key
   datatype VARCHAR NOT NULL,
   cols INTEGER NOT NULL,
   rows INTEGER NOT NULL,
@@ -22,8 +20,9 @@
   tbres DOUBLE PRECISION NOT NULL,
   min DOUBLE PRECISION,
   max DOUBLE PRECISION,
-  FOREIGN KEY (id) REFERENCES  raster3d_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX raster3d_metadata_index ON raster3d_metadata (id);
 
+
+

Modified: grass/trunk/lib/temporal/SQL/raster3d_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/raster3d_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/raster3d_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -10,35 +10,35 @@
 CREATE VIEW raster3d_view_abs_time AS SELECT 
             A1.id, A1.mapset,
             A1.name, A1.temporal_type,
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time,  
             A1.creator,
-            A2.start_time, A2.end_time, A2.timezone,
+            A2.start_time, A2.end_time,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.datatype, A4.cols, A4.rows, A4.depths,
             A4.nsres, A4.ewres, A4.tbres,
             A4.min, A4.max,
-            A4.str3ds_register,
-            A4.number_of_cells
+            A4.number_of_cells, A5.registered_stds
             FROM raster3d_base A1, raster3d_absolute_time A2, 
-            raster3d_spatial_extent A3, raster3d_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+            raster3d_spatial_extent A3, raster3d_metadata A4,
+            raster3d_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
 
 CREATE VIEW raster3d_view_rel_time AS SELECT 
             A1.id, A1.mapset,
             A1.name, A1.temporal_type,
             A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
             A1.creator,
-            A2.start_time, A2.end_time,
+            A2.start_time, A2.end_time, A2.unit,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.datatype, A4.cols, A4.rows, A4.depths,
             A4.nsres, A4.ewres, A4.tbres,
             A4.min, A4.max,
-            A4.str3ds_register,
-            A4.number_of_cells
+            A4.number_of_cells, A5.registered_stds
             FROM raster3d_base A1, raster3d_relative_time A2, 
-            raster3d_spatial_extent A3, raster3d_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
\ No newline at end of file
+            raster3d_spatial_extent A3, raster3d_metadata A4, 
+            raster3d_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
+
+

Modified: grass/trunk/lib/temporal/SQL/raster_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/raster_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/raster_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -10,8 +10,7 @@
 -- The metadata table reflects most of the raster metadata available in grass
 
 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 at mapset) and is used as primary foreign key
-  strds_register VARCHAR,            -- The name of the table storing all space-time raster datasets in which this map is registered
+  id VARCHAR NOT NULL,               -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary key
   datatype VARCHAR NOT NULL,
   cols INTEGER NOT NULL,
   rows INTEGER NOT NULL,
@@ -20,7 +19,7 @@
   ewres DOUBLE PRECISION NOT NULL,
   min DOUBLE PRECISION,
   max DOUBLE PRECISION,
-  FOREIGN KEY (id) REFERENCES  raster_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX raster_metadata_index ON raster_metadata (id);
+

Modified: grass/trunk/lib/temporal/SQL/raster_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/raster_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/raster_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -11,32 +11,32 @@
             A1.id, A1.mapset,
             A1.name, A1.temporal_type,
             A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
             A1.creator, 
-            A2.start_time, A2.end_time, A2.timezone,
+            A2.start_time, A2.end_time,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.datatype, A4.cols, A4.rows,
             A4.nsres, A4.ewres, A4.min, A4.max,
-            A4.strds_register,
-            A4.number_of_cells
+            A4.number_of_cells, A5.registered_stds
             FROM raster_base A1, raster_absolute_time A2, 
-            raster_spatial_extent A3, raster_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+            raster_spatial_extent A3, raster_metadata A4,
+            raster_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
 
 CREATE VIEW raster_view_rel_time AS SELECT 
             A1.id, A1.mapset,
             A1.name, A1.temporal_type,
             A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
             A1.creator, 
-            A2.start_time, A2.end_time,
+            A2.start_time, A2.end_time, A2.unit,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.datatype, A4.cols, A4.rows,
             A4.nsres, A4.ewres, A4.min, A4.max,
-            A4.strds_register,
-            A4.number_of_cells
+            A4.number_of_cells, A5.registered_stds
             FROM raster_base A1, raster_relative_time A2, 
-            raster_spatial_extent A3, raster_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+            raster_spatial_extent A3, raster_metadata A4,
+            raster_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
+
+

Modified: grass/trunk/lib/temporal/SQL/sqlite3_delete_trigger.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/sqlite3_delete_trigger.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/sqlite3_delete_trigger.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,5 +1,10 @@
+--#############################################################################
+-- This SQL script generates the sqlite3 trigger
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
 
--- Create trigger for automated deletion of dependent rows, this should normally be done using foreign keys 
+-- Create trigger for automated deletion of dependent rows
 
 CREATE TRIGGER delete_strds_base AFTER DELETE ON strds_base
   BEGIN
@@ -15,6 +20,7 @@
     DELETE FROM raster_relative_time WHERE id = old.id;
     DELETE FROM raster_spatial_extent WHERE id = old.id;
     DELETE FROM raster_metadata WHERE id = old.id;
+    DELETE FROM raster_stds_register WHERE id = old.id;
   END;
 
 CREATE TRIGGER delete_str3ds_base AFTER DELETE ON str3ds_base
@@ -31,6 +37,7 @@
     DELETE FROM raster3d_relative_time WHERE id = old.id;
     DELETE FROM raster3d_spatial_extent WHERE id = old.id;
     DELETE FROM raster3d_metadata WHERE id = old.id;
+    DELETE FROM raster3d_stds_register WHERE id = old.id;
   END;
 
 CREATE TRIGGER delete_stvds_base AFTER DELETE ON stvds_base
@@ -47,5 +54,7 @@
     DELETE FROM vector_relative_time WHERE id = old.id;
     DELETE FROM vector_spatial_extent WHERE id = old.id;
     DELETE FROM vector_metadata WHERE id = old.id;
+    DELETE FROM vector_stds_register WHERE id = old.id;
   END;
 
+

Added: grass/trunk/lib/temporal/SQL/sqlite3_indexes.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/sqlite3_indexes.sql	                        (rev 0)
+++ grass/trunk/lib/temporal/SQL/sqlite3_indexes.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -0,0 +1,51 @@
+--#############################################################################
+-- This SQL script generates the sqlite3 indexes
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- Indexes for space time datasets
+
+CREATE INDEX strds_base_index ON strds_base (id);
+CREATE INDEX strds_relative_time_index ON strds_relative_time (id);
+CREATE INDEX strds_absolute_time_index ON strds_absolute_time (id);
+CREATE INDEX strds_spatial_extent_index ON strds_spatial_extent (id);
+
+CREATE INDEX str3ds_base_index ON str3ds_base (id);
+CREATE INDEX str3ds_relative_time_index ON str3ds_relative_time (id);
+CREATE INDEX str3ds_absolute_time_index ON str3ds_absolute_time (id);
+CREATE INDEX str3ds_spatial_extent_index ON str3ds_spatial_extent (id);
+
+CREATE INDEX stvds_base_index ON stvds_base (id);
+CREATE INDEX stvds_relative_time_index ON stvds_relative_time (id);
+CREATE INDEX stvds_absolute_time_index ON stvds_absolute_time (id);
+CREATE INDEX stvds_spatial_extent_index ON stvds_spatial_extent (id);
+
+CREATE INDEX str3ds_metadata_index ON str3ds_metadata (id);
+CREATE INDEX strds_metadata_index ON strds_metadata (id);
+CREATE INDEX stvds_metadata_index ON stvds_metadata (id);
+
+-- Indexes for raster, vector and 3D raster maps
+
+CREATE INDEX raster_base_index ON raster_base (id);
+CREATE INDEX raster_relative_time_index ON raster_relative_time (id, start_time, end_time);
+CREATE INDEX raster_absolute_time_index ON raster_absolute_time (id, start_time, end_time);
+CREATE INDEX raster_spatial_extent_index ON raster_spatial_extent (id);
+CREATE INDEX raster_stds_register_index ON raster_stds_register (id);
+
+
+CREATE INDEX raster3d_base_index ON raster3d_base (id);
+CREATE INDEX raster3d_relative_time_index ON raster3d_relative_time (id, start_time, end_time);
+CREATE INDEX raster3d_absolute_time_index ON raster3d_absolute_time (id, start_time, end_time);
+CREATE INDEX raster3d_spatial_extent_index ON raster3d_spatial_extent (id);
+CREATE INDEX raster3d_stds_register_index ON raster3d_stds_register (id);
+
+CREATE INDEX vector_base_index ON vector_base (id);
+CREATE INDEX vector_relative_time_index ON vector_relative_time (id, start_time, end_time);
+CREATE INDEX vector_absolute_time_index ON vector_absolute_time (id, start_time, end_time);
+CREATE INDEX vector_spatial_extent_index ON vector_spatial_extent (id);
+CREATE INDEX vector_stds_register_index ON vector_stds_register (id);
+
+CREATE INDEX raster3d_metadata_index ON raster3d_metadata (id);
+CREATE INDEX raster_metadata_index ON raster_metadata (id);
+CREATE INDEX vector_metadata_index ON vector_metadata (id);
\ No newline at end of file

Modified: grass/trunk/lib/temporal/SQL/stds_map_register_table_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stds_map_register_table_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stds_map_register_table_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -8,16 +8,10 @@
 --#############################################################################
 
 -- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
--- SPACETIME_ID is a placeholder for specific stds id: name at mapset
 -- GRASS_MAP is a placeholder for specific map type: raster, raster3d or vector
--- STDS is a placeholder for specific space-time dataset type: strds, str3ds, stvds
 
---PRAGMA foreign_keys = ON;
-
 -- This table stores the.ids of the GRASS_MAP maps registered in the current spacetime GRASS_MAP table
 CREATE TABLE  SPACETIME_NAME_GRASS_MAP_register (
-  id VARCHAR NOT NULL, -- This colum is a primary foreign key storing the registered GRASS_MAP map.ids
-  FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  id VARCHAR NOT NULL, -- This colum is a primary key storing the registered GRASS_MAP map.ids
+  PRIMARY KEY (id)
 );
-
-CREATE INDEX SPACETIME_NAME_GRASS_MAP_register_index ON SPACETIME_NAME_GRASS_MAP_register (id);

Deleted: grass/trunk/lib/temporal/SQL/stds_raster3d_register_trigger_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stds_raster3d_register_trigger_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stds_raster3d_register_trigger_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,113 +0,0 @@
---#############################################################################
--- This SQL script creates a trigger to update a space-time raster3d dataset
--- metadata
---
--- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
---#############################################################################
-
--- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
--- SPACETIME_ID is a placeholder for specific stds id: name at mapset
-
---PRAGMA foreign_keys = ON;
-
--- Triggers are disabled due to huge performance issues
---CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster3d_register 
---  BEGIN
---    -- Update the min and max values
---    UPDATE str3ds_metadata SET min_min = 
---           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET min_max = 
---           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET max_min = 
---           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET max_max = 
---           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    -- Update the resolution
---    UPDATE str3ds_metadata SET nsres_min = 
---           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET nsres_max = 
---           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET ewres_min = 
---           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET ewres_max = 
---           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET tbres_min = 
---           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET tbres_max = 
---           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---  END;
---
---CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster3d_register 
---  BEGIN
---    -- Update the min and max values
---    UPDATE str3ds_metadata SET min_min = 
---           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET min_max = 
---           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET max_min = 
---           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET max_max = 
---           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    -- Update the resolution
---    UPDATE str3ds_metadata SET nsres_min = 
---           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET nsres_max = 
---           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET ewres_min = 
---           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET ewres_max = 
---           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET tbres_min = 
---           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE str3ds_metadata SET tbres_max = 
---           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster3d_register)
---           ) WHERE id = 'SPACETIME_ID';
---  END;
---
---
---
---
---
---
---
---
---

Deleted: grass/trunk/lib/temporal/SQL/stds_raster_register_trigger_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stds_raster_register_trigger_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stds_raster_register_trigger_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,113 +0,0 @@
---#############################################################################
--- This SQL script creates a trigger to update a space-time raster dataset
--- metadata
---
--- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
---#############################################################################
-
--- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
--- SPACETIME_ID is a placeholder for specific stds id: name at mapset
-
---PRAGMA foreign_keys = ON;
-
--- Triggers are disabled due to huge performance issues
---CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster_register 
---  BEGIN
---    -- Update the min and max values
---    UPDATE strds_metadata SET min_min = 
---           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET min_max = 
---           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET max_min = 
---           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET max_max = 
---           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    -- Update the resolution
---    UPDATE strds_metadata SET nsres_min = 
---           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET nsres_max = 
---           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET ewres_min = 
---           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET ewres_max = 
---           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---  END;
---
---CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster_register 
---  BEGIN
---    -- Update the min and max values
---    UPDATE strds_metadata SET min_min = 
---           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET min_max = 
---           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET max_min = 
---           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET max_max = 
---           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    -- Update the resolution
---    UPDATE strds_metadata SET nsres_min = 
---           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET nsres_max = 
---           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET ewres_min = 
---           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---    UPDATE strds_metadata SET ewres_max = 
---           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
---			(SELECT id FROM SPACETIME_NAME_raster_register)
---           ) WHERE id = 'SPACETIME_ID';
---  END;
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---
---

Modified: grass/trunk/lib/temporal/SQL/stds_tables_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stds_tables_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stds_tables_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -7,8 +7,6 @@
 
 -- STDS is a placeholder for specific space-time dataset type: strds, str3ds, stvds
 
---PRAGMA foreign_keys = ON;
-
 CREATE TABLE  STDS_base (
   id VARCHAR NOT NULL,                 -- Id of the space-time dataset, name at mapset this is the primary key
   name VARCHAR NOT NULL,               -- name of the space-time dataset
@@ -17,34 +15,31 @@
   temporal_type VARCHAR NOT NULL,      -- The temporal type of the dataset "absolute" or "relative" 
   semantic_type VARCHAR NOT NULL,      -- The semantic data description used for aggregation/decomposition algorithm selection: min, max, mean or sum
   creation_time TIMESTAMP NOT NULL,    -- The time of creation of the space-time dataset
--- Uncommented due to performance issues
---  modification_time TIMESTAMP NOT NULL,  -- The time of the last modification of the grass map
---  revision SMALLINT NOT NULL,            -- The revision number        -- The revision number
+  modification_time TIMESTAMP NOT NULL,-- The time of the last modification of the space time dataset
   PRIMARY KEY (id)
 );
 
 CREATE TABLE  STDS_relative_time (
-  id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary foreign key
+  id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary key
   start_time INTEGER,             -- The relative valid start time 
   end_time INTEGER,               -- The relative valid end time 
   granularity INTEGER,            -- The granularity 
   unit VARCHAR,                   -- The relative time unit, available are "years, months, days, minutes, seconds"
   map_time VARCHAR,               -- The temporal type of the registered maps, may be interval, point or mixed
-  FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
 CREATE TABLE  STDS_absolute_time (
-  id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary foreign key
+  id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary key
   start_time TIMESTAMP,           -- Start of the valid time, can be NULL if no map is registered
   end_time TIMESTAMP,             -- End of the valid time, can be NULL if no map is registered
   granularity VARCHAR,            -- The granularity "NNN seconds, NNN minutes, NNN hours, NNN days, NNN months, NNN years"
-  timezone VARCHAR,      -- The timezone of the valid time stored as string. This is currently not in use. Instead the timezone is set in the datetime strings 
   map_time VARCHAR,               -- The temporal type of the registered maps, may be interval, point or mixed
-  FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
 CREATE TABLE  STDS_spatial_extent (
-  id VARCHAR NOT NULL,      -- Id of the space-time dataset, this is the primary foreign key
+  id VARCHAR NOT NULL,      -- Id of the space-time dataset, this is the primary key
   north DOUBLE PRECISION,   -- The spatial north extent, derived from the registered maps
   south DOUBLE PRECISION,   -- The spatial south extent, derived from the registered maps
   east DOUBLE PRECISION,    -- The spatial east extent, derived from the registered maps
@@ -52,5 +47,8 @@
   top DOUBLE PRECISION,     -- The spatial top extent, derived from the registered maps
   bottom DOUBLE PRECISION,  -- The spatial bottom extent, derived from the registered maps
   proj VARCHAR,      -- The projection of the space time dataset (XY of LL)
-  FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
+
+
+

Deleted: grass/trunk/lib/temporal/SQL/stds_vector_register_trigger_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stds_vector_register_trigger_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stds_vector_register_trigger_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,6 +0,0 @@
---#############################################################################
--- This SQL script is for now a placeholder, till the vector metadata
--- concept is clear
---
--- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
---#############################################################################
\ No newline at end of file

Modified: grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -4,10 +4,8 @@
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
 
---PRAGMA foreign_keys = ON;
-
 CREATE TABLE  str3ds_metadata (
-  id VARCHAR NOT NULL,          -- Id of the space time 3D raster dataset, this is the primary foreign key
+  id VARCHAR NOT NULL,          -- Id of the space time 3D raster dataset, this is the primary key
   raster3d_register VARCHAR,    -- The id of the table in which the 3D raster maps are registered for this dataset
   number_of_maps INTEGER,       -- The number of registered 3D raster maps
   max_min DOUBLE PRECISION,     -- The minimal maximum of the registered 3D raster maps
@@ -20,8 +18,11 @@
   ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered 3D raster maps
   tbres_min DOUBLE PRECISION,   -- The lowest top-bottom resolution of the registered 3D raster maps
   tbres_max DOUBLE PRECISION,   -- The highest top-bottom resolution of the registered 3D 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 3D raster dataset
   description VARCHAR,          -- Detailed description of the space time 3D raster dataset
   command VARCHAR,              -- The command that was used to create the space time 3D raster dataset
-  FOREIGN KEY (id) REFERENCES  str3ds_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
+
+

Modified: grass/trunk/lib/temporal/SQL/str3ds_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/str3ds_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/str3ds_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -9,11 +9,9 @@
 CREATE VIEW str3ds_view_abs_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
             A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time, A1.modification_time,
             A1.creator, 
-            A2.start_time, A2.end_time, A2.timezone, A2.granularity,
+            A2.start_time, A2.end_time, A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.raster3d_register,
             A4.number_of_maps, 
@@ -21,7 +19,7 @@
             A4.nsres_max, A4.ewres_max, 
             A4.tbres_min, A4.tbres_max, 
             A4.min_min, A4.min_max,
-            A4.max_min, A4.max_max,
+            A4.max_min, A4.max_max, A4.aggregation_type,
             A4.title, A4.description, A4.command
             FROM str3ds_base A1, str3ds_absolute_time A2,  
             str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
@@ -30,11 +28,9 @@
 CREATE VIEW str3ds_view_rel_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
             A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time, A1.modification_time,
             A1.creator, 
-            A2.start_time, A2.end_time, A2.granularity,
+            A2.start_time, A2.end_time, A2.unit, A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.raster3d_register,
             A4.number_of_maps, 
@@ -42,8 +38,9 @@
             A4.nsres_max, A4.ewres_max, 
             A4.tbres_min, A4.tbres_max, 
             A4.min_min, A4.min_max,
-            A4.max_min, A4.max_max,
+            A4.max_min, A4.max_max, A4.aggregation_type,
             A4.title, A4.description, A4.command
             FROM str3ds_base A1, str3ds_relative_time A2,  
             str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
             A1.id = A3.id AND A1.id = A4.id;
+

Modified: grass/trunk/lib/temporal/SQL/strds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/strds_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/strds_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -4,10 +4,9 @@
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
 
---PRAGMA foreign_keys = ON;
 
 CREATE TABLE  strds_metadata (
-  id VARCHAR NOT NULL,          -- Id of the space-time dataset, this is the primary foreign key
+  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
@@ -18,8 +17,11 @@
   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
-  FOREIGN KEY (id) REFERENCES  strds_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
+
+

Modified: grass/trunk/lib/temporal/SQL/strds_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/strds_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/strds_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -9,18 +9,16 @@
 CREATE VIEW strds_view_abs_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
             A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time, A1.modification_time,
             A1.creator, 
-            A2.start_time, A2.end_time, A2.timezone, A2.granularity,
+            A2.start_time, A2.end_time, A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.raster_register,
             A4.number_of_maps, 
             A4.nsres_min, A4.ewres_min, 
             A4.nsres_max, A4.ewres_max, 
             A4.min_min, A4.min_max,
-            A4.max_min, A4.max_max,
+            A4.max_min, A4.max_max, A4.aggregation_type,
             A4.title, A4.description, A4.command	
             FROM strds_base A1, strds_absolute_time A2,  
             strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
@@ -29,19 +27,18 @@
 CREATE VIEW strds_view_rel_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
             A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time, A1.modification_time,
             A1.creator, 
-            A2.start_time, A2.end_time, A2.granularity,
+            A2.start_time, A2.end_time, A2.unit, A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.raster_register,
             A4.number_of_maps, 
             A4.nsres_min, A4.ewres_min, 
             A4.nsres_max, A4.ewres_max, 
             A4.min_min, A4.min_max,
-            A4.max_min, A4.max_max,
+            A4.max_min, A4.max_max, A4.aggregation_type,
             A4.title, A4.description, A4.command
             FROM strds_base A1, strds_relative_time A2,  
             strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
             A1.id = A3.id AND A1.id = A4.id;
+

Modified: grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -4,10 +4,8 @@
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
 --#############################################################################
 
---PRAGMA foreign_keys = ON;
-
 CREATE TABLE  stvds_metadata (
-  id VARCHAR NOT NULL,    -- Name of the space-time vector dataset, this is the primary foreign key
+  id VARCHAR NOT NULL,    -- Name of the space-time vector dataset, this is the primary key
   vector_register VARCHAR,-- The id of the table in which the vector maps are registered for this dataset
   number_of_maps INTEGER, -- The number of registered vector maps
   title VARCHAR,          -- Title of the space-time vector dataset
@@ -24,6 +22,7 @@
   areas INTEGER,          -- The number of areas accumulated from all registered maps (topological information)
   islands INTEGER,        -- The number of islands accumulated from all registered maps (topological information)
   holes INTEGER,          -- The number of holes accumulated from all registered maps (topological information)
-  volumes INTEGER,        -- The number of volumes accumulated from all registered maps (topological information)
-  FOREIGN KEY (id) REFERENCES  stvds_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  volumes INTEGER,        -- The number of volumes accumulated from all registered maps (topological information)           -- The command that was used to create the space time raster dataset
+  PRIMARY KEY (id)
 );
+

Modified: grass/trunk/lib/temporal/SQL/stvds_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stvds_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/stvds_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -9,11 +9,9 @@
 CREATE VIEW stvds_view_abs_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
             A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
+            A1.creation_time, A1.modification_time,
             A1.creator, 
-            A2.start_time, A2.end_time, A2.timezone,
+            A2.start_time, A2.end_time,
             A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.vector_register,
@@ -28,15 +26,13 @@
 
 CREATE VIEW stvds_view_rel_time AS SELECT 
             A1.id, A1.name, A1.mapset, A1.temporal_type,
-            A1.semantic_type, 
-            A1.creation_time, 
--- Uncommented due to performance issues
---            A1.modification_time, A1.revision, 
-            A1.creator, 
-            A2.start_time, A2.end_time, A2.granularity,
+            A1.semantic_type,
+            A1.creation_time, A1.modification_time,
+            A1.creator,
+            A2.start_time, A2.end_time, A2.unit, A2.granularity,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
             A4.vector_register,
-            A4.number_of_maps, 
+            A4.number_of_maps,
             A4.title, A4.description, A4.command, A4.points, A4.lines,
             A4.boundaries, A4.centroids, A4.faces, A4.kernels,
             A4.primitives, A4.nodes, A4.areas, A4.islands,
@@ -44,3 +40,5 @@
             FROM stvds_base A1, stvds_relative_time A2,  
             stvds_spatial_extent A3, stvds_metadata A4 WHERE A1.id = A2.id AND 
             A1.id = A3.id AND A1.id = A4.id;
+
+

Deleted: grass/trunk/lib/temporal/SQL/test.temporal.py
===================================================================
--- grass/trunk/lib/temporal/SQL/test.temporal.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/test.temporal.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -1,836 +0,0 @@
-import os
-from grass.script.tgis_core import *
-from grass.script.tgis_base import *
-from grass.script.tgis_temporal_extent import *
-from grass.script.tgis_spatial_extent import *
-from grass.script.tgis_metadata import *
-from grass.script.tgis_abstract_datasets import *
-from grass.script.tgis_space_time_datasets import *
-import grass.script as grass
-###############################################################################
-
-def test_dict_sql_serializer():
-    t = dict_sql_serializer()
-    t.test()
-
-def test_dataset_identifer():
-	for i in range(2):
-	    base = raster_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", creator="soeren", temporal_type="absolute", revision=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = raster3d_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", temporal_type="absolute", creator="soeren")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = vector_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", temporal_type="absolute", creator="soeren")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = strds_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", creator="soeren", semantic_type="event", temporal_type="absolute", revision=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = str3ds_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", temporal_type="absolute", semantic_type="event", creator="soeren")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = stvds_base(ident="soil" + str(i) + "@PERMANENT", name="soil" + str(i), mapset="PERMANENT", temporal_type="absolute", semantic_type="event", creator="soeren")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_creator("rene")
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-def test_absolute_timestamp():
-	for i in range(2):
-	    base = raster_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = raster3d_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = vector_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-	for i in range(2):
-	    base = strds_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), granularity="1 day", timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = str3ds_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), granularity="1 day", timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = stvds_absolute_time(ident="soil" + str(i) + "@PERMANENT", start_time=datetime(2011,01,01), end_time=datetime(2011,07,01), granularity="1 day", timezone=1)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_start_time(datetime(2010,01,01))
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-def test_spatial_extent():
-	for i in range(2):
-	    base = raster_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = raster3d_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = vector_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-	for i in range(2):
-	    base = strds_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = str3ds_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = stvds_spatial_extent(ident="soil" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_north(120+i)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-def test_relative_timestamp():
-	for i in range(2):
-	    base = raster_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = raster3d_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = vector_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-	for i in range(2):
-	    base = strds_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i, granularity=5.5)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = str3ds_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i, granularity=5.5)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = stvds_relative_time(ident="soil" + str(i) + "@PERMANENT", interval=i, granularity=5.5)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_interval(i+1)
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-def test_map_metadata():
-	for i in range(2):
-	    base = raster_metadata(ident="soil" + str(i) + "@PERMANENT", strds_register="PERMANENT_soil_strds_register", datatype="CELL", \
-			    cols=500, rows=400, number_of_cells=200000,nsres=1, ewres=1, min=0, max=33)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_datatype("FCELL")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = raster3d_metadata(ident="soil" + str(i) + "@PERMANENT", str3ds_register="PERMANENT_soil_str3ds_register", datatype="FCELL", \
-			    cols=500, rows=400, depths=20, number_of_cells=200000,nsres=1, ewres=1, tbres=10, min=0, max=33)
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_datatype("DCELL")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = vector_metadata(ident="soil" + str(i) + "@PERMANENT", stvds_register="PERMANENT_soil_stvds_register")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_stvds_register("PERMANENT_soil_stvds_register")
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-	for i in range(2):
-	    base = strds_metadata(ident="soil" + str(i) + "@PERMANENT", raster_register="PERMANENT_soil_raster_register", \
-                                   title="Test", description="Test description")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_title("More tests")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = str3ds_metadata(ident="soil" + str(i) + "@PERMANENT", raster3d_register="PERMANENT_soil_raster3d_register", \
-                                   title="Test", description="Test description")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_title("More tests")
-	    base.update()
-	    base.select()
-	    base.print_self()
-
-	for i in range(2):
-	    base = stvds_metadata(ident="soil" + str(i) + "@PERMANENT", vector_register="PERMANENT_soil_vector_register", \
-                                   title="Test", description="Test description")
-	    base.insert()
-	    base.select()
-	    base.print_self()
-	    base.clear()
-	    base.set_title("More tests")
-	    base.update()
-	    base.select()
-	    base.print_self()
-            
-def test_base_absolute_time_extent_metadata():
-
-	for i in range(10):
-	    base = vector_base(ident="water" + str(i) + "@PERMANENT", name="water" + str(i), mapset="PERMANENT", creator="soeren")
-	    base.insert()
-	    base = raster_base(ident="water" + str(i) + "@PERMANENT", name="water" + str(i), mapset="PERMANENT", creator="soeren")
-	    base.insert()
-	    base = raster3d_base(ident="water" + str(i) + "@PERMANENT", name="water" + str(i), mapset="PERMANENT", creator="soeren")
-	    base.insert()
-
-	for i in range(10):
-	    base = vector_base(ident="water" + str(i) + "@PERMANENT")
-	    base.set_creator("rene")
-	    base.update()
-	    base = raster_base(ident="water" + str(i) + "@PERMANENT")
-	    base.set_creator("rene")
-	    base.update()
-	    base = raster3d_base(ident="water" + str(i) + "@PERMANENT")
-	    base.set_creator("rene")
-	    base.update()
-
-	for i in range(10):
-	    base = vector_absolute_time(ident="water" + str(i) + "@PERMANENT", start_time=datetime.now(), end_time=datetime.now(), timezone=1)
-	    base.insert()
-	    base = raster_absolute_time(ident="water" + str(i) + "@PERMANENT", start_time=datetime.now(), end_time=datetime.now(), timezone=1)
-	    base.insert()
-	    base = raster3d_absolute_time(ident="water" + str(i) + "@PERMANENT", start_time=datetime.now(), end_time=datetime.now(), timezone=1)
-	    base.insert()
-
-	for i in range(10):
-	    base = vector_absolute_time(ident="water" + str(i) + "@PERMANENT")
-	    base.set_start_time(datetime(2010, 6, 1))
-	    base.update()
-	    base = raster_absolute_time(ident="water" + str(i) + "@PERMANENT")
-	    base.set_start_time(datetime(2010, 6, 1))
-	    base.update()
-	    base = raster3d_absolute_time(ident="water" + str(i) + "@PERMANENT")
-	    base.set_start_time(datetime(2010, 6, 1))
-	    base.update()
-
-	for i in range(10):
-	    base = vector_spatial_extent(ident="water" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-	    base = raster_spatial_extent(ident="water" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=0, bottom=0)
-	    base.insert()
-	    base = raster3d_spatial_extent(ident="water" + str(i) + "@PERMANENT", north=100 + i, south=10+i, east=50+i, west=20+i, top=i, bottom=0)
-	    base.insert()
-
-	for i in range(10):
-	    base = vector_spatial_extent(ident="water" + str(i) + "@PERMANENT")
-	    base.set_north(120 + i)
-	    base.set_south(20 + i)
-	    base.update()
-	    base = raster_spatial_extent(ident="water" + str(i) + "@PERMANENT")
-	    base.set_north(120 + i)
-	    base.set_south(20 + i)
-	    base.update()
-	    base = raster3d_spatial_extent(ident="water" + str(i) + "@PERMANENT")
-	    base.set_north(120 + i)
-	    base.set_south(20 + i)
-	    base.update()
-
-	for i in range(10):
-	    base = vector_metadata(ident="water" + str(i) + "@PERMANENT", stvds_register="PERMANENT_water_stvds_register")
-	    base.insert()
-	    base = raster_metadata(ident="water" + str(i) + "@PERMANENT", strds_register="PERMANENT_water_strds-register", datatype="CELL", \
-			    cols=500, rows=400, number_of_cells=200000,nsres=1, ewres=1, min=0, max=33)
-	    base.insert()
-	    base = raster3d_metadata(ident="water" + str(i) + "@PERMANENT", str3ds_register="PERMANENT_water_str3ds-register", datatype="FCELL", \
-			    cols=500, rows=400, depths=20, number_of_cells=200000,nsres=1, ewres=1, tbres=10, min=0, max=33)
-	    base.insert()
-
-	for i in range(10):
-	    base = vector_metadata(ident="water" + str(i) + "@PERMANENT")
-	    base.set_stvds_register("PERMANENT_water_stvds_register")
-	    base.update()
-	    base = raster_metadata(ident="water" + str(i) + "@PERMANENT")
-	    base.set_datatype("DCELL")
-	    base.update()
-	    base = raster3d_metadata(ident="water" + str(i) + "@PERMANENT")
-	    base.set_datatype("DCELL")
-	    base.update()
-
-	for i in range(10):
-	    base = vector_base(ident="water" + str(i) + "@PERMANENT")
-	    base.select()
-	    base.print_self()
-	    base = raster_base(ident="water" + str(i) + "@PERMANENT")
-	    base.select()
-	    base.print_self()
-	    base = raster3d_base(ident="water" + str(i) + "@PERMANENT")
-	    base.select()
-	    base.print_self()
-
-	print "Create a raster object"
-
-	rds = raster_dataset("water0 at PERMANENT")
-	rds.select()
-	rds.print_self()
-
-	print rds.temporal_relation(rds)
-
-def test_absolut_time_temporal_relations():
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2001, month=1, day=1), \
-		                                        end_time=datetime(year=2002, month=1, day=1), timezone=1)
-
-    print "Precedes: ", A.temporal_relation(B)
-    print "Follows:  ", B.temporal_relation(A)
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2001, month=1, day=2), \
-		                                        end_time=datetime(year=2002, month=1, day=1), timezone=1)
-
-    print "Before:   ", A.temporal_relation(B)
-    print "After:    ", B.temporal_relation(A)
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2002, month=1, day=1), timezone=1)
-
-    print "Starts:   ", A.temporal_relation(B)
-    print "Started:  ", B.temporal_relation(A)
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2000, month=1, day=2), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-
-    print "Finished: ", A.temporal_relation(B)
-    print "Finishes: ", B.temporal_relation(A)
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2001, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2000, month=3, day=1), \
-		                                        end_time=datetime(year=2000, month=9, day=1), timezone=1)
-
-    print "Contains: ", A.temporal_relation(B)
-    print "During:   ", B.temporal_relation(A)
-
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2000, month=6, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2000, month=3, day=1), \
-		                                        end_time=datetime(year=2000, month=9, day=1), timezone=1)
-
-    print "Overlap:   ", A.temporal_relation(B)
-    print "Overlapped:", B.temporal_relation(A)
-
-    A = raster_absolute_time(ident="test1 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2000, month=1, day=1), timezone=1)
-    B = raster_absolute_time(ident="test2 at PERMANENT", start_time=datetime(year=2000, month=1, day=1), \
-		                                        end_time=datetime(year=2000, month=1, day=1), timezone=1)
-
-    print "Equivalent:", A.temporal_relation(B)
-    print "Equivalent:", B.temporal_relation(A)
-
-
-def test_raster_dataset():
-    
-    # Create a test map
-    grass.raster.mapcalc("test = sin(x()) + cos(y())", overwrite = True)
-    
-    name = "test"
-    mapset =  grass.gisenv()["MAPSET"]
-    
-    print "Create a raster object"
-
-    # We need to specify the name and the mapset as identifier
-    rds = raster_dataset(name + "@" + mapset)
-    
-    # Load data from the raster map in the mapset
-    rds.load()
-    
-    print "Is in db: ", rds.is_in_db()
-    
-    if rds.is_in_db():      
-        # Remove the entry if it is in the db
-        rds.delete()
-    
-    # Set the absolute valid time
-    rds.set_absolute_time(start_time= datetime(year=2000, month=1, day=1), \
-                            end_time= datetime(year=2010, month=1, day=1))
-    # Insert the map data into the SQL database
-    rds.insert()
-    # Print self info
-    rds.print_self()
-    # The temporal relation must be equal
-    print rds.temporal_relation(rds)
-
-def test_raster3d_dataset():
-    
-    # Create a test map
-    grass.raster3d.mapcalc3d("test = sin(x()) + cos(y()) + sin(z())", overwrite = True)
-    
-    name = "test"
-    mapset =  grass.gisenv()["MAPSET"]
-    
-    print "Create a raster object"
-
-    # We need to specify the name and the mapset as identifier
-    r3ds = raster3d_dataset(name + "@" + mapset)
-    
-    # Load data from the raster map in the mapset
-    r3ds.load()
-    
-    print "Is in db: ", r3ds.is_in_db()
-    
-    if r3ds.is_in_db():      
-        # Remove the entry if it is in the db
-        r3ds.delete()
-    
-    # Set the absolute valid time
-    r3ds.set_absolute_time(start_time= datetime(year=2000, month=1, day=1), \
-                            end_time= datetime(year=2010, month=1, day=1))
-                            
-    # Insert the map data into the SQL database
-    r3ds.insert()
-    # Print self info
-    r3ds.print_self()
-    # The temporal relation must be equal
-    print r3ds.temporal_relation(r3ds)
-
-def test_vector_dataset():
-    
-    # Create a test map
-    grass.run_command("v.random", output="test", n=20, column="height", zmin=0, \
-                      zmax=100, flags="z", overwrite = True)
-    
-    name = "test"
-    mapset =  grass.gisenv()["MAPSET"]
-    
-    print "Create a vector object"
-
-    # We need to specify the name and the mapset as identifier
-    vds = vector_dataset(name + "@" + mapset)
-    
-    # Load data from the raster map in the mapset
-    vds.load()
-    
-    print "Is in db: ", vds.is_in_db()
-    
-    if vds.is_in_db():      
-        # Remove the entry if it is in the db
-        vds.delete()
-    
-    # Set the absolute valid time
-    vds.set_absolute_time(start_time= datetime(year=2000, month=1, day=1), \
-                            end_time= datetime(year=2010, month=1, day=1))
-    # Insert the map data into the SQL database
-    vds.insert()
-    # Print self info
-    vds.print_self()
-    # The temporal relation must be equal
-    print vds.temporal_relation(vds)
-
-
-def test_strds_dataset():
-    
-    name = "strds_test_1"
-    mapset =  grass.gisenv()["MAPSET"]
-
-    print "Create a strds object"
-
-    # We need to specify the name and the mapset as identifier
-    strds = space_time_raster_dataset(ident = name + "@" + mapset)
-    # Check if in db
-    print "Is strds in db: ", strds.is_in_db()
-    # Create a new entry if not in db
-    if strds.is_in_db() == False:
-        strds.set_initial_values(temporal_type = "absolute", granularity="1 day",\
-        semantic_type="event", title="This is a test space time raster dataset", description="A space time raster dataset for testing")
-        strds.insert()
-    
-    # Reread the data from the db
-    strds.select()
-    # Print self info
-    #strds.print_self()
-
-    # Create a test maps
-    for i in range(11):
-        i = i + 1
-        grass.raster.mapcalc("test" + str(i) + " = sin(x()) + cos(y())", overwrite = True)
-    
-        name = "test" + str(i)
-        mapset =  grass.gisenv()["MAPSET"]
-        ident = name + "@" + mapset
-
-        print "Create a raster object"
-
-        # We need to specify the name and the mapset as identifier
-        rds = raster_dataset(ident)
-
-        # Load data from the raster map in the mapset
-        rds.load()
-
-        print "Is raster in db: ", rds.is_in_db()
-
-        if rds.is_in_db():      
-            rds.select()
-            rds.print_self()
-            # Remove the entry if it is in the db
-            rds.delete()
-            rds.reset(ident)
-            rds.load()
-
-        # Set the absolute valid time
-        rds.set_absolute_time(start_time= datetime(year=2000, month=i, day=1), \
-                                end_time= datetime(year=2000, month=i + 1, day=1))
-        # Insert the map data into the SQL database
-        rds.insert()
-        # Register the map in the space time raster dataset
-        strds.register_map(rds)
-        # Print self info
-        #rds.print_self()
-
-    strds.update_from_registered_maps()
-    strds.select()
-    # Print self info
-    strds.print_self()
-    # Delete the dataset
-    strds.delete()
-
-
-def test_str3ds_dataset():
-    
-    name = "str3ds_test_1"
-    mapset =  grass.gisenv()["MAPSET"]
-
-    print "Create a str3ds object"
-
-    # We need to specify the name and the mapset as identifier
-    str3ds = space_time_raster3d_dataset(ident = name + "@" + mapset)
-    # Check if in db
-    print "Is str3ds in db: ", str3ds.is_in_db()
-    # Create a new entry if not in db
-    if str3ds.is_in_db() == False:
-        str3ds.set_initial_values(temporal_type = "absolute", granularity="1 day",\
-        semantic_type="event", title="This is a test space time raster3d dataset", description="A space time raster3d dataset for testing")
-        str3ds.insert()
-    
-    # Reread the data from the db
-    str3ds.select()
-    # Print self info
-    #str3ds.print_self()
-
-    # Create a test maps
-    for i in range(11):
-        i = i + 1
-        grass.raster3d.mapcalc3d("test" + str(i) + " = sin(x()) + cos(y()) + z()", overwrite = True)
-    
-        name = "test" + str(i)
-        mapset =  grass.gisenv()["MAPSET"]
-        ident = name + "@" + mapset
-
-        print "Create a raster3d object"
-
-        # We need to specify the name and the mapset as identifier
-        r3ds = raster3d_dataset(ident)
-
-        # Load data from the raster3d map in the mapset
-        r3ds.load()
-
-        print "Is raster3d in db: ", r3ds.is_in_db()
-
-        if r3ds.is_in_db():      
-            r3ds.select()
-            r3ds.print_self()
-            # Remove the entry if it is in the db
-            r3ds.delete()
-            r3ds.reset(ident)
-            r3ds.load()
-
-        # Set the absolute valid time
-        r3ds.set_absolute_time(start_time= datetime(year=2000, month=i, day=1), \
-                                end_time= datetime(year=2000, month=i + 1, day=1))
-        # Insert the map data into the SQL database
-        r3ds.insert()
-        # Register the map in the space time raster3d dataset
-        str3ds.register_map(r3ds)
-        # Print self info
-        #r3ds.print_self()
-
-    str3ds.update_from_registered_maps()
-    str3ds.select()
-    # Print self info
-    str3ds.print_self()
-    # Delete the dataset
-    str3ds.delete()
-
-
-def test_stvds_dataset():
-
-    name = "stvds_test_1"
-    mapset =  grass.gisenv()["MAPSET"]
-
-    print "Create a stvds object"
-
-    # We need to specify the name and the mapset as identifier
-    stvds = space_time_vector_dataset(ident = name + "@" + mapset)
-    # Check if in db
-    print "Is stvds in db: ", stvds.is_in_db()
-    # Create a new entry if not in db
-    if stvds.is_in_db() == False:
-        stvds.set_initial_values(temporal_type = "absolute", granularity="1 day",\
-        semantic_type="event", title="This is a test space time vector dataset", description="A space time vector dataset for testing")
-        stvds.insert()
-
-    # Reread the data from the db
-    stvds.select()
-    # Print self info
-    #stvds.print_self()
-
-    # Create a test maps
-    for i in range(11):
-        name = "test" + str(i)
-        mapset =  grass.gisenv()["MAPSET"]
-        ident = name + "@" + mapset
-
-        i = i + 1
-        grass.run_command("v.random", output=name, n=100, zmin=0, zmax=100, column="height" ,flags="z" , overwrite = True)
-
-
-        print "Create a vector object"
-
-        # We need to specify the name and the mapset as identifier
-        vds = vector_dataset(ident)
-
-        # Load data from the raster map in the mapset
-        vds.load()
-
-        print "Is vector in db: ", vds.is_in_db()
-
-        if vds.is_in_db():
-            vds.select()
-            vds.print_self()
-            # Remove the entry if it is in the db
-            vds.delete()
-            vds.reset(ident)
-            vds.load()
-
-        # Set the absolute valid time
-        vds.set_absolute_time(start_time= datetime(year=2000, month=i, day=1), \
-                                end_time= datetime(year=2000, month=i + 1, day=1))
-        # Insert the map data into the SQL database
-        vds.insert()
-        # Register the map in the space time raster dataset
-        stvds.register_map(vds)
-        # Print self info
-        #vds.print_self()
-
-    stvds.update_from_registered_maps()
-    stvds.select()
-    # Print self info
-    stvds.print_self()
-    # Delete the dataset
-    stvds.delete()
-
-
-test_dict_sql_serializer()
-create_temporal_database()
-#test_dataset_identifer()
-#test_absolute_timestamp()
-#test_relative_timestamp()
-#test_spatial_extent()
-#test_map_metadata()
-#test_base_absolute_time_extent_metadata()
-#test_absolut_time_temporal_relations()
-
-test_raster_dataset()
-test_raster3d_dataset()
-test_vector_dataset()
-
-test_strds_dataset()
-test_str3ds_dataset()
-test_stvds_dataset()
-test_increment_datetime_by_string()

Modified: grass/trunk/lib/temporal/SQL/update_stds_spatial_temporal_extent_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/update_stds_spatial_temporal_extent_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/update_stds_spatial_temporal_extent_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -64,3 +64,4 @@
        (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
     		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
        ) WHERE id = 'SPACETIME_ID';
+

Modified: grass/trunk/lib/temporal/SQL/update_str3ds_metadata_template.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/update_str3ds_metadata_template.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/update_str3ds_metadata_template.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -49,3 +49,4 @@
        (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
     		(SELECT id FROM SPACETIME_NAME_raster3d_register)
        ) WHERE id = 'SPACETIME_ID';
+

Modified: grass/trunk/lib/temporal/SQL/vector_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/vector_metadata_table.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/vector_metadata_table.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -10,8 +10,7 @@
 -- The metadata table 
 
 CREATE TABLE  vector_metadata (
-  id VARCHAR NOT NULL,    -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary foreign key
-  stvds_register VARCHAR, -- The name of the table storing all space-time vector datasets in which this map is registered
+  id VARCHAR NOT NULL,    -- The id (PK) is the unique identifier for all tables, it is based on name and mapset (name at mapset) and is used as primary key
   is_3d BOOLEAN,          -- This is 1 if the vector map is 3d and 0 otherwise 
   points INTEGER,         -- The number of points
   lines INTEGER,          -- The number of lines
@@ -25,7 +24,8 @@
   islands INTEGER,        -- The number of islands (topological information)
   holes INTEGER,          -- The number of holes (topological information)
   volumes INTEGER,        -- The number of volumes (topological information)
-  FOREIGN KEY (id) REFERENCES  vector_base (id) ON DELETE CASCADE ON UPDATE CASCADE
+  PRIMARY KEY (id)
 );
 
-CREATE INDEX vector_metadata_index ON vector_metadata (id);
+
+

Modified: grass/trunk/lib/temporal/SQL/vector_views.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/vector_views.sql	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/lib/temporal/SQL/vector_views.sql	2013-12-31 02:41:37 UTC (rev 58564)
@@ -11,27 +11,33 @@
             A1.name, A1.layer, A1.temporal_type,
             A1.creation_time, 
             A1.creator, 
-            A2.start_time, A2.end_time, A2.timezone,
+            A2.start_time, A2.end_time,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
-            A4.stvds_register, A4.is_3d, A4.points, A4.lines,
+            A4.is_3d, A4.points, A4.lines,
             A4.boundaries, A4.centroids, A4.faces, A4.kernels,
             A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
+            A4.holes, A4.volumes, A5.registered_stds
             FROM vector_base A1, vector_absolute_time A2, 
-            vector_spatial_extent A3, vector_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+            vector_spatial_extent A3, vector_metadata A4,
+            vector_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
 
 CREATE VIEW vector_view_rel_time AS SELECT 
             A1.id, A1.mapset,
             A1.name, A1.layer, A1.temporal_type,
             A1.creation_time,
             A1.creator, 
-            A2.start_time, A2.end_time,
+            A2.start_time, A2.end_time, A2.unit,
             A3.north, A3.south, A3.east, A3.west, A3.bottom, A3.top, A3.proj,
-            A4.stvds_register, A4.is_3d, A4.points, A4.lines,
+            A4.is_3d, A4.points, A4.lines,
             A4.boundaries, A4.centroids, A4.faces, A4.kernels,
             A4.primitives, A4.nodes, A4.areas, A4.islands,
-            A4.holes, A4.volumes
+            A4.holes, A4.volumes, A5.registered_stds
             FROM vector_base A1, vector_relative_time A2, 
-            vector_spatial_extent A3, vector_metadata A4 
-            WHERE A1.id = A2.id AND A1.id = A3.id AND A1.id = A4.id;
+            vector_spatial_extent A3, vector_metadata A4,
+            vector_stds_register A5
+            WHERE A1.id = A2.id AND A1.id = A3.id AND 
+            A1.id = A4.id AND A1.id = A5.id;
+
+

Modified: grass/trunk/temporal/benchmark.sh
===================================================================
--- grass/trunk/temporal/benchmark.sh	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/benchmark.sh	2013-12-31 02:41:37 UTC (rev 58564)
@@ -11,8 +11,10 @@
 MAP_LIST="map_list.txt"
 rm ${MAP_LIST}
 
-NUM_MAPS=50000
+NUM_MAPS=10000
 
+echo "### Generate raster maps"
+
 count=1
 while [ $count -lt ${NUM_MAPS} ]; do
     name="test_bench_${count}"
@@ -21,18 +23,39 @@
     count=$((count + 1))
 done
 
-t.create type=strds temporaltype=absolute output=benchmark1 title="Benchmark1" descr="Benchmark1 dataset"
-t.create type=strds temporaltype=absolute output=benchmark2 title="Benchmark2" descr="Benchmark2 dataset"
+echo "### Create space time datasets"
 
+time t.create type=strds temporaltype=absolute output=bench1 title="Bench1" descr="Bench1"
+time t.create type=strds temporaltype=absolute output=bench2 title="Bench2" descr="Bench2"
+time t.create type=strds temporaltype=absolute output=bench3 title="Bench3" descr="Bench3"
+time t.create type=strds temporaltype=absolute output=bench4 title="Bench4" descr="Bench4"
+
 echo "### Register maps"
-time t.register -i input=benchmark1  file=${MAP_LIST} start="2001-01-01 00:00:00" increment="1 hours"
-time t.register -i input=benchmark2  file=${MAP_LIST} start="2001-01-01 00:00:00" increment="1 hours"
+time t.register -i input=bench1  file=${MAP_LIST} start="2001-01-01 00:00:00" increment="1 day"
+echo "### Register maps again"
+time t.register input=bench2  file=${MAP_LIST}
+echo "### Register maps again"
+time t.register input=bench3  file=${MAP_LIST}
+echo "### Register maps again"
+time t.register input=bench4  file=${MAP_LIST}
 
 echo "### List maps"
-time t.rast.list input=benchmark1 column=name,start_time > "/dev/null"
-time t.rast.list input=benchmark2 column=name,start_time > "/dev/null"
+time t.rast.list input=bench1 column=name,start_time > "/dev/null"
+time t.rast.list input=bench2 column=name,start_time > "/dev/null"
+time t.rast.list input=bench3 column=name,start_time,end_time \
+    where="start_time > '2001-01-01'" > "/dev/null"
+time t.rast.list input=bench4 column=name,start_time,end_time,min,max \
+    where="start_time > '2001-01-01'" > "/dev/null"
 
+echo "### STRDS Infos"
+t.info bench1
+t.info bench2
+t.info bench3
+t.info bench4
+
 echo "### Remove STRDS and maps"
-time t.remove -rf type=strds input=benchmark1
-echo "### Remove STRDS"
-time t.remove type=strds input=benchmark2
+time t.remove type=strds input=bench1
+time t.remove type=strds input=bench2
+time t.remove type=strds input=bench3
+time t.remove -rf type=strds input=bench4
+

Modified: grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py
===================================================================
--- grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -126,7 +126,7 @@
             if new_map:
                 # Set the time stamp and write it to the raster map
                 if sp.is_time_absolute():
-                    new_map.set_absolute_time(start, end, None)
+                    new_map.set_absolute_time(start, end)
                 else:
                     new_map.set_relative_time(start,
                                               end, sp.get_relative_time_unit())
@@ -138,6 +138,8 @@
                 count += 1
 
     # Update the spatio-temporal extent and the raster metadata table entries
+    new_sp.set_aggregation_type(method)
+    new_sp.metadata.update(dbif)
     new_sp.update_from_registered_maps(dbif)
 
     dbif.close()

Modified: grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
===================================================================
--- grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -124,7 +124,7 @@
             if new_map:
                 # Set the time stamp and write it to the raster map
                 if sp.is_time_absolute():
-                    new_map.set_absolute_time(start, end, None)
+                    new_map.set_absolute_time(start, end)
                 else:
                     new_map.set_relative_time(start,
                                               end, sp.get_relative_time_unit())
@@ -134,6 +134,8 @@
                 new_sp.register_map(new_map, dbif)
 
     # Update the spatio-temporal extent and the raster metadata table entries
+    new_sp.set_aggregation_type(method)
+    new_sp.metadata.update(dbif)
     new_sp.update_from_registered_maps(dbif)
 
     dbif.close()

Modified: grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py
===================================================================
--- grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -162,17 +162,17 @@
         id = _map.get_id()
         if overwrite_flags[id] == True:
             if _map.is_time_absolute():
-                start, end, tz = _map.get_absolute_time()
+                start, end = _map.get_absolute_time()
                 if _map.is_in_db():
                     _map.delete(dbif)
                 _map = sp.get_new_map_instance(id)
-                _map.set_absolute_time(start, end, tz)
+                _map.set_absolute_time(start, end)
             else:
                 start, end, unit = _map.get_relative_time()
                 if _map.is_in_db():
                     _map.delete(dbif)
                 _map = sp.get_new_map_instance(id)
-                _map.set_relative_time(start, end, tz)
+                _map.set_relative_time(start, end, unit)
         _map.load()
         _map.insert(dbif)
         sp.register_map(_map, dbif)

Modified: grass/trunk/temporal/t.rast.import/test.t.rast.import.relative.sh
===================================================================
--- grass/trunk/temporal/t.rast.import/test.t.rast.import.relative.sh	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast.import/test.t.rast.import.relative.sh	2013-12-31 02:41:37 UTC (rev 58564)
@@ -35,7 +35,7 @@
     title="A test with input files" descr="A test with input files"
 
 # The first @test
-t.register -i type=rast input=precip_rel file="${n1}"  unit="years" 
+t.register type=rast input=precip_rel file="${n1}"  unit="years" 
 
 t.rast.export input=precip_rel output=strds_export.tar.bz2 compression=bzip2 format=GTiff workdir=test
 t.rast.export input=precip_rel output=strds_export.tar.gz compression=gzip format=GTiff workdir=test

Modified: grass/trunk/temporal/t.rast.series/t.rast.series.py
===================================================================
--- grass/trunk/temporal/t.rast.series/t.rast.series.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast.series/t.rast.series.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -105,11 +105,6 @@
                                 method=method)
 
         if ret == 0 and not add_time:
-            if sp.is_time_absolute():
-                start_time, end_time, tz = sp.get_absolute_time()
-            else:
-                start_time, end_time, unit = sp.get_relative_time()
-
             # Create the time range for the output map
             if output.find("@") >= 0:
                 id = output
@@ -119,12 +114,8 @@
 
             map = sp.get_new_map_instance(id)
             map.load()
+            map.set_temporal_extent(sp.get_temporal_extent())
 
-            if sp.is_time_absolute():
-                map.set_absolute_time(start_time, end_time, tz)
-            else:
-                map.set_relative_time(start_time, end_time, unit)
-
             # Register the map in the temporal database
             if map.is_in_db():
                 map.update_all()

Modified: grass/trunk/temporal/t.rast3d.univar/test.t.rast3d.univar.sh
===================================================================
--- grass/trunk/temporal/t.rast3d.univar/test.t.rast3d.univar.sh	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.rast3d.univar/test.t.rast3d.univar.sh	2013-12-31 02:41:37 UTC (rev 58564)
@@ -15,6 +15,7 @@
 
 t.create --o type=str3ds temporaltype=absolute output=precip_abs1 title="A test" descr="A test"
 t.register type=rast3d --v -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-01-15 12:05:45" increment="14 days"
+t.info type=str3ds input=precip_abs1
 
 # The first @test
 t.rast3d.univar -he input=precip_abs1 

Modified: grass/trunk/temporal/t.register/t.register.py
===================================================================
--- grass/trunk/temporal/t.register/t.register.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.register/t.register.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -118,8 +118,10 @@
         type=type, name=name, maps=maps, file=file, start=start, end=end,
         unit=unit, increment=increment, dbif=None, interval=interval, fs=fs)
 
+
 ###############################################################################
 
 if __name__ == "__main__":
     options, flags = grass.parser()
-    main()
+ 
+    tgis.profile_function(main)

Added: grass/trunk/temporal/t.register/test.t.register.raster.file.timezone.sh
===================================================================
--- grass/trunk/temporal/t.register/test.t.register.raster.file.timezone.sh	                        (rev 0)
+++ grass/trunk/temporal/t.register/test.t.register.raster.file.timezone.sh	2013-12-31 02:41:37 UTC (rev 58564)
@@ -0,0 +1,60 @@
+#!/bin/sh
+# This is a test to register and unregister raster maps in
+# space time raster input.
+# The raster maps will be registered in different space time raster
+# inputs
+# Maps have absolute time with time zone information
+
+# We need to set a specific region in the
+# @preprocess step of this test. We generate
+# raster with r.mapcalc and create two space time raster inputs
+# with absolute time
+# The region setting should work for UTM and LL test locations
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3
+
+r.mapcalc --o expr="prec_1 = rand(0, 550)"
+r.mapcalc --o expr="prec_2 = rand(0, 450)"
+r.mapcalc --o expr="prec_3 = rand(0, 320)"
+r.mapcalc --o expr="prec_4 = rand(0, 510)"
+r.mapcalc --o expr="prec_5 = rand(0, 300)"
+r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+n2=`g.tempfile pid=2 -d` # Map names and start time
+n3=`g.tempfile pid=3 -d` # Map names start time and increment
+
+cat > "${n2}" << EOF
+prec_1|2001-01-01 10:00:00 +02:00
+prec_2|2001-02-01 10:00:00 +02:00
+prec_3|2001-03-01 10:00:00 +02:00
+prec_4|2001-04-01 10:00:00 +02:00
+prec_5|2001-05-01 10:00:00 +02:00
+prec_6|2001-06-01 10:00:00 +02:00
+EOF
+cat "${n2}"
+
+cat > "${n3}" << EOF
+prec_1|2001-01-01 12:00:00 +01:00|2001-04-01 14:00:00 -01:00
+prec_2|2001-04-01 12:00:00 +01:00|2001-07-01 14:00:00 -01:00
+prec_3|2001-07-01 12:00:00 +01:00|2001-10-01 14:00:00 -01:00
+prec_4|2001-10-01 12:00:00 +01:00|2002-01-01 14:00:00 -01:00
+prec_5|2002-01-01 12:00:00 +01:00|2002-04-01 14:00:00 -01:00
+prec_6|2002-04-01 12:00:00 +01:00|2002-07-01 14:00:00 -01:00
+EOF
+cat "${n3}"
+
+# The first @test
+# We create the space time raster inputs and register the raster maps with absolute time interval
+t.create --o type=strds temporaltype=absolute output=precip_abs title="A test with input files" descr="A test with input files"
+
+# Test with input files
+# File 1
+# File 2
+t.register --o input=precip_abs file="${n2}"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+# File 3
+t.register --o -i input=precip_abs file="${n3}"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+
+t.remove -rf type=strds input=precip_abs


Property changes on: grass/trunk/temporal/t.register/test.t.register.raster.file.timezone.sh
___________________________________________________________________
Added: svn:executable
   + *

Modified: grass/trunk/temporal/t.remove/t.remove.py
===================================================================
--- grass/trunk/temporal/t.remove/t.remove.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.remove/t.remove.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -53,6 +53,7 @@
 #% key: f
 #% description: Force recursive removing
 #%end
+
 import grass.script as grass
 import grass.temporal as tgis
 import grass.pygrass.modules as pyg
@@ -154,4 +155,5 @@
 
 if __name__ == "__main__":
     options, flags = grass.parser()
-    main()
+    
+    tgis.profile_function(main)

Modified: grass/trunk/temporal/t.support/t.support.py
===================================================================
--- grass/trunk/temporal/t.support/t.support.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.support/t.support.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -130,10 +130,10 @@
             else:
                 # Delete the map from the temporal database
                 # We need to update all effected space time datasets
-                rows = map.get_registered_datasets(dbif)
-                if rows:
-                    for row in rows:
-                        dataset_dict[row["id"]] = row["id"]
+                datasets = map.get_registered_datasets(dbif)
+                if datasets:
+                    for dataset in datasets:
+                        dataset_dict[dataset] = dataset
                 # Collect the delete statements
                 statement += map.delete(dbif=dbif, update=False, execute=False)
 

Modified: grass/trunk/temporal/t.support/test.t.support.sh
===================================================================
--- grass/trunk/temporal/t.support/test.t.support.sh	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.support/test.t.support.sh	2013-12-31 02:41:37 UTC (rev 58564)
@@ -28,6 +28,7 @@
 t.support --v type=strds input=precip_rel1 title="Test support" descr="This is the support test strds" semantictype=max
 t.info type=strds input=precip_rel1
 
+
 # Check metadata update
 t.info type=strds input=precip_abs1
 t.support --v type=strds input=precip_abs1 title="Test support" descr="This is the support test strds" semantictype=mean
@@ -59,4 +60,4 @@
 
 t.remove --v type=strds input=precip_abs1,precip_rel1
 t.unregister type=rast maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
-g.remove rast=prec_4,prec_5,prec_6
\ No newline at end of file
+g.remove rast=prec_4,prec_5,prec_6

Modified: grass/trunk/temporal/t.unregister/t.unregister.py
===================================================================
--- grass/trunk/temporal/t.unregister/t.unregister.py	2013-12-30 17:48:18 UTC (rev 58563)
+++ grass/trunk/temporal/t.unregister/t.unregister.py	2013-12-31 02:41:37 UTC (rev 58564)
@@ -135,7 +135,7 @@
                 # Store all unique dataset ids in a dictionary
                 if datasets:
                     for dataset in datasets:
-                        update_dict[dataset["id"]] = dataset["id"]
+                        update_dict[dataset] = dataset
                 # Collect SQL statements
                 statement += map.delete(dbif=dbif, update=False, execute=False)
         else:
@@ -170,4 +170,5 @@
 
 if __name__ == "__main__":
     options, flags = grass.parser()
-    main()
+    
+    tgis.profile_function(main)



More information about the grass-commit mailing list