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

« back to all changes in this revision

Viewing changes to lib/form/form.c

  • 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
 
#include <stdlib.h>
2
 
#include <string.h>
3
 
#include <stdio.h>
4
 
#include <unistd.h>
5
 
#include <fcntl.h>
6
 
#include <sys/time.h>
7
 
#include <sys/types.h>
8
 
 
9
 
#include <tcl.h>
10
 
#include <tk.h>
11
 
 
12
 
#include <locale.h>
13
 
#include <grass/gis.h>
14
 
#include <grass/dbmi.h>
15
 
#include <grass/form.h>
16
 
 
17
 
/* Structure to store column names and values */
18
 
typedef struct
19
 
{
20
 
    char *name;
21
 
    int ctype;
22
 
    char *value;
23
 
} COLUMN;
24
 
 
25
 
static char *Drvname, *Dbname, *Tblname, *Key;
26
 
 
27
 
static COLUMN *Columns = NULL;
28
 
static int allocatedRows = 0;   /* allocated space */
29
 
static int nRows = 0;
30
 
 
31
 
/* Start new sql update */
32
 
int reset_values(ClientData cdata, Tcl_Interp * interp, int argc,
33
 
                 char *argv[])
34
 
{
35
 
    nRows = 0;
36
 
    Drvname = NULL;
37
 
    Dbname = NULL;
38
 
    Tblname = NULL;
39
 
    Key = NULL;
40
 
 
41
 
    return TCL_OK;
42
 
}
43
 
 
44
 
int set_value(ClientData cdata, Tcl_Interp * interp, int argc, char *argv[])
45
 
{
46
 
    G_debug(2, "set_value(): %s %s", argv[1], argv[2]);
47
 
 
48
 
    if (strcmp(argv[1], F_DRIVER_FNAME) == 0) {
49
 
        Drvname = G_store(argv[2]);
50
 
    }
51
 
    else if (strcmp(argv[1], F_DATABASE_FNAME) == 0) {
52
 
        Dbname = G_store(argv[2]);
53
 
    }
54
 
    else if (strcmp(argv[1], F_TABLE_FNAME) == 0) {
55
 
        Tblname = G_store(argv[2]);
56
 
    }
57
 
    else if (strcmp(argv[1], F_KEY_FNAME) == 0) {
58
 
        Key = G_store(argv[2]);
59
 
    }
60
 
    else {
61
 
        if (nRows == allocatedRows) {
62
 
            allocatedRows += 100;
63
 
            Columns =
64
 
                (COLUMN *) G_realloc(Columns,
65
 
                                     (allocatedRows) * sizeof(COLUMN));
66
 
        }
67
 
        Columns[nRows].name = G_store(argv[1]);
68
 
        Columns[nRows].value = G_store(argv[2]);
69
 
        nRows++;
70
 
    }
71
 
 
72
 
    return TCL_OK;
73
 
}
74
 
 
75
 
/* Update table, use the data previously stored by set_value() */
76
 
int submit(ClientData cdata, Tcl_Interp * interp, int argc, char *argv[])
77
 
