~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/python/script/db.py

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Database related functions to be used in Python scripts.
 
3
 
 
4
Usage:
 
5
 
 
6
::
 
7
 
 
8
    from grass.script import db as grass
 
9
 
 
10
    grass.db_describe(table)
 
11
    ...
 
12
 
 
13
(C) 2008-2009, 2012 by the GRASS Development Team
 
14
This program is free software under the GNU General Public
 
15
License (>=v2). Read the file COPYING that comes with GRASS
 
16
for details.
 
17
 
 
18
.. sectionauthor:: Glynn Clements
 
19
.. sectionauthor:: Martin Landa <landa.martin gmail.com>
 
20
"""
 
21
 
 
22
from core import *
 
23
from utils import try_remove
 
24
from grass.exceptions import CalledModuleError
 
25
 
 
26
 
 
27
def db_describe(table, **args):
 
28
    """Return the list of columns for a database table
 
29
    (interface to `db.describe -c`). Example:
 
30
 
 
31
    >>> run_command('g.copy', vector='firestations,myfirestations')
 
32
    0
 
33
    >>> db_describe('myfirestations') # doctest: +ELLIPSIS
 
34
    {'nrows': 71, 'cols': [['cat', 'INTEGER', '20'], ... 'ncols': 22}
 
35
    >>> run_command('g.remove', flags='f', type='vector', name='myfirestations')
 
36
    0
 
37
 
 
38
    :param str table: table name
 
39
    :param list args:
 
40
 
 
41
    :return: parsed module output
 
42
    """
 
43
    s = read_command('db.describe', flags='c', table=table, **args)
 
44
    if not s:
 
45
        fatal(_("Unable to describe table <%s>") % table)
 
46
 
 
47
    cols = []
 
48
    result = {}
 
49
    for l in s.splitlines():
 
50
        f = l.split(':')
 
51
        key = f[0]
 
52
        f[1] = f[1].lstrip(' ')
 
53
        if key.startswith('Column '):
 
54
            n = int(key.split(' ')[1])
 
55
            cols.insert(n, f[1:])
 
56
        elif key in ['ncols', 'nrows']:
 
57
            result[key] = int(f[1])
 
58
        else:
 
59
            result[key] = f[1:]
 
60
    result['cols'] = cols
 
61
 
 
62
    return result
 
63
 
 
64
 
 
65
def db_table_exist(table, **args):
 
66
    """Check if table exists.
 
67
 
 
68
    If no driver or database are given, then default settings is used
 
69
    (check db_connection()).
 
70
 
 
71
    >>> run_command('g.copy', vector='firestations,myfirestations')
 
72
    0
 
73
    >>> db_table_exist('myfirestations')
 
74
    True
 
75
    >>> run_command('g.remove', flags='f', type='vector', name='myfirestations')
 
76
    0
 
77
 
 
78
    :param str table: table name
 
79
    :param args:
 
80
 
 
81
    :return: True for success, False otherwise
 
82
    """
 
83
    nuldev = file(os.devnull, 'w+')
 
84
    ok = True
 
85
    try:
 
86
        run_command('db.describe', flags='c', table=table,
 
87
                    stdout=nuldev, stderr=nuldev, **args)
 
88
    except CalledModuleError:
 
89
        ok = False
 
90
    finally:
 
91
        nuldev.close()
 
92
 
 
93
    return ok
 
94
 
 
95
 
 
96
def db_connection(force=False):
 
97
    """Return the current database connection parameters
 
98
    (interface to `db.connect -g`). Example:
 
99
 
 
100
    >>> db_connection()
 
101
    {'group': '', 'schema': '', 'driver': 'sqlite', 'database': '$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db'}
 
102
 
 
103
    :param force True to set up default DB connection if not defined
 
104
 
 
105
    :return: parsed output of db.connect
 
106
    """
 
107
    nuldev = file(os.devnull, 'w')
 
108
    conn = parse_command('db.connect', flags='g', stderr=nuldev)
 
109
    nuldev.close()
 
110
    if not conn and force:
 
111
        run_command('db.connect', flags='c')
 
112
        conn = parse_command('db.connect', flags='g')
 
113
    
 
114
    return conn
 
115
 
 
116
def db_select(sql=None, filename=None, table=None, **args):
 
117
    """Perform SQL select statement
 
118
 
 
119
    Note: one of <em>sql</em>, <em>filename</em>, or <em>table</em>
 
120
    arguments must be provided.
 
121
 
 
122
    Examples:
 
123
 
 
124
    >>> run_command('g.copy', vector='firestations,myfirestations')
 
125
    0
 
126
    >>> db_select(sql = 'SELECT cat,CITY FROM myfirestations WHERE cat < 4')
 
127
    (('1', 'Morrisville'), ('2', 'Morrisville'), ('3', 'Apex'))
 
128
 
 
129
    Simplyfied usage (it performs <tt>SELECT * FROM myfirestations</tt>.)
 
130
 
 
131
    >>> db_select(table = 'myfirestations') # doctest: +ELLIPSIS
 
132
    (('1', '24', 'Morrisville #3', ... 'HS2A', '1.37'))
 
133
    >>> run_command('g.remove', flags='f', type='vector', name='myfirestations')
 
134
    0
 
135
 
 
136
    :param str sql: SQL statement to perform (or None)
 
137
    :param str filename: name of file with SQL statements (or None)
 
138
    :param str table: name of table to query (or None)
 
139
    :param str args:  see \gmod{db.select} arguments
 
140
    """
 
141
    fname = tempfile(create=False)
 
142
    if sql:
 
143
        args['sql'] = sql
 
144
    elif filename:
 
145
        args['input'] = filename
 
146
    elif table:
 
147
        args['table'] = table
 
148
    else:
 
149
        fatal(_("Programmer error: '%(sql)s', '%(filename)s', or '%(table)s' must be provided") %
 
150
              {'sql': 'sql', 'filename': 'filename', 'table': 'table'} )
 
151
 
 
152
    if 'sep' not in args:
 
153
        args['sep'] = '|'
 
154
 
 
155
    try:
 
156
        run_command('db.select', quiet=True, flags='c',
 
157
                    output=fname, **args)
 
158
    except CalledModuleError:
 
159
        fatal(_("Fetching data failed"))
 
160
 
 
161
    ofile = open(fname)
 
162
    result = map(lambda x: tuple(x.rstrip(os.linesep).split(args['sep'])),
 
163
                 ofile.readlines())
 
164
    ofile.close()
 
165
    try_remove(fname)
 
166
 
 
167
    return tuple(result)
 
168
 
 
169
 
 
170
def db_table_in_vector(table):
 
171
    """Return the name of vector connected to the table.
 
172
    It returns None if no vectors are connected to the table.
 
173
 
 
174
    >>> run_command('g.copy', vector='firestations,myfirestations')
 
175
    0
 
176
    >>> db_table_in_vector('myfirestations')
 
177
    ['myfirestations@user1']
 
178
    >>> db_table_in_vector('mfirestations')
 
179
    >>> run_command('g.remove', flags='f', type='vector', name='myfirestations')
 
180
    0
 
181
 
 
182
    :param str table: name of table to query
 
183
    """
 
184
    from vector import vector_db
 
185
    nuldev = file(os.devnull, 'w')
 
186
    used = []
 
187
    vects = list_strings('vect')
 
188
    for vect in vects:
 
189
        for f in vector_db(vect, stderr=nuldev).itervalues():
 
190
            if not f:
 
191
                continue
 
192
            if f['table'] == table:
 
193
                used.append(vect)
 
194
                break
 
195
    if len(used) > 0:
 
196
        return used
 
197
    else:
 
198
        return None