fetch.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /**********************************************************
  2. * MODULE: mysql
  3. * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
  4. * PURPOSE: MySQL database driver
  5. * COPYRIGHT: (C) 2001 by the GRASS Development Team
  6. * This program is free software under the
  7. * GNU General Public License (>=v2).
  8. * Read the file COPYING that comes with GRASS
  9. * for details.
  10. **********************************************************/
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <grass/gis.h>
  14. #include <grass/dbmi.h>
  15. #include <grass/glocale.h>
  16. #include "globals.h"
  17. #include "proto.h"
  18. int db__driver_fetch(dbCursor * cn, int position, int *more)
  19. {
  20. cursor *c;
  21. dbToken token;
  22. dbTable *table;
  23. int i;
  24. /* get cursor token */
  25. token = db_get_cursor_token(cn);
  26. /* get the cursor by its token */
  27. if (!(c = (cursor *) db_find_token(token))) {
  28. db_d_append_error(_("Cursor not found"));
  29. db_d_report_error();
  30. return DB_FAILED;
  31. }
  32. /* fetch on position */
  33. switch (position) {
  34. case DB_NEXT:
  35. c->row = mysql_fetch_row(c->res);
  36. break;
  37. case DB_CURRENT:
  38. break;
  39. case DB_PREVIOUS:
  40. case DB_FIRST:
  41. case DB_LAST:
  42. default:
  43. db_d_append_error(_("Cursor position is not supported "
  44. "by MySQL driver"));
  45. db_d_report_error();
  46. return DB_FAILED;
  47. }
  48. G_debug(3, "nrows = %d", c->nrows);
  49. if (c->row == NULL) {
  50. *more = 0;
  51. return DB_OK;
  52. }
  53. *more = 1;
  54. /* get the data out of the descriptor into the table */
  55. table = db_get_cursor_table(cn);
  56. for (i = 0; i < c->ncols; i++) {
  57. int col, sqltype, mysqltype;
  58. dbColumn *column;
  59. dbValue *value;
  60. char *val;
  61. col = c->cols[i]; /* known column */
  62. column = db_get_table_column(table, i);
  63. mysqltype = db_get_column_host_type(column);
  64. sqltype = db_get_column_sqltype(column);
  65. value = db_get_column_value(column);
  66. db_zero_string(&value->s);
  67. value->t.year = 0;
  68. value->t.month = 0;
  69. value->t.day = 0;
  70. value->t.hour = 0;
  71. value->t.minute = 0;
  72. value->t.seconds = 0.0;
  73. val = c->row[i];
  74. if (!val) {
  75. value->isNull = 1;
  76. continue;
  77. }
  78. else {
  79. value->isNull = 0;
  80. }
  81. G_debug(3, "col %d, mysqltype %d, sqltype %d, val = '%s'",
  82. col, mysqltype, sqltype, c->row[col]);
  83. /* defined in /usr/include/mysql/mysql_com.h */
  84. switch (mysqltype) {
  85. int ns;
  86. case MYSQL_TYPE_TINY:
  87. case MYSQL_TYPE_SHORT:
  88. case MYSQL_TYPE_LONG:
  89. case MYSQL_TYPE_INT24:
  90. case MYSQL_TYPE_LONGLONG:
  91. case MYSQL_TYPE_YEAR:
  92. value->i = atoi(val);
  93. break;
  94. case MYSQL_TYPE_FLOAT:
  95. case MYSQL_TYPE_DOUBLE:
  96. value->d = atof(val);
  97. break;
  98. /* MySQL TIMESTAMP < 4.1: YYYYMMDDHHMMSS TIMESTAMP(14)
  99. * YYMMDDHHMMSS TIMESTAMP(12)
  100. * YYMMDDHHMM TIMESTAMP(10)
  101. * YYYYMMDD TIMESTAMP(8)
  102. * YYMMDD TIMESTAMP(6)
  103. * YYMM TIMESTAMP(4)
  104. * YY YY
  105. * MySQL TIMESTAMP >= 4.1: 'YYYY-MM-DD HH:MM:SS' (19 chars) */
  106. case MYSQL_TYPE_TIMESTAMP:
  107. {
  108. char valbuf[25], buf[10];
  109. memset(valbuf, 0, 25);
  110. strcpy(valbuf, val);
  111. switch (strlen(val)) {
  112. case 2:
  113. case 4:
  114. case 6:
  115. case 10:
  116. case 12:
  117. strncpy(buf, val, 2);
  118. buf[2] = 0;
  119. value->t.year = atoi(buf);
  120. strncpy(buf, val + 2, 2);
  121. buf[2] = 0;
  122. value->t.month = atoi(buf);
  123. strncpy(buf, val + 4, 2);
  124. buf[2] = 0;
  125. value->t.day = atoi(buf);
  126. strncpy(buf, val + 6, 2);
  127. buf[2] = 0;
  128. value->t.hour = atoi(buf);
  129. strncpy(buf, val + 8, 2);
  130. buf[2] = 0;
  131. value->t.minute = atoi(buf);
  132. strncpy(buf, val + 10, 2);
  133. buf[2] = 0;
  134. value->t.seconds = atof(buf);
  135. break;
  136. case 8:
  137. case 14:
  138. strncpy(buf, val, 4);
  139. buf[4] = 0;
  140. value->t.year = atoi(buf);
  141. strncpy(buf, val + 4, 2);
  142. buf[2] = 0;
  143. value->t.month = atoi(buf);
  144. strncpy(buf, val + 6, 2);
  145. buf[2] = 0;
  146. value->t.day = atoi(buf);
  147. strncpy(buf, val + 8, 2);
  148. buf[2] = 0;
  149. value->t.hour = atoi(buf);
  150. strncpy(buf, val + 10, 2);
  151. buf[2] = 0;
  152. value->t.minute = atoi(buf);
  153. strncpy(buf, val + 12, 2);
  154. buf[2] = 0;
  155. value->t.seconds = atof(buf);
  156. break;
  157. case 19:
  158. ns = sscanf(val, "%4d-%2d-%2d %2d:%2d:%lf",
  159. &(value->t.year), &(value->t.month),
  160. &(value->t.day), &(value->t.hour),
  161. &(value->t.minute), &(value->t.seconds));
  162. if (ns != 6) {
  163. db_d_append_error("%s %s",
  164. _("Unable to scan timestamp: "),
  165. val);
  166. db_d_report_error();
  167. return DB_FAILED;
  168. }
  169. break;
  170. default:
  171. db_d_append_error("%s %s",
  172. _("Unknown timestamp format: "),
  173. val);
  174. db_d_report_error();
  175. return DB_FAILED;
  176. }
  177. }
  178. break;
  179. /* MySQL DATE: 'YYYY-MM-DD' */
  180. case MYSQL_TYPE_DATE:
  181. ns = sscanf(val, "%4d-%2d-%2d", &(value->t.year),
  182. &(value->t.month), &(value->t.day));
  183. if (ns != 3) {
  184. db_d_append_error("%s %s",
  185. _("Unable to scan date: "),
  186. val);
  187. db_d_report_error();
  188. return DB_FAILED;
  189. }
  190. break;
  191. /* MySQL DATETIME: 'HH:MM:SS' */
  192. case MYSQL_TYPE_TIME:
  193. ns = sscanf(val, "%2d:%2d:%lf", &(value->t.hour),
  194. &(value->t.minute), &(value->t.seconds));
  195. if (ns != 3) {
  196. db_d_append_error("%s %s",
  197. _("Unable to scan time: "),
  198. val);
  199. db_d_report_error();
  200. return DB_FAILED;
  201. }
  202. break;
  203. /* MySQL DATETIME: 'YYYY-MM-DD HH:MM:SS' */
  204. case MYSQL_TYPE_DATETIME:
  205. ns = sscanf(val, "%4d-%2d-%2d %2d:%2d:%lf",
  206. &(value->t.year), &(value->t.month),
  207. &(value->t.day), &(value->t.hour),
  208. &(value->t.minute), &(value->t.seconds));
  209. if (ns != 6) {
  210. db_d_append_error("%s %s",
  211. _("Unable to scan datetime:"),
  212. val);
  213. db_d_report_error();
  214. return DB_FAILED;
  215. }
  216. break;
  217. case MYSQL_TYPE_STRING:
  218. case MYSQL_TYPE_VAR_STRING:
  219. case MYSQL_TYPE_SET:
  220. case MYSQL_TYPE_ENUM:
  221. case MYSQL_TYPE_BLOB:
  222. db_set_string(&(value->s), val);
  223. break;
  224. }
  225. }
  226. G_debug(3, "Row fetched");
  227. return DB_OK;
  228. }
  229. int db__driver_get_num_rows(cn)
  230. dbCursor *cn;
  231. {
  232. cursor *c;
  233. dbToken token;
  234. /* get cursor token */
  235. token = db_get_cursor_token(cn);
  236. /* get the cursor by its token */
  237. if (!(c = (cursor *) db_find_token(token))) {
  238. db_d_append_error(_("Cursor not found"));
  239. db_d_report_error();
  240. return DB_FAILED;
  241. }
  242. return (c->nrows);
  243. }