You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
7.5 KiB

13 years ago
20 years ago
20 years ago
16 years ago
16 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2013 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Wez Furlong <wez@php.net> |
  16. | Frank M. Kromann <frank@kromann.info> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #ifdef HAVE_CONFIG_H
  21. # include "config.h"
  22. #endif
  23. #include "php.h"
  24. #include "php_ini.h"
  25. #include "ext/standard/php_string.h"
  26. #include "ext/standard/info.h"
  27. #include "pdo/php_pdo.h"
  28. #include "pdo/php_pdo_driver.h"
  29. #include "php_pdo_dblib.h"
  30. #include "php_pdo_dblib_int.h"
  31. #include "zend_exceptions.h"
  32. /* {{{ pdo_dblib_get_field_name
  33. *
  34. * Updated for MSSQL 2008 SR2 extended types
  35. *
  36. */
  37. static char *pdo_dblib_get_field_name(int type)
  38. {
  39. switch (type) {
  40. case 34: return "image";
  41. case 35: return "text";
  42. case 36: return "uniqueidentifier";
  43. case 40: return "date";
  44. case 41: return "time";
  45. case 42: return "datetime2";
  46. case 43: return "datetimeoffset";
  47. case 48: return "tinyint";
  48. case 52: return "smallint";
  49. case 56: return "int";
  50. case 58: return "smalldatetime";
  51. case 59: return "real";
  52. case 60: return "money";
  53. case 61: return "datetime";
  54. case 62: return "float";
  55. case 98: return "sql_variant";
  56. case 99: return "ntext";
  57. case 104: return "bit";
  58. case 106: return "decimal";
  59. case 108: return "numeric";
  60. case 122: return "smallmoney";
  61. case 127: return "bigint";
  62. case 240: return "geometry";
  63. case 165: return "varbinary";
  64. case 167: return "varchar";
  65. case 173: return "binary";
  66. case 175: return "char";
  67. case 189: return "timestamp";
  68. case 231: return "nvarchar";
  69. case 239: return "nchar";
  70. case 241: return "xml";
  71. default:
  72. return "unknown";
  73. break;
  74. }
  75. }
  76. /* }}} */
  77. static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
  78. {
  79. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  80. pdo_dblib_db_handle *H = S->H;
  81. /* Cancel any pending results */
  82. dbcancel(H->link);
  83. efree(stmt->columns);
  84. stmt->columns = NULL;
  85. return 1;
  86. }
  87. static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
  88. {
  89. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  90. dblib_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
  91. efree(S);
  92. return 1;
  93. }
  94. static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
  95. {
  96. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  97. pdo_dblib_db_handle *H = S->H;
  98. RETCODE ret;
  99. ret = dbresults(H->link);
  100. if (ret == FAIL || ret == NO_MORE_RESULTS) {
  101. return 0;
  102. }
  103. stmt->row_count = DBCOUNT(H->link);
  104. stmt->column_count = dbnumcols(H->link);
  105. return 1;
  106. }
  107. static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
  108. {
  109. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  110. pdo_dblib_db_handle *H = S->H;
  111. RETCODE ret;
  112. dbsetuserdata(H->link, (BYTE*) &S->err);
  113. if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
  114. return 0;
  115. }
  116. if (FAIL == dbsqlexec(H->link)) {
  117. return 0;
  118. }
  119. ret = pdo_dblib_stmt_next_rowset(stmt TSRMLS_CC);
  120. if (ret == 0) {
  121. return 0;
  122. }
  123. stmt->row_count = DBCOUNT(H->link);
  124. stmt->column_count = dbnumcols(H->link);
  125. return 1;
  126. }
  127. static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
  128. enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
  129. {
  130. RETCODE ret;
  131. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  132. pdo_dblib_db_handle *H = S->H;
  133. ret = dbnextrow(H->link);
  134. if (ret == FAIL || ret == NO_MORE_ROWS) {
  135. return 0;
  136. }
  137. return 1;
  138. }
  139. static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
  140. {
  141. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  142. pdo_dblib_db_handle *H = S->H;
  143. struct pdo_column_data *col = &stmt->columns[colno];
  144. col->name = (char*)dbcolname(H->link, colno+1);
  145. col->maxlen = dbcollen(H->link, colno+1);
  146. col->namelen = strlen(col->name);
  147. col->param_type = PDO_PARAM_STR;
  148. return 1;
  149. }
  150. static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
  151. unsigned long *len, int *caller_frees TSRMLS_DC)
  152. {
  153. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  154. pdo_dblib_db_handle *H = S->H;
  155. int coltype;
  156. unsigned int tmp_len;
  157. char *tmp_ptr = NULL;
  158. coltype = dbcoltype(H->link, colno+1);
  159. *len = dbdatlen(H->link, colno+1);
  160. *ptr = dbdata(H->link, colno+1);
  161. if (*len == 0 && *ptr == NULL) {
  162. return 1;
  163. }
  164. switch (coltype) {
  165. case SQLCHAR:
  166. case SQLTEXT:
  167. case SQLVARBINARY:
  168. case SQLBINARY:
  169. case SQLIMAGE:
  170. case SQLVARCHAR:
  171. tmp_ptr = emalloc(*len + 1);
  172. memcpy(tmp_ptr, *ptr, *len);
  173. tmp_ptr[*len] = '\0';
  174. *ptr = tmp_ptr;
  175. break;
  176. case SQLMONEY:
  177. case SQLMONEY4:
  178. case SQLMONEYN: {
  179. DBFLT8 money_value;
  180. dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
  181. *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
  182. *ptr = tmp_ptr;
  183. break;
  184. }
  185. #ifdef SQLUNIQUE
  186. case SQLUNIQUE: {
  187. #else
  188. case 36: { /* FreeTDS hack, also used by ext/mssql */
  189. #endif
  190. *len = 36+1;
  191. tmp_ptr = emalloc(*len + 1);
  192. /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
  193. #ifdef SQLUNIQUE
  194. *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
  195. #else
  196. *len = dbconvert(NULL, 36, *ptr, *len, SQLCHAR, tmp_ptr, *len);
  197. #endif
  198. php_strtoupper(tmp_ptr, *len);
  199. *ptr = tmp_ptr;
  200. break;
  201. }
  202. default:
  203. if (dbwillconvert(coltype, SQLCHAR)) {
  204. tmp_len = 32 + (2 * (*len));
  205. tmp_ptr = emalloc(tmp_len);
  206. *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
  207. *ptr = tmp_ptr;
  208. } else {
  209. *len = 0;
  210. *ptr = NULL;
  211. }
  212. }
  213. *caller_frees = 1;
  214. return 1;
  215. }
  216. static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
  217. enum pdo_param_event event_type TSRMLS_DC)
  218. {
  219. return 1;
  220. }
  221. static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
  222. {
  223. pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
  224. pdo_dblib_db_handle *H = S->H;
  225. array_init(return_value);
  226. DBTYPEINFO* dbtypeinfo;
  227. dbtypeinfo = dbcoltypeinfo(H->link, colno+1);
  228. add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
  229. add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
  230. add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
  231. add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1), 1);
  232. add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)), 1);
  233. return 1;
  234. }
  235. struct pdo_stmt_methods dblib_stmt_methods = {
  236. pdo_dblib_stmt_dtor,
  237. pdo_dblib_stmt_execute,
  238. pdo_dblib_stmt_fetch,
  239. pdo_dblib_stmt_describe,
  240. pdo_dblib_stmt_get_col,
  241. pdo_dblib_stmt_param_hook,
  242. NULL, /* set attr */
  243. NULL, /* get attr */
  244. pdo_dblib_stmt_get_column_meta, /* meta */
  245. pdo_dblib_stmt_next_rowset, /* nextrow */
  246. dblib_dblib_stmt_cursor_closer
  247. };