GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
generate.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <grass/gis.h>
4 #include <grass/dbmi.h>
5 #include <grass/form.h>
6 
7 /* Escape string for use in TCL */
8 char *escape_tcl_string(char *input)
9 {
10  char *escaped;
11 
12  escaped = G_str_replace(input, "\\", "\\\\");
13  escaped = G_str_replace(escaped, "[", "\\[");
14  escaped = G_str_replace(escaped, "]", "\\]");
15  escaped = G_str_replace(escaped, "$", "\\$");
16 
17  return escaped;
18 }
19 
20 /* Generate form in HTML/TXT format.
21  * Pointer to resulting string is stored to 'form'. This string must be freed by application.
22  *
23  * returns: -1 error
24  * 0 success
25  */
26 int
27 F_generate(char *drvname, char *dbname, char *tblname, char *key, int keyval,
28  char *frmname, char *frmmapset,
29  int edit_mode, int format, char **form)
30 {
31  int col, ncols, ctype, sqltype, more;
32  char buf[5000], buf1[100];
33  const char *colname;
34  dbString sql, html, str;
35  dbDriver *driver;
36  dbHandle handle;
37  dbCursor cursor;
38  dbTable *table;
39  dbColumn *column;
40  dbValue *value;
41 
42  int i = 0;
43 
44  /* see /usr/lib/tcl8.4/encoding/ */
45  static char *encoding_list[] = {
46  "utf-8",
47  "ascii",
48  "iso8859-1",
49  "iso8859-2",
50  "iso8859-15",
51  "iso2022-jp",
52  "koi8-r",
53  "euc-jp",
54  NULL
55  };
56  char *enc_env;
57 
58  G__read_env();
59  enc_env = G__getenv("GRASS_DB_ENCODING");
60 
61  /* TODO: support 'format' (txt, html), currently html only */
62 
63  G_debug(2,
64  "F_generate(): drvname = '%s', dbname = '%s'\n tblname = '%s', key = '%s', keyval = %d\n"
65  " form = '%s', form_mapset = '%s'\n edit_mode = %d",
66  drvname, dbname, tblname, key, keyval, frmname, frmmapset,
67  edit_mode);
68 
69  db_init_string(&sql);
70  db_init_string(&html); /* here is the result stored */
71  db_init_string(&str);
72 
73  G_debug(2, "Open driver");
74  driver = db_start_driver(drvname);
75  if (driver == NULL) {
76  G_warning("Cannot open driver");
77  sprintf(buf, "Cannot open driver '%s'<BR>",
78  escape_tcl_string(drvname));
79  *form = G_store(buf);
80  return -1;
81  }
82  G_debug(2, "Driver opened");
83 
84  db_init_handle(&handle);
85  db_set_handle(&handle, dbname, NULL);
86  G_debug(2, "Open database");
87  if (db_open_database(driver, &handle) != DB_OK) {
88  G_warning("Cannot open database");
89  db_shutdown_driver(driver);
90  sprintf(buf, "Cannot open database '%s' by driver '%s'<BR>",
91  escape_tcl_string(dbname), escape_tcl_string(drvname));
92  *form = G_store(buf);
93  return -1;
94  }
95  G_debug(2, "Database opened");
96 
97  /* TODO: test if table exist first, but this should be tested by application befor
98  * F_generate() is called, because it may be correct (connection defined in DB
99  * but table does not exist) */
100 
101  sprintf(buf, "select * from %s where %s = %d", tblname, key, keyval);
102  G_debug(2, "%s", buf);
103  db_set_string(&sql, buf);
104  if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
105  G_warning("Cannot open select cursor");
106  db_close_database(driver);
107  db_shutdown_driver(driver);
108  sprintf(buf,
109  "Cannot open select cursor:<BR>'%s'<BR>on database '%s' by driver '%s'<BR>",
111  escape_tcl_string(dbname), escape_tcl_string(drvname));
112  *form = G_store(buf);
113  return -1;
114  }
115  G_debug(2, "Select Cursor opened");
116 
117  table = db_get_cursor_table(&cursor);
118 
119  if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
120  G_warning("Cannot fetch next record");
121  db_close_cursor(&cursor);
122  db_close_database(driver);
123  db_shutdown_driver(driver);
124  *form = G_store("Cannot fetch next record");
125  return -1;
126  }
127 
128  if (!more) {
129  G_warning("No database record");
130  if (format == F_HTML) {
131  *form = G_store("No record selected.<BR>");
132  }
133  else {
134  *form = G_store("No record selected.");
135  }
136  }
137  else {
138  ncols = db_get_table_number_of_columns(table);
139 
140  /* Start form */
141  if (format == F_HTML) {
142  if (edit_mode == F_EDIT) {
143  db_append_string(&html, "<FORM>");
144 
145  sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
146  escape_tcl_string(F_DRIVER_FNAME),
147  escape_tcl_string(drvname));
148  db_append_string(&html, buf);
149  /* Note: because html_library.tcl failes to parse
150  * <INPUT name=abc value='dbname=xxx'> and returnes
151  * name="xxx" value="dbname=xxx" order of value and name parameters is changed */
152  sprintf(buf, "<INPUT type=hidden value=\"%s\" name=%s>",
153  escape_tcl_string(dbname),
154  escape_tcl_string(F_DATABASE_FNAME));
155  db_append_string(&html, buf);
156  sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
157  escape_tcl_string(F_TABLE_FNAME),
158  escape_tcl_string(tblname));
159  db_append_string(&html, buf);
160  sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
161  escape_tcl_string(F_KEY_FNAME),
162  escape_tcl_string(key));
163  db_append_string(&html, buf);
164 
165  }
166 
167  for (col = 0; col < ncols; col++) {
168  column = db_get_table_column(table, col);
169  sqltype = db_get_column_sqltype(column);
170  ctype = db_sqltype_to_Ctype(sqltype);
171  value = db_get_column_value(column);
172  db_convert_value_to_string(value, sqltype, &str);
173  colname = db_get_column_name(column);
174 
175  G_debug(2, "%s: %s", colname, db_get_string(&str));
176 
177  if (edit_mode == F_VIEW) {
178  sprintf(buf, "<B>%s : </B> %s <BR>",
179  escape_tcl_string(G_strdup(colname)),
181  db_append_string(&html, buf);
182  }
183  else {
184  sprintf(buf, "<B>%s : </B>",
185  escape_tcl_string(G_strdup(colname)));
186  db_append_string(&html, buf);
187 
188  if (G_strcasecmp(colname, key) == 0) {
189  sprintf(buf,
190  "%s<BR> <INPUT type=hidden name=%s value=\"%s\">",
192  escape_tcl_string(G_strdup(colname)),
194  }
195  else {
196  switch (ctype) {
197  case DB_C_TYPE_INT:
198  sprintf(buf1, "20");
199  break;
200  case DB_C_TYPE_DOUBLE:
201  sprintf(buf1, "30");
202  break;
203  case DB_C_TYPE_STRING:
204  sprintf(buf1, "%d", db_get_column_length(column));
205  break;
206  case DB_C_TYPE_DATETIME:
207  sprintf(buf1, "20");
208  break;
209  }
210  sprintf(buf,
211  "<INPUT type=text size=%s name=%s value=\"%s\"><BR>",
212  escape_tcl_string(buf1),
213  escape_tcl_string(G_strdup(colname)),
215  }
216  db_append_string(&html, buf);
217  }
218  }
219 
220  if (edit_mode == F_EDIT) {
221  sprintf(buf,
222  "<HR> Assume data encoding as:<BR><BR><SELECT NAME=%s SIZE=4><HR><BR>",
223  F_ENCODING);
224  db_append_string(&html, buf);
225 
226  i = 0;
227  while (encoding_list[i] != NULL) {
228 
229  if (G_strcasecmp(encoding_list[i], enc_env) == 0)
230  sprintf(buf, "<OPTION VALUE=\"%s\" SELECTED>%s",
231  encoding_list[i], encoding_list[i]);
232  else
233  sprintf(buf, "<OPTION VALUE=\"%s\">%s",
234  encoding_list[i], encoding_list[i]);
235  ++i;
236  db_append_string(&html, buf);
237  }
238 
239  sprintf(buf, "</SELECT>");
240  db_append_string(&html, buf);
241  }
242 
243  /* Close form */
244  if (edit_mode == F_EDIT) {
245  db_append_string(&html, "</FORM>");
246  }
247  }
248  else { /* F_TXT */
249  for (col = 0; col < ncols; col++) {
250  column = db_get_table_column(table, col);
251  sqltype = db_get_column_sqltype(column);
252  ctype = db_sqltype_to_Ctype(sqltype);
253  value = db_get_column_value(column);
254  db_convert_value_to_string(value, sqltype, &str);
255  colname = db_get_column_name(column);
256 
257  G_debug(2, "%s: %s", colname, db_get_string(&str));
258 
259  sprintf(buf, "%s : %s\n", colname, db_get_string(&str));
260  db_append_string(&html, buf);
261  }
262  }
263  }
264  G_debug(2, "FORM STRING:\n%s\n", db_get_string(&html));
265 
266  db_close_cursor(&cursor);
267  db_close_database(driver);
268  db_shutdown_driver(driver);
269 
270  *form = G_store(db_get_string(&html));
271 
272  db_free_string(&sql);
273  db_free_string(&html);
274  db_free_string(&str);
275 
276  return 0;
277 }
dbColumn * db_get_table_column(dbTable *table, int n)
returns column structure for given table and column number
int F_generate(char *drvname, char *dbname, char *tblname, char *key, int keyval, char *frmname, char *frmmapset, int edit_mode, int format, char **form)
Definition: generate.c:27
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:192
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
int db_close_cursor(dbCursor *cursor)
Close cursor.
Definition: c_close_cur.c:27
struct driver * driver
Definition: driver/init.c:26
char * G__getenv(const char *name)
Get environment variable.
Definition: env.c:312
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
const char * db_get_column_name(dbColumn *column)
returns column name for given column
int db_shutdown_driver(dbDriver *driver)
Closedown the driver, and free the driver structure.
Definition: shutdown.c:36
int db_close_database(dbDriver *driver)
Close database connection.
Definition: c_closedb.c:26
char * G_strdup(const char *string)
Copies the null-terminated string into a newly allocated string. The string is allocated using G_mall...
Definition: strings.c:265
int db_get_column_length(dbColumn *column)
int db_convert_value_to_string(dbValue *value, int sqltype, dbString *string)
Definition: valuefmt.c:47
int db_append_string(dbString *x, const char *s)
Definition: string.c:193
int db_sqltype_to_Ctype(int sqltype)
Definition: sqlCtype.c:9
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data.
Definition: c_fetch.c:28
dbTable * db_get_cursor_table(dbCursor *cursor)
Definition: cursor.c:55
int db_get_column_sqltype(dbColumn *column)
returns column sqltype for column (the function db_sqltype_name() returns sqltype description) ...
char * G_str_replace(char *buffer, const char *old_str, const char *new_str)
Replace all occurencies of old_str in buffer with new_str.
Definition: strings.c:316
int db_get_table_number_of_columns(dbTable *table)
dbValue * db_get_column_value(dbColumn *column)
returns column value for given column structure
char * value
Definition: env.c:30
int db_set_handle(dbHandle *handle, const char *dbName, const char *dbSchema)
Definition: handle.c:22
char * escape_tcl_string(char *input)
Definition: generate.c:8
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
char * db_get_string(dbString *x)
Definition: string.c:131
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void db_init_handle(dbHandle *handle)
Definition: handle.c:10
int db_set_string(dbString *x, const char *s)
Definition: string.c:33
int db_open_database(dbDriver *driver, dbHandle *handle)
Open database connection.
Definition: c_opendb.c:27
void db_free_string(dbString *x)
Definition: string.c:142
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition: start.c:43
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
Definition: c_openselect.c:29
void db_init_string(dbString *x)
Definition: string.c:11
int G__read_env(void)
Initialize init array for G_VAR_GISRC.
Definition: env.c:495