generate.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <grass/gis.h>
  4. #include <grass/dbmi.h>
  5. #include <grass/form.h>
  6. /* Generate form in HTML/TXT format.
  7. * Pointer to resulting string is stored to 'form'. This string must be freed by application.
  8. *
  9. * returns: -1 error
  10. * 0 success
  11. */
  12. int
  13. F_generate(char *drvname, char *dbname, char *tblname, char *key, int keyval,
  14. char *frmname, char *frmmapset,
  15. int edit_mode, int format, char **form)
  16. {
  17. int col, ncols, ctype, sqltype, more;
  18. char buf[5000], buf1[100];
  19. const char *colname;
  20. dbString sql, html, str;
  21. dbDriver *driver;
  22. dbHandle handle;
  23. dbCursor cursor;
  24. dbTable *table;
  25. dbColumn *column;
  26. dbValue *value;
  27. int i = 0;
  28. /* see /usr/lib/tcl8.4/encoding/ */
  29. static char *encoding_list[] = {
  30. "utf-8",
  31. "ascii",
  32. "iso8859-1",
  33. "iso8859-2",
  34. "iso8859-15",
  35. "iso2022-jp",
  36. "koi8-r",
  37. "euc-jp",
  38. NULL
  39. };
  40. const char *enc_env;
  41. G__read_env();
  42. enc_env = G__getenv("GRASS_DB_ENCODING");
  43. /* TODO: support 'format' (txt, html), currently html only */
  44. G_debug(2,
  45. "F_generate(): drvname = '%s', dbname = '%s'\n tblname = '%s', key = '%s', keyval = %d\n"
  46. " form = '%s', form_mapset = '%s'\n edit_mode = %d",
  47. drvname, dbname, tblname, key, keyval, frmname, frmmapset,
  48. edit_mode);
  49. db_init_string(&sql);
  50. db_init_string(&html); /* here is the result stored */
  51. db_init_string(&str);
  52. G_debug(2, "Open driver");
  53. driver = db_start_driver(drvname);
  54. if (driver == NULL) {
  55. G_warning("Cannot open driver\n");
  56. sprintf(buf, "Cannot open driver '%s'<BR>", drvname);
  57. *form = G_store(buf);
  58. return -1;
  59. }
  60. G_debug(2, "Driver opened");
  61. db_init_handle(&handle);
  62. db_set_handle(&handle, dbname, NULL);
  63. G_debug(2, "Open database");
  64. if (db_open_database(driver, &handle) != DB_OK) {
  65. G_warning("Cannot open database\n");
  66. db_shutdown_driver(driver);
  67. sprintf(buf, "Cannot open database '%s' by driver '%s'<BR>", dbname,
  68. drvname);
  69. *form = G_store(buf);
  70. return -1;
  71. }
  72. G_debug(2, "Database opened");
  73. /* TODO: test if table exist first, but this should be tested by application befor
  74. * F_generate() is called, because it may be correct (connection defined in DB
  75. * but table does not exist) */
  76. sprintf(buf, "select * from %s where %s = %d", tblname, key, keyval);
  77. G_debug(2, "%s", buf);
  78. db_set_string(&sql, buf);
  79. if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
  80. G_warning("Cannot open select cursor\n");
  81. db_close_database(driver);
  82. db_shutdown_driver(driver);
  83. sprintf(buf,
  84. "Cannot open select cursor:<BR>'%s'<BR>on database '%s' by driver '%s'<BR>",
  85. db_get_string(&sql), dbname, drvname);
  86. *form = G_store(buf);
  87. return -1;
  88. }
  89. G_debug(2, "Select Cursor opened");
  90. table = db_get_cursor_table(&cursor);
  91. if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
  92. G_warning("Cannot fetch next record\n");
  93. db_close_cursor(&cursor);
  94. db_close_database(driver);
  95. db_shutdown_driver(driver);
  96. *form = G_store("Cannot fetch next record");
  97. return -1;
  98. }
  99. if (!more) {
  100. G_warning("No database record");
  101. if (format == F_HTML) {
  102. *form = G_store("No record selected.<BR>");
  103. }
  104. else {
  105. *form = G_store("No record selected.");
  106. }
  107. }
  108. else {
  109. ncols = db_get_table_number_of_columns(table);
  110. /* Start form */
  111. if (format == F_HTML) {
  112. if (edit_mode == F_EDIT) {
  113. db_append_string(&html, "<FORM>");
  114. sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
  115. F_DRIVER_FNAME, drvname);
  116. db_append_string(&html, buf);
  117. /* Note: because html_library.tcl failes to parse
  118. * <INPUT name=abc value='dbname=xxx'> and returnes
  119. * name="xxx" value="dbname=xxx" order of value and name parameters is changed */
  120. sprintf(buf, "<INPUT type=hidden value=\"%s\" name=%s>",
  121. dbname, F_DATABASE_FNAME);
  122. db_append_string(&html, buf);
  123. sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
  124. F_TABLE_FNAME, tblname);
  125. db_append_string(&html, buf);
  126. sprintf(buf, "<INPUT type=hidden name=%s value=\"%s\">",
  127. F_KEY_FNAME, key);
  128. db_append_string(&html, buf);
  129. }
  130. for (col = 0; col < ncols; col++) {
  131. column = db_get_table_column(table, col);
  132. sqltype = db_get_column_sqltype(column);
  133. ctype = db_sqltype_to_Ctype(sqltype);
  134. value = db_get_column_value(column);
  135. db_convert_value_to_string(value, sqltype, &str);
  136. colname = db_get_column_name(column);
  137. G_debug(2, "%s: %s", colname, db_get_string(&str));
  138. if (edit_mode == F_VIEW) {
  139. sprintf(buf, "<B>%s : </B> %s <BR>", colname,
  140. db_get_string(&str));
  141. db_append_string(&html, buf);
  142. }
  143. else {
  144. sprintf(buf, "<B>%s : </B>", colname);
  145. db_append_string(&html, buf);
  146. if (G_strcasecmp(colname, key) == 0) {
  147. sprintf(buf,
  148. "%s<BR> <INPUT type=hidden name=%s value=\"%s\">",
  149. db_get_string(&str), colname,
  150. db_get_string(&str));
  151. }
  152. else {
  153. switch (ctype) {
  154. case DB_C_TYPE_INT:
  155. sprintf(buf1, "20");
  156. break;
  157. case DB_C_TYPE_DOUBLE:
  158. sprintf(buf1, "30");
  159. break;
  160. case DB_C_TYPE_STRING:
  161. sprintf(buf1, "%d", db_get_column_length(column));
  162. break;
  163. case DB_C_TYPE_DATETIME:
  164. sprintf(buf1, "20");
  165. break;
  166. }
  167. sprintf(buf,
  168. "<INPUT type=text size=%s name=%s value=\"%s\"><BR>",
  169. buf1, colname, db_get_string(&str));
  170. }
  171. db_append_string(&html, buf);
  172. }
  173. }
  174. if (edit_mode == F_EDIT) {
  175. sprintf(buf,
  176. "<HR> Assume data encoding as:<BR><BR><SELECT NAME=%s SIZE=4><HR><BR>",
  177. F_ENCODING);
  178. db_append_string(&html, buf);
  179. i = 0;
  180. while (encoding_list[i] != NULL) {
  181. if (G_strcasecmp(encoding_list[i], enc_env) == 0)
  182. sprintf(buf, "<OPTION VALUE=\"%s\" SELECTED>%s",
  183. encoding_list[i], encoding_list[i]);
  184. else
  185. sprintf(buf, "<OPTION VALUE=\"%s\">%s",
  186. encoding_list[i], encoding_list[i]);
  187. ++i;
  188. db_append_string(&html, buf);
  189. }
  190. sprintf(buf, "</SELECT>");
  191. db_append_string(&html, buf);
  192. }
  193. /* Close form */
  194. if (edit_mode == F_EDIT) {
  195. db_append_string(&html, "</FORM>");
  196. }
  197. }
  198. else { /* F_TXT */
  199. for (col = 0; col < ncols; col++) {
  200. column = db_get_table_column(table, col);
  201. sqltype = db_get_column_sqltype(column);
  202. ctype = db_sqltype_to_Ctype(sqltype);
  203. value = db_get_column_value(column);
  204. db_convert_value_to_string(value, sqltype, &str);
  205. colname = db_get_column_name(column);
  206. G_debug(2, "%s: %s", colname, db_get_string(&str));
  207. sprintf(buf, "%s : %s\n", colname, db_get_string(&str));
  208. db_append_string(&html, buf);
  209. }
  210. }
  211. }
  212. G_debug(2, "FORM STRING:\n%s\n", db_get_string(&html));
  213. db_close_cursor(&cursor);
  214. db_close_database(driver);
  215. db_shutdown_driver(driver);
  216. *form = G_store(db_get_string(&html));
  217. db_free_string(&sql);
  218. db_free_string(&html);
  219. db_free_string(&str);
  220. return 0;
  221. }