fetch.c 6.6 KB

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