Annotation of embedaddon/php/ext/pdo_dblib/dblib_stmt.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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:
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 21:
22: #ifdef HAVE_CONFIG_H
23: # include "config.h"
24: #endif
25:
26: #include "php.h"
27: #include "php_ini.h"
28: #include "ext/standard/php_string.h"
29: #include "ext/standard/info.h"
30: #include "pdo/php_pdo.h"
31: #include "pdo/php_pdo_driver.h"
32: #include "php_pdo_dblib.h"
33: #include "php_pdo_dblib_int.h"
34: #include "zend_exceptions.h"
35:
1.1.1.2 misho 36:
37: /* {{{ pdo_dblib_get_field_name
38: *
1.1.1.3 ! misho 39: * Return the data type name for a given TDS number
1.1.1.2 misho 40: *
41: */
42: static char *pdo_dblib_get_field_name(int type)
1.1 misho 43: {
1.1.1.3 ! misho 44: /*
! 45: * I don't return dbprtype(type) because it does not fully describe the type
! 46: * (example: varchar is reported as char by dbprtype)
! 47: *
! 48: * FIX ME: Cache datatypes from server systypes table in pdo_dblib_handle_factory()
! 49: * to make this future proof.
! 50: */
! 51:
1.1.1.2 misho 52: switch (type) {
1.1.1.3 ! misho 53: case 31: return "nvarchar";
1.1.1.2 misho 54: case 34: return "image";
55: case 35: return "text";
56: case 36: return "uniqueidentifier";
1.1.1.3 ! misho 57: case 37: return "varbinary"; /* & timestamp - Sybase AS12 */
! 58: case 38: return "bigint"; /* & bigintn - Sybase AS12 */
! 59: case 39: return "varchar"; /* & sysname & nvarchar - Sybase AS12 */
1.1.1.2 misho 60: case 40: return "date";
61: case 41: return "time";
62: case 42: return "datetime2";
63: case 43: return "datetimeoffset";
1.1.1.3 ! misho 64: case 45: return "binary"; /* Sybase AS12 */
! 65: case 47: return "char"; /* & nchar & uniqueidentifierstr Sybase AS12 */
1.1.1.2 misho 66: case 48: return "tinyint";
1.1.1.3 ! misho 67: case 50: return "bit"; /* Sybase AS12 */
1.1.1.2 misho 68: case 52: return "smallint";
1.1.1.3 ! misho 69: case 55: return "decimal"; /* Sybase AS12 */
1.1.1.2 misho 70: case 56: return "int";
71: case 58: return "smalldatetime";
72: case 59: return "real";
73: case 60: return "money";
74: case 61: return "datetime";
75: case 62: return "float";
1.1.1.3 ! misho 76: case 63: return "numeric"; /* or uint, ubigint, usmallint Sybase AS12 */
1.1.1.2 misho 77: case 98: return "sql_variant";
78: case 99: return "ntext";
79: case 104: return "bit";
1.1.1.3 ! misho 80: case 106: return "decimal"; /* decimal n on sybase */
! 81: case 108: return "numeric"; /* numeric n on sybase */
1.1.1.2 misho 82: case 122: return "smallmoney";
83: case 127: return "bigint";
84: case 165: return "varbinary";
85: case 167: return "varchar";
86: case 173: return "binary";
87: case 175: return "char";
88: case 189: return "timestamp";
89: case 231: return "nvarchar";
90: case 239: return "nchar";
1.1.1.3 ! misho 91: case 240: return "geometry";
1.1.1.2 misho 92: case 241: return "xml";
1.1.1.3 ! misho 93: default: return "unknown";
1.1 misho 94: }
1.1.1.2 misho 95: }
96: /* }}} */
97:
1.1.1.3 ! misho 98: static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
1.1.1.2 misho 99: {
100: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
101: pdo_dblib_db_handle *H = S->H;
102:
103: /* Cancel any pending results */
104: dbcancel(H->link);
1.1.1.3 ! misho 105:
! 106: efree(stmt->columns);
1.1.1.2 misho 107: stmt->columns = NULL;
108:
109: return 1;
1.1 misho 110: }
111:
112: static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
113: {
114: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
115:
1.1.1.3 ! misho 116: efree(stmt->columns);
! 117: stmt->columns = NULL;
1.1 misho 118:
1.1.1.2 misho 119: efree(S);
120:
1.1 misho 121: return 1;
122: }
123:
1.1.1.2 misho 124: static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
1.1 misho 125: {
126: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
127: pdo_dblib_db_handle *H = S->H;
1.1.1.2 misho 128: RETCODE ret;
129:
130: ret = dbresults(H->link);
131:
1.1.1.3 ! misho 132: if (FAIL == ret) {
! 133: pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbresults() returned FAIL" TSRMLS_CC);
! 134: return 0;
! 135: }
! 136:
! 137: if(NO_MORE_RESULTS == ret) {
1.1.1.2 misho 138: return 0;
1.1 misho 139: }
1.1.1.2 misho 140:
141: stmt->row_count = DBCOUNT(H->link);
142: stmt->column_count = dbnumcols(H->link);
143:
144: return 1;
145: }
1.1 misho 146:
1.1.1.2 misho 147: static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
148: {
149: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
150: pdo_dblib_db_handle *H = S->H;
151: RETCODE ret;
152:
153: dbsetuserdata(H->link, (BYTE*) &S->err);
154:
1.1.1.3 ! misho 155: pdo_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
! 156:
1.1 misho 157: if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
158: return 0;
159: }
1.1.1.2 misho 160:
1.1 misho 161: if (FAIL == dbsqlexec(H->link)) {
162: return 0;
163: }
164:
1.1.1.2 misho 165: ret = pdo_dblib_stmt_next_rowset(stmt TSRMLS_CC);
166:
1.1 misho 167: stmt->row_count = DBCOUNT(H->link);
1.1.1.2 misho 168: stmt->column_count = dbnumcols(H->link);
1.1 misho 169:
1.1.1.2 misho 170: return 1;
1.1 misho 171: }
172:
173: static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
174: enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
175: {
1.1.1.2 misho 176:
177: RETCODE ret;
178:
1.1 misho 179: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2 misho 180: pdo_dblib_db_handle *H = S->H;
181:
182: ret = dbnextrow(H->link);
183:
1.1.1.3 ! misho 184: if (FAIL == ret) {
! 185: pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbnextrow() returned FAIL" TSRMLS_CC);
! 186: return 0;
! 187: }
! 188:
! 189: if(NO_MORE_ROWS == ret) {
1.1 misho 190: return 0;
191: }
192:
1.1.1.2 misho 193: return 1;
1.1 misho 194: }
195:
196: static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
197: {
198: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2 misho 199: pdo_dblib_db_handle *H = S->H;
200:
1.1.1.3 ! misho 201: if(colno >= stmt->column_count || colno < 0) {
! 202: return FAILURE;
! 203: }
! 204:
1.1 misho 205: struct pdo_column_data *col = &stmt->columns[colno];
1.1.1.2 misho 206:
207: col->name = (char*)dbcolname(H->link, colno+1);
208: col->maxlen = dbcollen(H->link, colno+1);
209: col->namelen = strlen(col->name);
1.1 misho 210: col->param_type = PDO_PARAM_STR;
211:
212: return 1;
213: }
214:
215: static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
216: unsigned long *len, int *caller_frees TSRMLS_DC)
217: {
1.1.1.2 misho 218:
1.1 misho 219: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2 misho 220: pdo_dblib_db_handle *H = S->H;
221:
222: int coltype;
223: unsigned int tmp_len;
224: char *tmp_ptr = NULL;
225:
226: coltype = dbcoltype(H->link, colno+1);
227:
228: *len = dbdatlen(H->link, colno+1);
229: *ptr = dbdata(H->link, colno+1);
230:
231: if (*len == 0 && *ptr == NULL) {
232: return 1;
233: }
234:
235: switch (coltype) {
236: case SQLVARBINARY:
237: case SQLBINARY:
238: case SQLIMAGE:
1.1.1.3 ! misho 239: case SQLTEXT:
! 240: /* FIXME: Above types should be returned as a stream as they can be VERY large */
! 241: case SQLCHAR:
1.1.1.2 misho 242: case SQLVARCHAR:
243: tmp_ptr = emalloc(*len + 1);
244: memcpy(tmp_ptr, *ptr, *len);
245: tmp_ptr[*len] = '\0';
246: *ptr = tmp_ptr;
247: break;
248: case SQLMONEY:
249: case SQLMONEY4:
250: case SQLMONEYN: {
251: DBFLT8 money_value;
252: dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
253: *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
254: *ptr = tmp_ptr;
255: break;
256: }
257: case SQLUNIQUE: {
258: *len = 36+1;
259: tmp_ptr = emalloc(*len + 1);
260:
261: /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
262: *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
263: php_strtoupper(tmp_ptr, *len);
264: *ptr = tmp_ptr;
265: break;
266: }
267: default:
268: if (dbwillconvert(coltype, SQLCHAR)) {
1.1.1.3 ! misho 269: tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
1.1.1.2 misho 270: tmp_ptr = emalloc(tmp_len);
271: *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
272: *ptr = tmp_ptr;
1.1.1.3 ! misho 273: } else {
! 274: *len = 0; /* FIXME: Silently fails and returns null on conversion errors */
! 275: *ptr = NULL;
! 276: }
1.1.1.2 misho 277: }
278:
279: *caller_frees = 1;
1.1 misho 280:
281: return 1;
282: }
283:
284: static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
285: enum pdo_param_event event_type TSRMLS_DC)
286: {
287: return 1;
288: }
289:
1.1.1.2 misho 290: static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
1.1 misho 291: {
292: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2 misho 293: pdo_dblib_db_handle *H = S->H;
1.1.1.3 ! misho 294: DBTYPEINFO* dbtypeinfo;
! 295:
! 296: if(colno >= stmt->column_count || colno < 0) {
! 297: return FAILURE;
! 298: }
! 299:
1.1.1.2 misho 300: array_init(return_value);
1.1 misho 301:
1.1.1.2 misho 302: dbtypeinfo = dbcoltypeinfo(H->link, colno+1);
1.1.1.3 ! misho 303:
! 304: if(!dbtypeinfo) return FAILURE;
1.1.1.2 misho 305:
306: add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
307: add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
308: add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
309: add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1), 1);
310: add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)), 1);
1.1.1.3 ! misho 311: add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
! 312: add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
1.1 misho 313:
314: return 1;
315: }
316:
1.1.1.2 misho 317:
1.1 misho 318: struct pdo_stmt_methods dblib_stmt_methods = {
319: pdo_dblib_stmt_dtor,
320: pdo_dblib_stmt_execute,
321: pdo_dblib_stmt_fetch,
322: pdo_dblib_stmt_describe,
323: pdo_dblib_stmt_get_col,
324: pdo_dblib_stmt_param_hook,
325: NULL, /* set attr */
326: NULL, /* get attr */
1.1.1.2 misho 327: pdo_dblib_stmt_get_column_meta, /* meta */
328: pdo_dblib_stmt_next_rowset, /* nextrow */
1.1.1.3 ! misho 329: pdo_dblib_stmt_cursor_closer
1.1 misho 330: };
331:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>