update.c 8.0 KB

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