update.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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_begin_transaction(driver);
  44. /* select existing categories (layer) to array (array is sorted) */
  45. vstat.select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
  46. G_debug(3, "Existing categories: %d", vstat.select);
  47. /* create beginning of stmt */
  48. switch (options.option) {
  49. case O_CAT:
  50. sprintf(buf1, "insert into %s ( %s ) values ", Fi->table, Fi->key);
  51. break;
  52. case O_COUNT:
  53. case O_LENGTH:
  54. case O_AREA:
  55. case O_QUERY:
  56. case O_COMPACT:
  57. case O_FD:
  58. case O_PERIMETER:
  59. case O_SLOPE:
  60. case O_SINUOUS:
  61. case O_AZIMUTH:
  62. sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
  63. break;
  64. case O_COOR:
  65. case O_START:
  66. case O_END:
  67. case O_SIDES:
  68. sprintf(buf1, "update %s set ", Fi->table);
  69. break;
  70. }
  71. /* update */
  72. G_message(_("Updating database..."));
  73. for (i = 0; i < vstat.rcat; i++) {
  74. G_percent(i, vstat.rcat, 2);
  75. fcat = Values[i].cat;
  76. if (fcat < 0)
  77. continue;
  78. switch (options.option) {
  79. case O_CAT:
  80. sprintf(buf2, "%s ( %d )", buf1, Values[i].cat);
  81. break;
  82. case O_COUNT:
  83. sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].count1,
  84. Fi->key, Values[i].cat);
  85. break;
  86. case O_LENGTH:
  87. case O_AREA:
  88. case O_COMPACT:
  89. case O_FD:
  90. case O_PERIMETER:
  91. case O_SLOPE:
  92. case O_SINUOUS:
  93. case O_AZIMUTH:
  94. sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
  95. Values[i].cat);
  96. break;
  97. case O_COOR:
  98. case O_START:
  99. case O_END:
  100. if (Values[i].count1 > 1) {
  101. G_warning(_("More elements of category %d, nothing loaded to database"),
  102. Values[i].cat);
  103. vstat.dupl++;
  104. continue;
  105. }
  106. if (Values[i].count1 < 1) { /* No points */
  107. continue;
  108. }
  109. if (options.col[2]) {
  110. sprintf(buf2,
  111. "%s %s = %.15g, %s = %.15g, %s = %.15g where %s = %d",
  112. buf1, options.col[0], Values[i].d1, options.col[1],
  113. Values[i].d2, options.col[2], Values[i].d3, Fi->key,
  114. Values[i].cat);
  115. }
  116. else {
  117. sprintf(buf2, "%s %s = %.15g, %s = %.15g where %s = %d",
  118. buf1, options.col[0], Values[i].d1, options.col[1],
  119. Values[i].d2, Fi->key, Values[i].cat);
  120. }
  121. break;
  122. case O_SIDES:
  123. if (Values[i].count1 == 1) {
  124. if (Values[i].i1 >= 0)
  125. sprintf(left, "%d", Values[i].i1);
  126. else
  127. sprintf(left, "-1"); /* NULL, no area/cat */
  128. }
  129. else if (Values[i].count1 > 1) {
  130. sprintf(left, "null");
  131. }
  132. else { /* Values[i].count1 == 0 */
  133. /* It can be OK if the category is assigned to an element
  134. type which is not GV_BOUNDARY */
  135. /* -> TODO: print only if there is boundary with that cat */
  136. sprintf(left, "null");
  137. }
  138. if (Values[i].count2 == 1) {
  139. if (Values[i].i2 >= 0)
  140. sprintf(right, "%d", Values[i].i2);
  141. else
  142. sprintf(right, "-1"); /* NULL, no area/cat */
  143. }
  144. else if (Values[i].count2 > 1) {
  145. sprintf(right, "null");
  146. }
  147. else { /* Values[i].count1 == 0 */
  148. sprintf(right, "null");
  149. }
  150. sprintf(buf2, "%s %s = %s, %s = %s where %s = %d", buf1,
  151. options.col[0], left, options.col[1], right, Fi->key,
  152. Values[i].cat);
  153. break;
  154. case O_QUERY:
  155. if (Values[i].null) {
  156. sprintf(buf2, "%s null where %s = %d", buf1, Fi->key,
  157. Values[i].cat);
  158. }
  159. else {
  160. switch (vstat.qtype) {
  161. case (DB_C_TYPE_INT):
  162. sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].i1,
  163. Fi->key, Values[i].cat);
  164. break;
  165. case (DB_C_TYPE_DOUBLE):
  166. sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1,
  167. Fi->key, Values[i].cat);
  168. break;
  169. case (DB_C_TYPE_STRING):
  170. sprintf(buf2, "%s '%s' where %s = %d", buf1,
  171. Values[i].str1, Fi->key, Values[i].cat);
  172. break;
  173. case (DB_C_TYPE_DATETIME):
  174. sprintf(buf2, "%s '%s' where %s = %d", buf1,
  175. Values[i].str1, Fi->key, Values[i].cat);
  176. break;
  177. }
  178. }
  179. }
  180. G_debug(3, "SQL: %s", buf2);
  181. db_set_string(&stmt, buf2);
  182. /* category exist in DB table ? */
  183. cex = (int *)bsearch((void *)&fcat, catexst, vstat.select, sizeof(int),
  184. srch);
  185. if (options.option == O_CAT) {
  186. if (cex == NULL) { /* cat does not exist in DB */
  187. upd = 1;
  188. vstat.notexist++;
  189. }
  190. else { /* cat exists in DB */
  191. G_warning(_("Record (cat %d) already exists (not inserted)"),
  192. fcat);
  193. upd = 0;
  194. vstat.exist++;
  195. }
  196. }
  197. else {
  198. if (cex == NULL) { /* cat does not exist in DB */
  199. G_warning(_("Record (cat %d) does not exist (not updated)"),
  200. fcat);
  201. upd = 0;
  202. vstat.notexist++;
  203. }
  204. else { /* cat exists in DB */
  205. upd = 1;
  206. vstat.exist++;
  207. }
  208. }
  209. if (upd == 1) {
  210. if (options.sql) {
  211. fprintf(stdout, "%s\n", db_get_string(&stmt));
  212. }
  213. else {
  214. if (db_execute_immediate(driver, &stmt) == DB_OK) {
  215. vstat.update++;
  216. }
  217. else {
  218. vstat.error++;
  219. }
  220. }
  221. }
  222. }
  223. G_percent(1, 1, 1);
  224. db_commit_transaction(driver);
  225. G_free(catexst);
  226. db_close_database_shutdown_driver(driver);
  227. db_free_string(&stmt);
  228. return 0;
  229. }
  230. int srch(const void *pa, const void *pb)
  231. {
  232. int *p1 = (int *)pa;
  233. int *p2 = (int *)pb;
  234. if (*p1 < *p2)
  235. return -1;
  236. if (*p1 > *p2)
  237. return 1;
  238. return 0;
  239. }