update.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <grass/dbmi.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. static int srch();
  7. int update(struct Map_info *Map)
  8. {
  9. int i, *catexst, *cex, upd, fcat;
  10. char buf1[2000], buf2[2000], left[20], right[20];
  11. struct field_info *qFi, *Fi;
  12. dbString stmt;
  13. dbDriver *driver;
  14. vstat.dupl = 0;
  15. vstat.exist = 0;
  16. vstat.notexist = 0;
  17. vstat.update = 0;
  18. vstat.error = 0;
  19. db_init_string(&stmt);
  20. /* layer to find table to read from */
  21. qFi = Vect_get_field(Map, options.qfield);
  22. if (options.option == O_QUERY && qFi == NULL)
  23. G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
  24. options.qfield);
  25. /* layer to find table to write to */
  26. if ((Fi = Vect_get_field(Map, options.field)) == NULL)
  27. G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
  28. options.field);
  29. if (qFi) {
  30. G_debug(3, "Reading from map <%s>, query layer %d (table <%s>): updating table <%s>, column <%s>",
  31. options.name, options.qfield, qFi->table, Fi->table, Fi->key);
  32. }
  33. else {
  34. G_debug(3, "Reading from map <%s>, updating table <%s>, column <%s>",
  35. options.name, Fi->table, Fi->key);
  36. }
  37. /* Open driver */
  38. driver = db_start_driver_open_database(Fi->driver, Fi->database);
  39. if (driver == NULL) {
  40. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  41. Fi->database, Fi->driver);
  42. }
  43. db_set_error_handler_driver(driver);
  44. db_begin_transaction(driver);
  45. /* select existing categories (layer) to array (array is sorted) */
  46. vstat.select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
  47. G_debug(3, "Existing categories: %d", vstat.select);
  48. /* create beginning of stmt */
  49. switch (options.option) {
  50. case O_CAT:
  51. sprintf(buf1, "insert into %s ( %s ) values ", Fi->table, Fi->key);
  52. break;
  53. case O_COUNT:
  54. case O_LENGTH:
  55. case O_AREA:
  56. case O_QUERY:
  57. case O_COMPACT:
  58. case O_FD:
  59. case O_PERIMETER:
  60. case O_SLOPE:
  61. case O_SINUOUS:
  62. case O_AZIMUTH:
  63. sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
  64. break;
  65. case O_COOR:
  66. case O_START:
  67. case O_END:
  68. case O_SIDES:
  69. sprintf(buf1, "update %s set ", Fi->table);
  70. break;
  71. }
  72. /* update */
  73. G_message(_("Updating database..."));
  74. for (i = 0; i < vstat.rcat; i++) {
  75. G_percent(i, vstat.rcat, 2);
  76. fcat = Values[i].cat;
  77. if (fcat < 0)
  78. continue;
  79. switch (options.option) {
  80. case O_CAT:
  81. sprintf(buf2, "%s ( %d )", buf1, Values[i].cat);
  82. break;
  83. case O_COUNT:
  84. sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].count1,
  85. Fi->key, Values[i].cat);
  86. break;
  87. case O_LENGTH:
  88. case O_AREA:
  89. case O_COMPACT:
  90. case O_FD:
  91. case O_PERIMETER:
  92. case O_SLOPE:
  93. case O_SINUOUS:
  94. case O_AZIMUTH:
  95. sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
  96. Values[i].cat);
  97. break;
  98. case O_COOR:
  99. case O_START:
  100. case O_END:
  101. if (Values[i].count1 > 1) {
  102. G_warning(_("More elements of category %d, nothing loaded to database"),
  103. Values[i].cat);
  104. vstat.dupl++;
  105. continue;
  106. }
  107. if (Values[i].count1 < 1) { /* No points */
  108. continue;
  109. }
  110. if (options.col[2]) {
  111. sprintf(buf2,
  112. "%s %s = %.15g, %s = %.15g, %s = %.15g where %s = %d",
  113. buf1, options.col[0], Values[i].d1, options.col[1],
  114. Values[i].d2, options.col[2], Values[i].d3, Fi->key,
  115. Values[i].cat);
  116. }
  117. else {
  118. sprintf(buf2, "%s %s = %.15g, %s = %.15g where %s = %d",
  119. buf1, options.col[0], Values[i].d1, options.col[1],
  120. Values[i].d2, Fi->key, Values[i].cat);
  121. }
  122. break;
  123. case O_SIDES:
  124. if (Values[i].count1 == 1) {
  125. if (Values[i].i1 >= 0)
  126. sprintf(left, "%d", Values[i].i1);
  127. else
  128. sprintf(left, "-1"); /* NULL, no area/cat */
  129. }
  130. else if (Values[i].count1 > 1) {
  131. sprintf(left, "null");
  132. }
  133. else { /* Values[i].count1 == 0 */
  134. /* It can be OK if the category is assigned to an element
  135. type which is not GV_BOUNDARY */
  136. /* -> TODO: print only if there is boundary with that cat */
  137. sprintf(left, "null");
  138. }
  139. if (Values[i].count2 == 1) {
  140. if (Values[i].i2 >= 0)
  141. sprintf(right, "%d", Values[i].i2);
  142. else
  143. sprintf(right, "-1"); /* NULL, no area/cat */
  144. }
  145. else if (Values[i].count2 > 1) {
  146. sprintf(right, "null");
  147. }
  148. else { /* Values[i].count1 == 0 */
  149. sprintf(right, "null");
  150. }
  151. sprintf(buf2, "%s %s = %s, %s = %s where %s = %d", buf1,
  152. options.col[0], left, options.col[1], right, Fi->key,
  153. Values[i].cat);
  154. break;
  155. case O_QUERY:
  156. if (Values[i].null) {
  157. sprintf(buf2, "%s null where %s = %d", buf1, Fi->key,
  158. Values[i].cat);
  159. }
  160. else {
  161. switch (vstat.qtype) {
  162. case (DB_C_TYPE_INT):
  163. sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].i1,
  164. Fi->key, Values[i].cat);
  165. break;
  166. case (DB_C_TYPE_DOUBLE):
  167. sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1,
  168. Fi->key, Values[i].cat);
  169. break;
  170. case (DB_C_TYPE_STRING):
  171. sprintf(buf2, "%s '%s' where %s = %d", buf1,
  172. Values[i].str1, Fi->key, Values[i].cat);
  173. break;
  174. case (DB_C_TYPE_DATETIME):
  175. sprintf(buf2, "%s '%s' where %s = %d", buf1,
  176. Values[i].str1, Fi->key, Values[i].cat);
  177. break;
  178. }
  179. }
  180. }
  181. G_debug(3, "SQL: %s", buf2);
  182. db_set_string(&stmt, buf2);
  183. /* category exist in DB table ? */
  184. cex = (int *)bsearch((void *)&fcat, catexst, vstat.select, sizeof(int),
  185. srch);
  186. if (options.option == O_CAT) {
  187. if (cex == NULL) { /* cat does not exist in DB */
  188. upd = 1;
  189. vstat.notexist++;
  190. }
  191. else { /* cat exists in DB */
  192. G_warning(_("Record (cat %d) already exists (not inserted)"),
  193. fcat);
  194. upd = 0;
  195. vstat.exist++;
  196. }
  197. }
  198. else {
  199. if (cex == NULL) { /* cat does not exist in DB */
  200. G_warning(_("Record (cat %d) does not exist (not updated)"),
  201. fcat);
  202. upd = 0;
  203. vstat.notexist++;
  204. }
  205. else { /* cat exists in DB */
  206. upd = 1;
  207. vstat.exist++;
  208. }
  209. }
  210. if (upd == 1) {
  211. if (options.sql) {
  212. fprintf(stdout, "%s\n", db_get_string(&stmt));
  213. }
  214. else {
  215. if (db_execute_immediate(driver, &stmt) == DB_OK) {
  216. vstat.update++;
  217. }
  218. else {
  219. vstat.error++;
  220. }
  221. }
  222. }
  223. }
  224. G_percent(1, 1, 1);
  225. db_commit_transaction(driver);
  226. G_free(catexst);
  227. db_close_database_shutdown_driver(driver);
  228. db_free_string(&stmt);
  229. return 0;
  230. }
  231. int srch(const void *pa, const void *pb)
  232. {
  233. int *p1 = (int *)pa;
  234. int *p2 = (int *)pb;
  235. if (*p1 < *p2)
  236. return -1;
  237. if (*p1 > *p2)
  238. return 1;
  239. return 0;
  240. }