{
78
 
    int i, first, ncols, found, col, sqltype, keyval = 0, ret;
79
 
    char buf[2001];
80
 
    dbString sql, table_name, strval;
81
 
    dbDriver *driver;
82
 
    dbHandle handle;
83
 
    dbTable *table;
84
 
    dbColumn *column;
85
 
 
86
 
    G_debug(2, "submit()");
87
 
 
88
 
    db_init_string(&sql);
89
 
    db_init_string(&table_name);
90
 
    db_init_string(&strval);
91
 
 
92
 
    /* Check if all internal values are set */
93
 
    if (Drvname == NULL || Dbname == NULL || Tblname == NULL || Key == NULL) {
94
 
        G_warning("db connection was not set by form");
95
 
        sprintf(buf, "set submit_msg \"db connection was not set by form.\"");
96
 
        Tcl_Eval(interp, buf);
97
 
        Tcl_Eval(interp, "set submit_result 0");
98
 
        return TCL_OK;
99
 
    }
100
 
 
101
 
    /* Get column types */
102
 
    G_debug(2, "Open driver");
103
 
    driver = db_start_driver(Drvname);
104
 
    if (driver == NULL) {
105
 
        G_warning("Cannot open driver");
106
 
        sprintf(buf, "set submit_msg \"Cannot open driver '%s'\"", Drvname);
107
 
        Tcl_Eval(interp, buf);
108
 
        Tcl_Eval(interp, "set submit_result 0");
109
 
        return TCL_OK;
110
 
    }
111
 
    G_debug(2, "Driver opened");
112
 
 
113
 
    db_init_handle(&handle);
114
 
    db_set_handle(&handle, Dbname, NULL);
115
 
    G_debug(2, "Open database");
116
 
    if (db_open_database(driver, &handle) != DB_OK) {
117
 
        G_warning("Cannot open database");
118
 
        db_shutdown_driver(driver);
119
 
        sprintf(buf,
120
 
                "set submit_msg \"Cannot open database '%s' by driver '%s'\"",
121
 
                Dbname, Drvname);
122
 
 
123
 
        Tcl_Eval(interp, buf);
124
 
        Tcl_Eval(interp, "set submit_result 0");
125
 
        return TCL_OK;
126
 
    }
127
 
    G_debug(2, "Database opened");
128
 
 
129
 
    db_set_string(&table_name, Tblname);
130
 
    if (db_describe_table(driver, &table_name, &table) != DB_OK) {
131
 
        G_warning("Cannot describe table");
132
 
        db_shutdown_driver(driver);
133
 
        db_close_database(driver);
134
 
        sprintf(buf, "set submit_msg \"Cannot describe table '%s'\"",
135
 
                Tblname);
136
 
        Tcl_Eval(interp, buf);
137
 
        Tcl_Eval(interp, "set submit_result 0");
138
 
        return TCL_OK;
139
 
    }
140
 
    ncols = db_get_table_number_of_columns(table);
141
 
 
142
 
    /* For each column get ctype */
143
 
    for (i = 0; i < nRows; i++) {
144
 
        found = 0;
145
 
        for (col = 0; col < ncols; col++) {
146
 
            /* get keyval */
147
 
            if (G_strcasecmp(Columns[i].name, Key) == 0) {
148
 
                keyval = atoi(Columns[i].value);
149
 
            }
150
 
            column = db_get_table_column(table, col);
151
 
            if (G_strcasecmp(db_get_column_name(column), Columns[i].name) ==
152
 
                0) {
153
 
                sqltype = db_get_column_sqltype(column);
154
 
                Columns[i].ctype = db_sqltype_to_Ctype(sqltype);
155
 
                found = 1;
156
 
                break;
157
 
            }
158
 
        }
159
 
        if (!found && (G_strcasecmp(Columns[i].name, F_ENCODING) != 0)) {
160
 
            G_warning("Cannot find column type");
161
 
            db_close_database(driver);
162
 
            db_shutdown_driver(driver);
163
 
            sprintf(buf, "set submit_msg \"Cannot find column type\"");
164
 
            Tcl_Eval(interp, buf);
165
 
            Tcl_Eval(interp, "set submit_result 0");
166
 
            return TCL_OK;
167
 
        }
168
 
    }
169
 
 
170
 
    /* Construct update statement */
171
 
    sprintf(buf, "update %s set ", Tblname);
172
 
    db_set_string(&sql, buf);
173
 
 
174
 
    first = 1;
175
 
    for (i = 0; i < nRows; i++) {
176
 
        G_debug(3, "Index = %d of %d Name = %s, Key = %s", i, nRows,
177
 
                Columns[i].name, Key);
178
 
        if (G_strcasecmp(Columns[i].name, Key) == 0)
179
 
            continue;
180
 
 
181
 
        if (G_strcasecmp(Columns[i].name, F_ENCODING) == 0) {
182
 
 
183
 
            G_debug(3, "GRASS_DB_ENCODING env-var is '%s', col val is '%s'",
184
 
                    G__getenv("GRASS_DB_ENCODING"), Columns[i].value);
185
 
 
186
 
            if ((strlen(Columns[i].value) == 0) ||
187
 
                G_strcasecmp(Columns[i].value,
188
 
                             G__getenv("GRASS_DB_ENCODING")) == 0)
189
 
                continue;
190
 
            else {
191
 
                G_setenv("GRASS_DB_ENCODING", Columns[i].value);
192
 
                G_debug(3, "Set env var GRASS_DB_ENCODING to '%s'",
193
 
                        Columns[i].value);
194
 
                if (Tcl_SetSystemEncoding(interp, Columns[i].value) ==
195
 
                    TCL_ERROR) {
196
 
                    G_warning
197
 
                        ("Could not set Tcl system encoding to '%s' (%s)",
198
 
                         Columns[i].value, Tcl_GetStringResult(interp));
199
 
                }
200
 
            }
201
 
            continue;
202
 
        }
203
 
 
204
 
        if (!first) {
205
 
            db_append_string(&sql, ", ");
206
 
        }
207
 
        if (strlen(Columns[i].value) == 0) {
208
 
            sprintf(buf, "%s = null", Columns[i].name);
209
 
        }
210
 
        else {
211
 
            if (Columns[i].ctype == DB_C_TYPE_INT ||
212
 
                Columns[i].ctype == DB_C_TYPE_DOUBLE) {
213
 
                sprintf(buf, "%s = %s", Columns[i].name, Columns[i].value);
214
 
            }
215
 
            else {
216
 
                memset(buf, '\0', strlen(buf));
217
 
                ret = Tcl_UtfToExternal(interp,
218
 
                                        Tcl_GetEncoding(interp,
219
 
                                                        G__getenv
220
 
                                                        ("GRASS_DB_ENCODING")),
221
 
                                        Columns[i].value,
222
 
                                        strlen(Columns[i].value), 0, NULL,
223
 
                                        buf, 2000, NULL, NULL, NULL);
224
 
 
225
 
                if (ret != TCL_OK) {
226
 
                    G_warning("Could not convert UTF to external.");
227
 
                    db_set_string(&strval, Columns[i].value);
228
 
                }
229
 
                else {
230
 
                    db_set_string(&strval, buf);
231
 
                }
232
 
 
233
 
                db_double_quote_string(&strval);
234
 
                sprintf(buf, "%s = '%s'", Columns[i].name,
235
 
                        db_get_string(&strval));
236
 
            }
237
 
        }
238
 
        db_append_string(&sql, buf);
239
 
        first = 0;
240
 
    }
241
 
 
242
 
    sprintf(buf, " where %s = %d", Key, keyval);
243
 
    db_append_string(&sql, buf);
244
 
 
245
 
    G_debug(2, "SQL: %s", db_get_string(&sql));
246
 
 
247
 
    /* Update table */
248
 
    ret = db_execute_immediate(driver, &sql);
249
 
 
250
 
    db_close_database(driver);
251
 
    db_shutdown_driver(driver);
252
 
 
253
 
    if (ret != DB_OK) {
254
 
        G_warning("Cannot update table");
255
 
        Tcl_VarEval(interp, "set submit_msg \"Cannot update table:\n",
256
 
                    db_get_error_msg(), "\"", NULL);
257
 
        Tcl_Eval(interp, "set submit_result 0");
258
 
    }
259
 
    else {
260
 
        Tcl_Eval(interp, "set submit_msg \"Record successfully updated\"");
261
 
        Tcl_Eval(interp, "set submit_result 1");
262
 
    }
263
 
 
264
 
    return TCL_OK;
265
 
}
266
 
 
267
 
