[GRASS-SVN] r58586 - grass/trunk/lib/python/temporal
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jan 2 19:34:42 PST 2014
Author: huhabla
Date: 2014-01-02 19:34:41 -0800 (Thu, 02 Jan 2014)
New Revision: 58586
Modified:
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/gui_support.py
Log:
Better performance of tgis.init() and code cleanup. Reduced number of external module calls.
Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2014-01-02 21:54:35 UTC (rev 58585)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2014-01-03 03:34:41 UTC (rev 58586)
@@ -477,7 +477,7 @@
maps = self.get_registered_maps_as_objects(
where=None, order="start_time", dbif=dbif)
- return count_temporal_topology_relationships(maps)
+ return count_temporal_topology_relationships(maps1=maps, dbif=dbif)
def check_temporal_topology(self, maps=None, dbif=None):
"""!Check the temporal topology of all maps of the current space time
@@ -516,7 +516,7 @@
maps = self.get_registered_maps_as_objects(
where=None, order="start_time", dbif=dbif)
- relations = count_temporal_topology_relationships(maps)
+ relations = count_temporal_topology_relationships(maps1=maps, dbif=dbif)
if relations == None:
return False
@@ -2272,7 +2272,7 @@
dbif.execute_transaction(sql_script)
# Read and validate the selected end time
- self.select()
+ self.select(dbif)
if self.is_time_absolute():
start_time, end_time = self.get_absolute_time()
Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py 2014-01-02 21:54:35 UTC (rev 58585)
+++ grass/trunk/lib/python/temporal/base.py 2014-01-03 03:34:41 UTC (rev 58586)
@@ -37,10 +37,10 @@
###############################################################################
-
class DictSQLSerializer(object):
def __init__(self):
self.D = {}
+ self.dbmi_paramstyle = get_tgis_dbmi_paramstyle()
def serialize(self, type, table, where=None):
"""!Convert the internal dictionary into a string of semicolon
@@ -75,7 +75,6 @@
\endcode
"""
- dbif = SQLDatabaseInterfaceConnection()
sql = ""
args = []
@@ -110,12 +109,12 @@
sql += ') VALUES ('
for key in self.D.keys():
if count == 0:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += '?'
else:
sql += '%s'
else:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += ' ,?'
else:
sql += ' ,%s'
@@ -135,13 +134,13 @@
# Update only entries which are not None
if self.D[key] is not None:
if count == 0:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += ' %s = ? ' % key
else:
sql += ' %s ' % key
sql += '= %s '
else:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += ' ,%s = ? ' % key
else:
sql += ' ,%s ' % key
@@ -158,13 +157,13 @@
sql += 'UPDATE ' + table + ' SET '
for key in self.D.keys():
if count == 0:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += ' %s = ? ' % key
else:
sql += ' %s ' % key
sql += '= %s '
else:
- if dbif.dbmi.paramstyle == "qmark":
+ if self.dbmi_paramstyle == "qmark":
sql += ' ,%s = ? ' % key
else:
sql += ' ,%s ' % key
Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py 2014-01-02 21:54:35 UTC (rev 58585)
+++ grass/trunk/lib/python/temporal/core.py 2014-01-03 03:34:41 UTC (rev 58586)
@@ -27,7 +27,7 @@
@endcode
-(C) 2011-2013 by the GRASS Development Team
+(C) 2011-2014 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@@ -83,7 +83,23 @@
# of the temporal GIS
# It can either be "sqlite" or "pg"
tgis_backend = None
+def get_tgis_backend():
+ """!Return the temporal GIS backend as string
+
+ return either "sqlite" or "pg"
+ """
+ global tgis_backend
+ return tgis_backend
+# Global variable that defines the database string
+# of the temporal GIS
+tgis_database = None
+def get_tgis_database():
+ """!Return the temporal database string specified with t.connect
+ """
+ global tgis_database
+ return tgis_database
+
# 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
@@ -94,9 +110,22 @@
# temporal database SQL layout
tgis_db_version=2
+# We need to know the parameter style of the database backend
+tgis_dbmi_paramstyle = None
+
+def get_tgis_dbmi_paramstyle():
+ """!Return the temporal database backend parameter style
+
+ @return "qmark" or ""
+ """
+ global tgis_dbmi_paramstyle
+ return tgis_dbmi_paramstyle
+
# 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
-current_mapset=None
+# a global variable that will be initiated when init() is called
+current_mapset = None
+current_location = None
+current_gisdbase = None
###############################################################################
@@ -110,19 +139,29 @@
global current_mapset
return current_mapset
-def _set_current_mapset(mapset=None):
- """!This functions set the global current mapset variable to
- the current mapset by calling g.gisenv.
+###############################################################################
- @param mapset The current mapset, g.gisenv will be called
- if this variable is set to None
+def get_current_location():
+ """!Return the current location
+
+ This is the fastest way to receive the current location.
+ The current location is set by init() and stored in a global variable.
+ This function provides access to this global variable.
"""
- global current_mapset
+ global current_location
+ return current_location
+
+###############################################################################
- if mapset == None:
- mapset = core.gisenv()["MAPSET"]
+def get_current_gisdbase():
+ """!Return the current gis database (gisdbase)
- current_mapset = mapset
+ This is the fastest way to receive the current gisdbase.
+ The current gisdbase is set by init() and stored in a global variable.
+ This function provides access to this global variable.
+ """
+ global current_gisdbase
+ return current_gisdbase
###############################################################################
@@ -266,48 +305,20 @@
###############################################################################
-def get_temporal_dbmi_init_string(kv=None, grassenv=None):
- """!Return the database initialization string
+# The temporal database string set with t.connect
+# with substituted GRASS variables gisdbase, location and mapset
+tgis_database_string = None
- @param kv dictionary generated by grass.script.parse_command("t.connect", flags="pg")
- @param grassenv Grass environemntal variables created by grass.script.gisenv()
+def get_tgis_database_string():
+ """!Return the preprocessed temporal database string
+
+ This string is the temporal database string set with t.connect
+ that was processed to substitue location, gisdbase and mapset
+ varibales.
"""
+ global tgis_database_string
+ return tgis_database_string
- global temporal_dbmi_init_string
-
- if kv == None:
- kv = core.parse_command("t.connect", flags="pg")
- if grassenv == None:
- grassenv = core.gisenv()
-
- global tgis_backend
- msgr = get_tgis_message_interface()
-
- if tgis_backend == "sqlite":
- # We substitute GRASS variables if they are located in the database string
- # This behavior is in conjunction with db.connect
- if "database" in kv:
- string = kv["database"]
- string = string.replace("$GISDBASE", grassenv["GISDBASE"])
- 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 "
- "interface. Use t.connect to specify the driver "
- "and the database string"))
- 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 "
- "interface. Use t.connect to specify the driver "
- "and the database string"))
-
###############################################################################
def get_sql_template_path():
@@ -319,6 +330,7 @@
def stop_subprocesses():
"""!Stop the messenger and C-interface subprocesses
+ that are started by tgis.init()
"""
global message_interface
global c_library_interface
@@ -327,55 +339,74 @@
if c_library_interface:
c_library_interface.stop()
+# We register this function to be called at exit
atexit.register(stop_subprocesses)
###############################################################################
def init():
"""!This function set the correct database backend from GRASS environmental variables
- and creates the grass location database structure for raster,
+ and creates the grass temporal database structure for raster,
vector and raster3d maps as well as for the space-time datasets strds,
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
-
+
+ Re-run this function in case the following GRASS variables change while the process runs:
+ - MAPSET
+ - LOCATION_NAME
+ - GISDBASE
+ - TGIS_RAISE_ON_ERROR
+ - TGIS_DISABLE_MAPSET_CHECK
+ - TGIS_DISABLE_TIMESTAMP_WRITE
+
+ Re-run the script if the following t.connect variables change while the process runs:
+ - temporal GIS driver (set by t.connect driver=)
+ - temporal GIS database (set by t.connect database=)
+
The following environmental variables are checked:
- GRASS_TGIS_PROFILE
ATTENTION: This functions must be called before any spatio-temporal processing
can be started
"""
- # We need to set the correct database backend from the environment variables
+ # We need to set the correct database backend and several global variables
+ # from the GRASS mapset specific environment variables of g.gisenv and t.connect
global tgis_backend
+ global tgis_database
+ global tgis_database_string
+ global tgis_dbmi_paramstyle
global enable_mapset_check
global enable_timestamp_write
-
+ global current_mapset
+ global current_location
+ global current_gisdbase
+
+ # We must run t.connect at first to create the temporal database and to
+ # get the environmental variables
core.run_command("t.connect", flags="c")
kv = core.parse_command("t.connect", flags="pg")
grassenv = core.gisenv()
raise_on_error = False
+ # Set the global variable for faster access
+ current_mapset = grassenv["MAPSET"]
+ current_location = grassenv["LOCATION_NAME"]
+ current_gisdbase = grassenv["GISDBASE"]
+
# 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")
@@ -414,15 +445,33 @@
else:
# Set the default sqlite3 connection in case nothing was defined
core.run_command("t.connect", flags="d")
+ kv = core.parse_command("t.connect", flags="pg")
+ tgis_backend = kv["driver"]
+ # Database string from t.connect -pg
+ tgis_database = kv["database"]
+ # Set the parameter style
+ tgis_dbmi_paramstyle = dbmi.paramstyle
+
+ # Create the temporal database string
+ if tgis_backend == "sqlite":
+ # We substitute GRASS variables if they are located in the database string
+ # This behavior is in conjunction with db.connect
+ tgis_database_string = tgis_database
+ tgis_database_string = tgis_database_string.replace("$GISDBASE", current_gisdbase)
+ tgis_database_string = tgis_database_string.replace("$LOCATION_NAME", current_location)
+ tgis_database_string = tgis_database_string.replace("$MAPSET", current_mapset)
+ elif tgis_backend == "pg":
+ tgis_database_string = tgis_database
+
+ # We do not know if the database already exists
db_exists = False
- database = get_temporal_dbmi_init_string(kv=kv, grassenv=grassenv)
dbif = SQLDatabaseInterfaceConnection()
# Check if the database already exists
if tgis_backend == "sqlite":
# Check path of the sqlite database
- if os.path.exists(database):
+ if os.path.exists(tgis_database_string):
dbif.connect()
# Check for raster_base table
dbif.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='raster_base';")
@@ -441,7 +490,6 @@
db_exists = True
if db_exists == True:
-
# Check the version of the temporal database
# This version works only with database of version 2
dbif.close()
@@ -450,7 +498,7 @@
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"
@@ -460,11 +508,11 @@
"Supported temporal database version is: %(tdb)i")%( {"tdb":get_tgis_db_version()}))
return
- create_temporal_database(dbif, database)
+ create_temporal_database(dbif)
###############################################################################
-def create_temporal_database(dbif, database):
+def create_temporal_database(dbif):
"""!This function will create the temporal database
It will create all tables and triggers that are needed to run
@@ -475,6 +523,7 @@
global tgis_backend
global tgis_version
global tgis_db_version
+ global tgis_database_string
template_path = get_sql_template_path()
msgr = get_tgis_message_interface()
@@ -528,11 +577,11 @@
stvds_tables_sql = stds_tables_template_sql.replace("STDS", "stvds")
str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
- msgr.message(_("Create temporal database: %s" % (database)))
+ msgr.message(_("Create temporal database: %s" % (tgis_database_string)))
if tgis_backend == "sqlite":
# We need to create the sqlite3 database path if it does not exists
- tgis_dir = os.path.dirname(database)
+ tgis_dir = os.path.dirname(tgis_database_string)
if not os.path.exists(tgis_dir):
os.makedirs(tgis_dir)
# Set up the trigger that takes care of
@@ -633,7 +682,12 @@
self.dbmi = psycopg2
self.msgr = get_tgis_message_interface()
+ self.msgr.debug(1, "SQLDatabaseInterfaceConnection constructor")
+ def __del__(self):
+ if self.connected is True:
+ self.close()
+
def rollback(self):
"""
Roll back the last transaction. This must be called
@@ -650,9 +704,10 @@
Supported backends are sqlite3 and postgresql
"""
- self.database = get_temporal_dbmi_init_string()
+ global tgis_database_string
+
if self.dbmi.__name__ == "sqlite3":
- self.connection = self.dbmi.connect(self.database,
+ self.connection = self.dbmi.connect(tgis_database_string,
detect_types = self.dbmi.PARSE_DECLTYPES | self.dbmi.PARSE_COLNAMES)
self.connection.row_factory = self.dbmi.Row
self.connection.isolation_level = None
@@ -660,7 +715,7 @@
self.cursor.execute("PRAGMA synchronous = OFF")
self.cursor.execute("PRAGMA journal_mode = MEMORY")
elif self.dbmi.__name__ == "psycopg2":
- self.connection = self.dbmi.connect(self.database)
+ self.connection = self.dbmi.connect(tgis_database_string)
#self.connection.set_isolation_level(dbmi.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
self.cursor = self.connection.cursor(
cursor_factory = self.dbmi.extras.DictCursor)
@@ -668,7 +723,6 @@
def close(self):
"""!Close the DBMI connection"""
- #print "Close connection to", self.database
self.connection.commit()
self.cursor.close()
self.connected = False
@@ -819,7 +873,10 @@
def init_dbif(dbif):
"""!This method checks if the database interface connection exists,
- if not a new one will be created, connected and True will be returned
+ if not a new one will be created, connected and True will be returned.
+ If the database interface exists but is connected, the connection will be established.
+
+ @return the tuple (dbif, True|False)
Usage code sample:
@code
@@ -839,6 +896,9 @@
dbif = SQLDatabaseInterfaceConnection()
dbif.connect()
return dbif, True
+ elif dbif.connected is False:
+ dbif.connect()
+ return dbif, True
return dbif, False
Modified: grass/trunk/lib/python/temporal/gui_support.py
===================================================================
--- grass/trunk/lib/python/temporal/gui_support.py 2014-01-02 21:54:35 UTC (rev 58585)
+++ grass/trunk/lib/python/temporal/gui_support.py 2014-01-03 03:34:41 UTC (rev 58586)
@@ -18,7 +18,7 @@
###############################################################################
-def tlist_grouped(type, group_type = False):
+def tlist_grouped(type, group_type = False, dbif=None):
"""!List of temporal elements grouped by mapsets.
Returns a dictionary where the keys are mapset
@@ -36,6 +36,7 @@
@return directory of mapsets/elements
"""
result = {}
+ dbif, connected = init_dbif(dbif)
mapset = None
if type == 'stds':
@@ -44,7 +45,7 @@
types = [type]
for type in types:
try:
- tlist_result = tlist(type)
+ tlist_result = tlist(type=type, dbif=dbif)
except core.ScriptError, e:
warning(e)
continue
@@ -70,11 +71,14 @@
else:
result[mapset].append(name)
+ if connected is True:
+ dbif.close()
+
return result
###############################################################################
-def tlist(type):
+def tlist(type, dbif=None):
"""!Return a list of space time datasets of absolute and relative time
@param type element type (strds, str3ds, stvds)
@@ -83,10 +87,8 @@
"""
id = None
sp = dataset_factory(type, id)
+ dbif, connected = init_dbif(dbif)
- dbif = SQLDatabaseInterfaceConnection()
- dbif.connect()
-
output = []
temporal_type = ["absolute", 'relative']
for type in temporal_type:
@@ -107,6 +109,8 @@
for row in rows:
for col in row:
output.append(str(col))
- dbif.close()
+ if connected is True:
+ dbif.close()
+
return output
More information about the grass-commit
mailing list