Annotation of embedaddon/php/ext/pdo_dblib/dblib_stmt.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 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:
20: /* $Id: dblib_stmt.c 321634 2012-01-01 13:15:04Z felipe $ */
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:
36: static void free_rows(pdo_dblib_stmt *S TSRMLS_DC)
37: {
38: int i, j;
39:
40: for (i = 0; i < S->nrows; i++) {
41: for (j = 0; j < S->ncols; j++) {
42: pdo_dblib_colval *val = &S->rows[i*S->ncols] + j;
43: if (val->data) {
44: efree(val->data);
45: val->data = NULL;
46: }
47: }
48: }
49: efree(S->rows);
50: S->rows = NULL;
51: S->nrows = 0;
52: }
53:
54: static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
55: {
56: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
57:
58: if (S->rows) {
59: free_rows(S TSRMLS_CC);
60: }
61: if (S->cols) {
62: efree(S->cols);
63: }
64: efree(S);
65:
66: return 1;
67: }
68:
69: static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
70: {
71: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
72: pdo_dblib_db_handle *H = S->H;
73: RETCODE resret, ret;
74: int i, j;
75: int arows;
76: unsigned int size;
77:
78: dbsetuserdata(H->link, &S->err);
79:
80: if (S->rows) {
81: /* clean them up */
82: free_rows(S TSRMLS_CC);
83: }
84:
85: if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
86: return 0;
87: }
88: if (FAIL == dbsqlexec(H->link)) {
89: return 0;
90: }
91:
92: resret = dbresults(H->link);
93: if (resret == FAIL) {
94: return 0;
95: }
96:
97: ret = dbnextrow(H->link);
98:
99: stmt->row_count = DBCOUNT(H->link);
100:
101: if (ret == NO_MORE_ROWS) {
102: return 1;
103: }
104:
105: if (!S->cols) {
106: S->ncols = dbnumcols(H->link);
107:
108: if (S->ncols <= 0) {
109: return 1;
110: }
111:
112: S->cols = ecalloc(S->ncols, sizeof(pdo_dblib_col));
113: stmt->column_count = S->ncols;
114:
115: for (i = 0, j = 0; i < S->ncols; i++) {
116: char *tmp = NULL;
117:
118: S->cols[i].coltype = dbcoltype(H->link, i+1);
119: S->cols[i].name = (char*)dbcolname(H->link, i+1);
120:
121: if (!strlen(S->cols[i].name)) {
122: if (j) {
123: spprintf(&tmp, 0, "computed%d", j++);
124: strlcpy(S->cols[i].name, tmp, strlen(tmp)+1);
125: efree(tmp);
126: } else {
127: S->cols[i].name = "computed";
128: j++;
129: }
130: }
131:
132: S->cols[i].source = (char*)dbcolsource(H->link, i+1);
133: tmp = estrdup(S->cols[i].source ? S->cols[i].source : "");
134: S->cols[i].source = tmp;
135: efree(tmp);
136:
137: S->cols[i].maxlen = dbcollen(H->link, i+1);
138: }
139: }
140:
141: arows = 100;
142: size = S->ncols * sizeof(pdo_dblib_colval);
143: S->rows = safe_emalloc(arows, size, 0);
144:
145: /* let's fetch all the data */
146: do {
147: if (S->nrows >= arows) {
148: arows *= 2;
149: S->rows = erealloc(S->rows, arows * size);
150: }
151: for (i = 0; i < S->ncols; i++) {
152: pdo_dblib_colval *val = &S->rows[S->nrows * S->ncols + i];
153:
154: if (dbdatlen(H->link, i+1) == 0 && dbdata(H->link, i+1) == NULL) {
155: val->len = 0;
156: val->data = NULL;
157: } else {
158: switch (S->cols[i].coltype) {
159: case SQLCHAR:
160: case SQLTEXT:
161: case SQLVARBINARY:
162: case SQLBINARY:
163: case SQLIMAGE:
164: val->len = dbdatlen(H->link, i+1);
165: val->data = emalloc(val->len + 1);
166: memcpy(val->data, dbdata(H->link, i+1), val->len);
167: val->data[val->len] = '\0';
168: break;
169: case SQLMONEY:
170: case SQLMONEY4:
171: case SQLMONEYN: {
172: DBFLT8 money_value;
173: dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLFLT8, (LPBYTE)&money_value, 8);
174: val->len = spprintf(&val->data, 0, "%.4f", money_value);
175: }
176: break;
177: #ifdef SQLUNIQUE
178: case SQLUNIQUE: {
179: #else
180: case 36: { /* FreeTDS hack, also used by ext/mssql */
181: #endif
182: val->len = 36+1;
183: val->data = emalloc(val->len + 1);
184:
185: /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
186: #ifdef SQLUNIQUE
187: val->len = dbconvert(NULL, SQLUNIQUE, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
188: #else
189: val->len = dbconvert(NULL, 36, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
190: #endif
191: php_strtoupper(val->data, val->len);
192: break;
193: }
194: default:
195: if (dbwillconvert(S->cols[i].coltype, SQLCHAR)) {
196: val->len = 32 + (2 * dbdatlen(H->link, i+1));
197: val->data = emalloc(val->len);
198:
199: val->len = dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1),
200: dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
201:
202: if (val->len >= 0) {
203: val->data[val->len] = '\0';
204: }
205: } else {
206: val->len = 0;
207: val->data = NULL;
208: }
209: }
210: }
211: }
212:
213: S->nrows++;
214:
215: ret = dbnextrow(H->link);
216:
217: if (ret == BUF_FULL) {
218: dbclrbuf(H->link, DBLASTROW(H->link)-1);
219: }
220: } while (ret != FAIL && ret != NO_MORE_ROWS);
221:
222: if (resret != NO_MORE_RESULTS) {
223: /* there are additional result sets available */
224: dbresults(H->link);
225: /* cancel pending rows */
226: dbcanquery(H->link);
227:
228: /* TODO: figure out a sane solution */
229: }
230:
231: S->current = -1;
232:
233: return 1;
234: }
235:
236: static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
237: enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
238: {
239: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
240:
241: if (!S->rows) {
242: return 0;
243: }
244:
245: if (++S->current < S->nrows) {
246: return 1;
247: }
248:
249: return 0;
250: }
251:
252: static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
253: {
254: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
255: struct pdo_column_data *col = &stmt->columns[colno];
256:
257: if (!S->rows) {
258: return 0;
259: }
260:
261: col->maxlen = S->cols[colno].maxlen;
262: col->namelen = strlen(S->cols[colno].name);
263: col->name = estrdup(S->cols[colno].name);
264: col->param_type = PDO_PARAM_STR;
265:
266: return 1;
267: }
268:
269: static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
270: unsigned long *len, int *caller_frees TSRMLS_DC)
271: {
272: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
273: pdo_dblib_colval *val = &S->rows[S->current * S->ncols + colno];
274:
275: *ptr = val->data;
276: *len = val->len;
277: return 1;
278: }
279:
280: static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
281: enum pdo_param_event event_type TSRMLS_DC)
282: {
283: return 1;
284: }
285:
286: static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
287: {
288: pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
289:
290: if (S->rows) {
291: free_rows(S TSRMLS_CC);
292: S->rows = NULL;
293: }
294:
295: return 1;
296: }
297:
298: struct pdo_stmt_methods dblib_stmt_methods = {
299: pdo_dblib_stmt_dtor,
300: pdo_dblib_stmt_execute,
301: pdo_dblib_stmt_fetch,
302: pdo_dblib_stmt_describe,
303: pdo_dblib_stmt_get_col,
304: pdo_dblib_stmt_param_hook,
305: NULL, /* set attr */
306: NULL, /* get attr */
307: NULL, /* meta */
308: NULL, /* nextrow */
309: dblib_dblib_stmt_cursor_closer
310: };
311:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>