query.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <grass/dbmi.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. /* Query database for qfield. */
  7. int query(struct Map_info *Map)
  8. {
  9. int i, j, idx, cat_no, nlines, type;
  10. register int line_num;
  11. struct line_pnts *Points;
  12. struct line_cats *Cats;
  13. struct field_info *Fi;
  14. dbString stmt, value_string;
  15. dbDriver *driver;
  16. /* Initialize the Point struct */
  17. Points = Vect_new_line_struct();
  18. Cats = Vect_new_cats_struct();
  19. /* Cycle through all lines and make a list of categories of 'qfield' for each category given by 'field' */
  20. G_message(_("Reading data from the map..."));
  21. nlines = Vect_get_num_lines(Map);
  22. for (line_num = 1; line_num <= nlines; line_num++) {
  23. G_percent(line_num, nlines, 1);
  24. type = Vect_read_line(Map, Points, Cats, line_num);
  25. if (!(type & options.type))
  26. continue;
  27. for (i = 0; i < Cats->n_cats; i++) {
  28. if (Cats->field[i] == options.field) {
  29. cat_no = Cats->cat[i];
  30. idx = find_cat(cat_no);
  31. for (j = 0; j < Cats->n_cats; j++) {
  32. if (Cats->field[j] == options.qfield) { /* Add to list */
  33. if (Values[idx].nqcats == Values[idx].aqcats) { /* Alloc space */
  34. Values[idx].aqcats += 2;
  35. Values[idx].qcat =
  36. (int *)G_realloc(Values[idx].qcat,
  37. Values[idx].aqcats *
  38. sizeof(int));
  39. }
  40. Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
  41. Values[idx].nqcats++;
  42. }
  43. }
  44. }
  45. }
  46. /* If there is no field cat add cat -1, values for cat -1 are reported at the end */
  47. Vect_cat_get(Cats, options.field, &cat_no);
  48. if (cat_no == -1) {
  49. idx = find_cat(cat_no);
  50. for (j = 0; j < Cats->n_cats; j++) {
  51. if (Cats->field[j] == options.qfield) { /* Add to list */
  52. if (Values[idx].nqcats == Values[idx].aqcats) { /* Alloc space */
  53. Values[idx].aqcats += 2;
  54. Values[idx].qcat =
  55. (int *)G_realloc(Values[idx].qcat,
  56. Values[idx].aqcats *
  57. sizeof(int));
  58. }
  59. Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
  60. Values[idx].nqcats++;
  61. }
  62. }
  63. }
  64. }
  65. db_init_string(&stmt);
  66. db_init_string(&value_string);
  67. if ((Fi = Vect_get_field(Map, options.qfield)) == NULL)
  68. G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
  69. options.qfield);
  70. /* Open driver */
  71. driver = db_start_driver_open_database(Fi->driver, Fi->database);
  72. if (driver == NULL)
  73. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  74. Fi->database, Fi->driver);
  75. /* Query the database for each category */
  76. G_message(_("Querying database... "));
  77. for (i = 0; i < vstat.rcat; i++) {
  78. int j, ctype, nrows, more;
  79. char buf[2000];
  80. dbCursor cursor;
  81. dbTable *table;
  82. dbColumn *column;
  83. dbValue *value;
  84. G_debug(3, "cat %d", Values[i].cat);
  85. G_percent(i + 1, vstat.rcat, 1);
  86. /* Skip if cat is zero and large number of query categories (many features without category).
  87. * It would cause problems on server side and take long time. Postgres limit is 10000 */
  88. if (Values[i].cat == 0 && Values[i].nqcats > 1000) {
  89. G_warning(_("Query for category '0' (no category) was not executed because of too many "
  90. "(%d) query categories. All later reported values for cat 0 are not valid."),
  91. Values[i].nqcats);
  92. continue;
  93. }
  94. if (Values[i].nqcats > 0) {
  95. sprintf(buf, "SELECT %s FROM %s WHERE", options.qcol, Fi->table);
  96. db_set_string(&stmt, buf);
  97. for (j = 0; j < Values[i].nqcats; j++) {
  98. G_debug(4, " qcat %d", Values[i].qcat[j]);
  99. if (j > 0)
  100. db_append_string(&stmt, " OR");
  101. sprintf(buf, " %s = %d", Fi->key, Values[i].qcat[j]);
  102. db_append_string(&stmt, buf);
  103. }
  104. G_debug(4, " SQL: '%s'", db_get_string(&stmt));
  105. if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL)
  106. != DB_OK)
  107. G_fatal_error("Cannot open cursor: '%s'",
  108. db_get_string(&stmt));
  109. table = db_get_cursor_table(&cursor);
  110. column = db_get_table_column(table, 0); /* first column */
  111. value = db_get_column_value(column);
  112. ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
  113. vstat.qtype = ctype;
  114. nrows = db_get_num_rows(&cursor);
  115. G_debug(4, " nrows = %d, columnt type = %d", nrows, ctype);
  116. if (nrows != 1) {
  117. if (nrows > 1) {
  118. G_warning(_("Multiple query results, output value set to NULL (category [%d])"),
  119. Values[i].cat);
  120. }
  121. Values[i].null = 1;
  122. }
  123. else {
  124. if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
  125. G_fatal_error(_("Unable to fetch record"));
  126. db_convert_column_value_to_string(column, &stmt);
  127. G_debug(4, " value = %s", db_get_string(&stmt));
  128. if (db_test_value_isnull(value)) {
  129. Values[i].null = 1;
  130. }
  131. else {
  132. switch (ctype) {
  133. case (DB_C_TYPE_INT):
  134. Values[i].i1 = db_get_value_int(value);
  135. break;
  136. case (DB_C_TYPE_DOUBLE):
  137. Values[i].d1 = db_get_value_double(value);
  138. break;
  139. case (DB_C_TYPE_STRING):
  140. Values[i].str1 = G_store(db_get_value_string(value));
  141. break;
  142. case (DB_C_TYPE_DATETIME):
  143. db_convert_column_value_to_string(column,
  144. &value_string);
  145. Values[i].str1 =
  146. G_store(db_get_string(&value_string));
  147. }
  148. Values[i].null = 0;
  149. }
  150. }
  151. db_close_cursor(&cursor);
  152. }
  153. else { /* no qcats -> upload NULL */
  154. Values[i].null = 1;
  155. }
  156. }
  157. db_close_database_shutdown_driver(driver);
  158. return 0;
  159. }