/* 
268
 
 *  Form 
269
 
 */
270
 
int Tcl_AppInit(Tcl_Interp * interp)
271
 
{
272
 
    if (Tcl_Init(interp) == TCL_ERROR)
273
 
        return TCL_ERROR;
274
 
 
275
 
    if (Tk_Init(interp) == TCL_ERROR)
276
 
        return TCL_ERROR;
277
 
 
278
 
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
279
 
 
280
 
    /*
281
 
     * Call Tcl_CreateCommand for application-specific commands, if
282
 
     * they weren't already created by the init procedures called above.
283
 
     */
284
 
 
285
 
    Tcl_CreateCommand(interp, "submit", (Tcl_CmdProc *) submit,
286
 
                      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
287
 
    Tcl_CreateCommand(interp, "set_value",
288
 
                      (Tcl_CmdProc *) set_value,
289
 
                      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
290
 
    Tcl_CreateCommand(interp, "reset_values",
291
 
                      (Tcl_CmdProc *) reset_values,
292
 
                      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
293
 
    /*
294
 
     * Specify a user-specific startup file to invoke if the application
295
 
     * is run interactively.  Typically the startup file is "~/.apprc"
296
 
     * where "app" is the name of the application.  If this line is deleted
297
 
     * then no user-specific startup file will be run under any conditions.
298
 
     */
299
 
 
300
 
    Tcl_SetVar(interp, "tcl_rcFileName", "~/.grassformrc", TCL_GLOBAL_ONLY);
301
 
    return TCL_OK;
302
 
}
303
 
 
304
 
int main(int argc, char *argv[])
305
 
{
306
 
    G_gisinit("form");
307
 
    G_debug(2, "Form: main()");
308
 
 
309
 
    Tk_Main(argc, argv, Tcl_AppInit);
310
 
    return 0;
311
 
}