fetch.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <grass/dbmi.h>
  2. #include "odbc.h"
  3. #include "globals.h"
  4. #include "proto.h"
  5. int db__driver_fetch(cn, position, more)
  6. dbCursor *cn;
  7. int position;
  8. int *more;
  9. {
  10. cursor *c;
  11. dbToken token;
  12. dbTable *table;
  13. dbColumn *column;
  14. dbValue *value;
  15. int col, ncols;
  16. SQLINTEGER len;
  17. int htype, sqltype, ctype;
  18. SQLRETURN ret;
  19. DATE_STRUCT date;
  20. TIME_STRUCT time;
  21. TIMESTAMP_STRUCT timestamp;
  22. /* get cursor token */
  23. token = db_get_cursor_token(cn);
  24. /* get the cursor by its token */
  25. if (!(c = (cursor *) db_find_token(token))) {
  26. db_error("cursor not found");
  27. return DB_FAILED;
  28. }
  29. /* fetch on position */
  30. switch (position) {
  31. case DB_NEXT:
  32. ret = SQLFetchScroll(c->stmt, SQL_FETCH_NEXT, 0);
  33. break;
  34. case DB_CURRENT:
  35. ret = SQLFetchScroll(c->stmt, SQL_FETCH_RELATIVE, 0);
  36. break;
  37. case DB_PREVIOUS:
  38. ret = SQLFetchScroll(c->stmt, SQL_FETCH_PRIOR, 0);
  39. break;
  40. case DB_FIRST:
  41. ret = SQLFetchScroll(c->stmt, SQL_FETCH_FIRST, 0);
  42. break;
  43. case DB_LAST:
  44. ret = SQLFetchScroll(c->stmt, SQL_FETCH_LAST, 0);
  45. break;
  46. default:
  47. return DB_FAILED;
  48. };
  49. if (ret == SQL_NO_DATA) {
  50. *more = 0;
  51. return DB_OK;
  52. }
  53. if (!SQL_SUCCEEDED(ret)) {
  54. return DB_FAILED;
  55. }
  56. *more = 1;
  57. /* get the data out of the descriptor into the table */
  58. table = db_get_cursor_table(cn);
  59. ncols = db_get_table_number_of_columns(table);
  60. for (col = 1; col <= ncols; col++) {
  61. column = db_get_table_column(table, col - 1);
  62. value = db_get_column_value(column);
  63. db_free_string(&value->s);
  64. /* Is null? */
  65. SQLGetData(c->stmt, col, SQL_C_CHAR, NULL, 0, &len);
  66. if (len == SQL_NULL_DATA) {
  67. value->isNull = 1;
  68. continue;
  69. }
  70. else
  71. value->isNull = 0;
  72. sqltype = db_get_column_sqltype(column);
  73. ctype = db_sqltype_to_Ctype(sqltype);
  74. htype = db_get_column_host_type(column);
  75. switch (ctype) {
  76. case DB_C_TYPE_STRING:
  77. if (htype == SQL_CHAR) {
  78. len = db_get_column_length(column);
  79. db_enlarge_string(&value->s, len + 1);
  80. ret =
  81. SQLGetData(c->stmt, col, SQL_C_CHAR, value->s.string,
  82. len + 1, NULL);
  83. }
  84. else if (htype == SQL_VARCHAR) {
  85. ret = SQLGetData(c->stmt, col, SQL_C_CHAR, NULL, 0, &len);
  86. db_enlarge_string(&value->s, len + 1);
  87. ret =
  88. SQLGetData(c->stmt, col, SQL_C_CHAR, value->s.string,
  89. len + 1, NULL);
  90. }
  91. else { /* now the same as SQL_VARCHAR, could differ for other htype ? */
  92. ret = SQLGetData(c->stmt, col, SQL_C_CHAR, NULL, 0, &len);
  93. db_enlarge_string(&value->s, len + 1);
  94. ret =
  95. SQLGetData(c->stmt, col, SQL_C_CHAR, value->s.string,
  96. len + 1, NULL);
  97. }
  98. break;
  99. case DB_C_TYPE_INT:
  100. ret =
  101. SQLGetData(c->stmt, col, SQL_C_LONG, &value->i,
  102. sizeof(value->i), NULL);
  103. break;
  104. case DB_C_TYPE_DOUBLE:
  105. ret =
  106. SQLGetData(c->stmt, col, SQL_C_DOUBLE, &value->d,
  107. sizeof(value->d), NULL);
  108. break;
  109. case DB_C_TYPE_DATETIME:
  110. switch (sqltype) {
  111. case DB_SQL_TYPE_DATE:
  112. ret =
  113. SQLGetData(c->stmt, col, SQL_C_TYPE_DATE, &date,
  114. sizeof(date), NULL);
  115. value->t.year = date.year;
  116. value->t.month = date.month;
  117. value->t.day = date.day;
  118. value->t.hour = 0;
  119. value->t.minute = 0;
  120. value->t.seconds = 0.0;
  121. break;
  122. case DB_SQL_TYPE_TIME:
  123. ret =
  124. SQLGetData(c->stmt, col, SQL_C_TYPE_TIME, &time,
  125. sizeof(time), NULL);
  126. value->t.year = 0;
  127. value->t.month = 0;
  128. value->t.day = 0;
  129. value->t.hour = time.hour;
  130. value->t.minute = time.minute;
  131. value->t.seconds = time.second;
  132. break;
  133. case DB_SQL_TYPE_TIMESTAMP:
  134. ret =
  135. SQLGetData(c->stmt, col, SQL_C_TYPE_TIMESTAMP, &timestamp,
  136. sizeof(timestamp), NULL);
  137. value->t.year = timestamp.year;
  138. value->t.month = timestamp.month;
  139. value->t.day = timestamp.day;
  140. value->t.hour = timestamp.hour;
  141. value->t.minute = timestamp.minute;
  142. value->t.seconds = timestamp.second;
  143. break;
  144. /*
  145. case DB_SQL_TYPE_INTERVAL:
  146. break;
  147. default:
  148. break;
  149. */
  150. }
  151. default:
  152. len = db_get_column_length(column);
  153. db_enlarge_string(&value->s, len + 1);
  154. ret =
  155. SQLGetData(c->stmt, col, SQL_C_CHAR, value->s.string, len + 1,
  156. NULL);
  157. break;
  158. }
  159. }
  160. return DB_OK;
  161. }
  162. int db__driver_get_num_rows(cn)
  163. dbCursor *cn;
  164. {
  165. cursor *c;
  166. dbToken token;
  167. /* get cursor token */
  168. token = db_get_cursor_token(cn);
  169. /* get the cursor by its token */
  170. if (!(c = (cursor *) db_find_token(token))) {
  171. db_error("cursor not found");
  172. return DB_FAILED;
  173. }
  174. return (c->nrows);
  175. }