Annotation of embedaddon/php/ext/pdo_dblib/dblib_stmt.c, revision 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>