Skip to content

Commit

Permalink
sqlite db: automatically enable vacuum, trac https://trac.osgeo.org/g…
Browse files Browse the repository at this point in the history
…rass/ticket/3697 (bundle backport: trunk https://trac.osgeo.org/grass/changeset/73692, https://trac.osgeo.org/grass/changeset/73703, https://trac.osgeo.org/grass/changeset/73704, https://trac.osgeo.org/grass/changeset/73706, https://trac.osgeo.org/grass/changeset/73707, https://trac.osgeo.org/grass/changeset/73708)

 * lib/init: clean up sqlite db if existing, see https://trac.osgeo.org/grass/ticket/3697
 * libpython: move clean_default_db() to setup
 * libinit: use clean_default_db() from script.setup
 * libpython: add functions to finish a GRASS session
 * libinit: start rewriting to use functions in lib/python/scripts
 * libinit: fix https://trac.osgeo.org/grass/changeset/73707, clean_all() takes no arguments


git-svn-id: https://svn.osgeo.org/grass/grass/branches/releasebranch_7_6@73736 15284696-431f-4ddb-bdfa-cd5b030d7da7
  • Loading branch information
neteler committed Nov 30, 2018
1 parent e549e95 commit f790d68
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 28 deletions.
34 changes: 25 additions & 9 deletions lib/init/grass.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,12 @@ def set_paths(grass_config_dir):

# Set PYTHONPATH to find GRASS Python modules
if os.path.exists(gpath('etc', 'python')):
path_prepend(gpath('etc', 'python'), 'PYTHONPATH')
pythonpath = gpath('etc', 'python')
path_prepend(pythonpath, 'PYTHONPATH')
# the env var PYTHONPATH is only evaluated when python is started,
# thus:
sys.path.append(pythonpath)
# now we can import stuff from GRASS lib/python

# set path for the GRASS man pages
grass_man_path = gpath('docs', 'man')
Expand Down Expand Up @@ -1779,6 +1784,17 @@ def clean_temp():
nul.close()


def clean_all():
from grass.script import setup as gsetup
# clean default sqlite db
gsetup.clean_default_db()
# remove leftover temp files
clean_temp()
# save 'last used' GISRC after removing variables which shouldn't
# be saved, e.g. d.mon related
clean_env(os.environ['GISRC'])


def grep(pattern, lines):
"""Search lines (list of strings) and return them when beginning matches.
Expand Down Expand Up @@ -2128,10 +2144,12 @@ def main():
# only non-error, interactive version continues from here
if batch_job:
returncode = run_batch_job(batch_job)
clean_temp()
clean_all()
sys.exit(returncode)
elif params.exit_grass:
clean_temp()
# clean always at exit, cleans whatever is current mapset based on
# the GISRC env variable
clean_all()
sys.exit(0)
else:
clear_screen()
Expand Down Expand Up @@ -2166,17 +2184,15 @@ def main():

# close GUI if running
close_gui()

# here we are at the end of grass session
clear_screen()
# TODO: can we just register this atexit?
# TODO: and what is difference to deleting .tmp which we do?
clean_temp()
# save 'last used' GISRC after removing variables which shouldn't
# be saved, e.g. d.mon related
clean_env(gisrc)
clean_all()
if not params.tmp_location:
writefile(gisrcrc, readfile(gisrc))
# After this point no more grass modules may be called
# done message at last: no atexit.register()
# or register done_message()
done_message()

if __name__ == '__main__':
Expand Down
106 changes: 87 additions & 19 deletions lib/python/script/setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Setup and initialization functions
"""Setup, initialization, and clean-up functions
Function can be used in Python scripts to setup a GRASS environment
without starting an actual GRASS session.
Functions can be used in Python scripts to setup a GRASS environment
and session without using grassXY.
Usage::
Expand Down Expand Up @@ -77,8 +77,8 @@
for vect in gscript.list_strings(type='vector'):
print vect
# delete the rcfile
os.remove(rcfile)
# clean up at the end
gsetup.cleanup()
(C) 2010-2012 by the GRASS Development Team
Expand All @@ -88,6 +88,7 @@
@author Martin Landa <landa.martin gmail.com>
@author Vaclav Petras <wenzeslaus gmail.com>
@author Markus Metz
"""

# TODO: this should share code from lib/init/grass.py
Expand All @@ -100,6 +101,9 @@
import tempfile as tmpfile


windows = sys.platform == 'win32'


def write_gisrc(dbase, location, mapset):
"""Write the ``gisrc`` file and return its path."""
gisrc = tmpfile.mktemp()
Expand All @@ -117,21 +121,19 @@ def set_gui_path():
sys.path.insert(0, gui_path)


# TODO: there should be a function to do the clean up
# (unset the GISRC and delete the file)
def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
"""Initialize system variables to run GRASS modules
This function is for running GRASS GIS without starting it
explicitly. No GRASS modules shall be called before call of this
function but any module or user script can be called afterwards
as if it would be called in an actual GRASS session. GRASS Python
libraries are usable as well in general but the ones using
C libraries through ``ctypes`` are not (which is caused by
library path not being updated for the current process
which is a common operating system limitation).
This function is for running GRASS GIS without starting it with the
standard script grassXY. No GRASS modules shall be called before
call of this function but any module or user script can be called
afterwards because a GRASS session has been set up. GRASS Python
libraries are usable as well in general but the ones using C
libraries through ``ctypes`` are not (which is caused by library
path not being updated for the current process which is a common
operating system limitation).
To create a (fake) GRASS session a ``gisrc`` file is created.
To create a GRASS session a ``gisrc`` file is created.
Caller is responsible for deleting the ``gisrc`` file.
Basic usage::
Expand All @@ -142,8 +144,8 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
"/home/john/grassdata",
"nc_spm_08", "user1")
# ... use GRASS modules here
# remove the session's gisrc file to end the session
os.remove(gisrc)
# end the session
gscript.setup.finish()
:param gisbase: path to GRASS installation
:param dbase: path to GRASS database (default: '')
Expand All @@ -152,7 +154,8 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
:returns: path to ``gisrc`` file (to be deleted later)
"""
# TODO: why we don't set GISBASE?
# Set GISBASE
os.environ['GISBASE'] = gisbase
mswin = sys.platform.startswith('win')
# define PATH
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')
Expand All @@ -179,6 +182,7 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
os.environ['@LD_LIBRARY_PATH_VAR@'] = ''
os.environ['@LD_LIBRARY_PATH_VAR@'] += os.pathsep + os.path.join(gisbase, 'lib')

# TODO: lock the mapset?
os.environ['GIS_LOCK'] = str(os.getpid())

# Set GRASS_PYTHON and PYTHONPATH to find GRASS Python modules
Expand All @@ -204,3 +208,67 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):

os.environ['GISRC'] = write_gisrc(dbase, location, mapset)
return os.environ['GISRC']


# clean-up functions when terminating a GRASS session
# these fns can only be called within a valid GRASS session
def clean_default_db():
# clean the default db if it is sqlite
from grass.script import db as gdb
from grass.script import core as gcore

conn = gdb.db_connection()
if conn and conn['driver'] == 'sqlite':
# check if db exists
gisenv = gcore.gisenv()
database = conn['database']
database = database.replace('$GISDBASE', gisenv['GISDBASE'])
database = database.replace('$LOCATION_NAME', gisenv['LOCATION_NAME'])
database = database.replace('$MAPSET', gisenv['MAPSET'])
if os.path.exists(database):
gcore.message(_("Cleaning up default sqlite database ..."))
gcore.start_command('db.execute', sql = 'VACUUM')
# give it some time to start
import time
time.sleep(0.1)


def call(cmd, **kwargs):
import subprocess
"""Wrapper for subprocess.call to deal with platform-specific issues"""
if windows:
kwargs['shell'] = True
return subprocess.call(cmd, **kwargs)


def clean_temp():
from grass.script import core as gcore

gcore.message(_("Cleaning up temporary files..."))
nul = open(os.devnull, 'w')
gisbase = os.environ['GISBASE']
call([os.path.join(gisbase, "etc", "clean_temp")], stdout=nul)
nul.close()


def finish():
"""Terminate the GRASS session and clean up
GRASS commands can no longer be used after this function has been
called
Basic usage::
import grass.script as gscript
gscript.setup.cleanup()
"""

clean_default_db()
clean_temp()
# TODO: unlock the mapset?
# unset the GISRC and delete the file
from grass.script import utils as gutils
gutils.try_remove(os.environ['GISRC'])
os.environ.pop('GISRC')
# remove gislock env var (not the gislock itself
os.environ.pop('GIS_LOCK')

0 comments on commit f790d68

Please sign in to comment.