execute.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*!
  2. \file db/drivers/execute.c
  3. \brief Low level OGR SQL driver
  4. (C) 2011 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Martin Landa <landa.martin gmail.com> (2011/07)
  8. */
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <grass/gis.h>
  12. #include <grass/dbmi.h>
  13. #include <grass/glocale.h>
  14. #include <ogr_api.h>
  15. #include <cpl_error.h>
  16. #include "globals.h"
  17. #include "proto.h"
  18. static int parse_sql_update(const char *, char **, column_info **, int *, char **);
  19. int db__driver_execute_immediate(dbString * sql)
  20. {
  21. char *where, *table;
  22. int res, ncols, i;
  23. column_info *cols;
  24. OGRLayerH hLayer;
  25. OGRFeatureH hFeature;
  26. OGRFeatureDefnH hFeatureDefn;
  27. OGRFieldDefnH hFieldDefn;
  28. G_debug(1, "db__driver_execute_immediate():");
  29. G_debug(3, "\tSQL: '%s'", db_get_string(sql));
  30. /* try RDBMS SQL */
  31. OGR_DS_ExecuteSQL(hDs, db_get_string(sql), NULL, NULL);
  32. if (CPLGetLastErrorType() == CE_None)
  33. return DB_OK;
  34. /* parse UPDATE statement */
  35. res = parse_sql_update(db_get_string(sql), &table, &cols, &ncols, &where);
  36. G_debug(3, "\tUPDATE: table=%s, where=%s, ncols=%d", table, where ? where : "", ncols);
  37. if (res != 0)
  38. return DB_FAILED;
  39. /* get OGR layer */
  40. hLayer = OGR_DS_GetLayerByName(hDs, table);
  41. if (!hLayer) {
  42. db_d_append_error(_("OGR layer <%s> not found"), table);
  43. db_d_report_error();
  44. return DB_FAILED;
  45. }
  46. if (where)
  47. OGR_L_SetAttributeFilter(hLayer, where);
  48. /* get columns info */
  49. hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
  50. for (i = 0; i < ncols; i++) {
  51. cols[i].index = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].name);
  52. if (cols[i].index < 0) {
  53. db_d_append_error(_("Column <%s> not found in table <%s>"),
  54. cols[i].name, table);
  55. db_d_report_error();
  56. return DB_FAILED;
  57. }
  58. cols[i].qindex = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].value);
  59. hFieldDefn = OGR_FD_GetFieldDefn(hFeatureDefn, cols[i].index);
  60. cols[i].type = OGR_Fld_GetType(hFieldDefn);
  61. G_debug(3, "\t\tcol=%s, val=%s, idx=%d, type=%d, qidx=%d",
  62. cols[i].name, cols[i].value, cols[i].index, cols[i].type,
  63. cols[i].qindex);
  64. }
  65. /* update features */
  66. OGR_L_ResetReading(hLayer);
  67. while(TRUE) {
  68. char *value;
  69. hFeature = OGR_L_GetNextFeature(hLayer);
  70. if (!hFeature)
  71. break;
  72. G_debug(5, "\tfid=%ld", OGR_F_GetFID(hFeature));
  73. for (i = 0; i < ncols; i++) {
  74. if (cols[i].qindex > -1) {
  75. value = (char *)OGR_F_GetFieldAsString(hFeature, cols[i].qindex);
  76. }
  77. else {
  78. if ((cols[i].type != OFTInteger ||
  79. cols[i].type != OFTReal) && *(cols[i].value) == '\'') {
  80. value = G_strchg(cols[i].value, '\'', ' ');
  81. G_strip(value);
  82. }
  83. else {
  84. value = cols[i].value;
  85. }
  86. }
  87. OGR_F_SetFieldString(hFeature, cols[i].index, value);
  88. }
  89. OGR_L_SetFeature(hLayer, hFeature);
  90. OGR_F_Destroy(hFeature);
  91. }
  92. G_free(table);
  93. G_free(where);
  94. for (i = 0; i < ncols; i++) {
  95. G_free(cols[i].name);
  96. G_free(cols[i].value);
  97. }
  98. return DB_OK;
  99. }
  100. int parse_sql_update(const char *sql, char **table, column_info **cols, int *ncols, char **where)
  101. {
  102. int nprefix, n;
  103. int has_where;
  104. char *prefix;
  105. char *p, *w, *c, *t;
  106. char **token, **itoken;
  107. prefix = "UPDATE";
  108. nprefix = strlen(prefix);
  109. if (G_strncasecmp(sql, prefix, nprefix) != 0)
  110. return 1;
  111. p = (char *) sql + nprefix; /* skip 'UPDATE' */
  112. if (*p != ' ')
  113. return 1;
  114. p++;
  115. /* table */
  116. t = strchr(p, ' ');
  117. n = t - p;
  118. *table = G_malloc(n + 1);
  119. strncpy(*table, p, n);
  120. (*table)[n] = '\0';
  121. G_strip(*table);
  122. p += n;
  123. if (*p != ' ')
  124. return 1;
  125. p++;
  126. if (G_strncasecmp(p, "SET", 3) != 0)
  127. return 1;
  128. p += 3; /* skip 'SET' */
  129. if (*p != ' ')
  130. return 1;
  131. p++;
  132. w = G_strcasestr(p, "WHERE");
  133. if (!w) {
  134. has_where = FALSE;
  135. w = (char *)sql + strlen(sql);
  136. }
  137. else {
  138. has_where = TRUE;
  139. }
  140. /* process columns & values */
  141. n = w - p;
  142. c = G_malloc(n + 1);
  143. strncpy(c, p, n);
  144. c[n] = '\0';
  145. token = G_tokenize2(c, ",", "'");
  146. *ncols = G_number_of_tokens(token);
  147. *cols = (column_info *)G_malloc(sizeof(column_info) * (*ncols));
  148. for (n = 0; n < (*ncols); n++) {
  149. itoken = G_tokenize(token[n], "=");
  150. if (G_number_of_tokens(itoken) != 2)
  151. return FALSE;
  152. G_strip(itoken[0]);
  153. G_strip(itoken[1]);
  154. (*cols)[n].name = G_store(itoken[0]);
  155. (*cols)[n].value = G_store(itoken[1]);
  156. G_free_tokens(itoken);
  157. }
  158. G_free_tokens(token);
  159. G_free(c);
  160. if (!has_where) {
  161. *where = NULL;
  162. return 0;
  163. }
  164. /* where */
  165. w += strlen("WHERE");
  166. if (*w != ' ')
  167. return 1;
  168. w++;
  169. G_strip(w);
  170. *where = G_store(w);
  171. return 0;
  172. }