Annotation of embedaddon/php/ext/oci8/oci8_statement.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: | Authors: Stig Sæther Bakken <ssb@php.net> |
! 16: | Thies C. Arntzen <thies@thieso.net> |
! 17: | |
! 18: | Collection support by Andy Sautins <asautins@veripost.net> |
! 19: | Temporary LOB support by David Benson <dbenson@mancala.com> |
! 20: | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
! 21: | |
! 22: | Redesigned by: Antony Dovgal <antony@zend.com> |
! 23: | Andi Gutmans <andi@zend.com> |
! 24: | Wez Furlong <wez@omniti.com> |
! 25: +----------------------------------------------------------------------+
! 26: */
! 27:
! 28: /* $Id: oci8_statement.c 321634 2012-01-01 13:15:04Z felipe $ */
! 29:
! 30:
! 31: #ifdef HAVE_CONFIG_H
! 32: #include "config.h"
! 33: #endif
! 34:
! 35: #include "php.h"
! 36: #include "ext/standard/info.h"
! 37: #include "php_ini.h"
! 38:
! 39: #if HAVE_OCI8
! 40:
! 41: #include "php_oci8.h"
! 42: #include "php_oci8_int.h"
! 43:
! 44: /* {{{ php_oci_statement_create()
! 45: Create statemend handle and allocate necessary resources */
! 46: php_oci_statement *php_oci_statement_create (php_oci_connection *connection, char *query, int query_len TSRMLS_DC)
! 47: {
! 48: php_oci_statement *statement;
! 49:
! 50: statement = ecalloc(1,sizeof(php_oci_statement));
! 51:
! 52: if (!query_len) {
! 53: /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */
! 54: PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
! 55: }
! 56:
! 57: PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL));
! 58:
! 59: if (query_len > 0) {
! 60: PHP_OCI_CALL_RETURN(connection->errcode, OCIStmtPrepare2,
! 61: (
! 62: connection->svc,
! 63: &(statement->stmt),
! 64: connection->err,
! 65: (text *)query,
! 66: query_len,
! 67: NULL,
! 68: 0,
! 69: OCI_NTV_SYNTAX,
! 70: OCI_DEFAULT
! 71: )
! 72: );
! 73: if (connection->errcode != OCI_SUCCESS) {
! 74: connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
! 75:
! 76: PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT));
! 77: PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
! 78:
! 79: efree(statement);
! 80: PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
! 81: return NULL;
! 82: }
! 83: }
! 84:
! 85: if (query && query_len) {
! 86: statement->last_query = estrndup(query, query_len);
! 87: statement->last_query_len = query_len;
! 88: }
! 89: else {
! 90: statement->last_query = NULL;
! 91: statement->last_query_len = 0;
! 92: }
! 93:
! 94: statement->connection = connection;
! 95: statement->has_data = 0;
! 96: statement->has_descr = 0;
! 97: statement->parent_stmtid = 0;
! 98: zend_list_addref(statement->connection->rsrc_id);
! 99:
! 100: if (OCI_G(default_prefetch) >= 0) {
! 101: php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC);
! 102: }
! 103:
! 104: PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
! 105:
! 106: OCI_G(num_statements)++;
! 107:
! 108: return statement;
! 109: }
! 110: /* }}} */
! 111:
! 112: /* {{{ php_oci_statement_set_prefetch()
! 113: Set prefetch buffer size for the statement (we're assuming that one row is ~1K sized) */
! 114: int php_oci_statement_set_prefetch(php_oci_statement *statement, long size TSRMLS_DC)
! 115: {
! 116: ub4 prefetch = size;
! 117:
! 118: if (size < 0) {
! 119: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0");
! 120: return 1;
! 121: }
! 122:
! 123: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err));
! 124:
! 125: if (statement->errcode != OCI_SUCCESS) {
! 126: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 127: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 128: return 1;
! 129: }
! 130:
! 131: return 0;
! 132: }
! 133: /* }}} */
! 134:
! 135: /* {{{ php_oci_cleanup_pre_fetch()
! 136: Helper function to cleanup ref-cursors and descriptors from the previous row */
! 137: int php_oci_cleanup_pre_fetch(void *data TSRMLS_DC)
! 138: {
! 139: php_oci_out_column *outcol = data;
! 140:
! 141: if (!outcol->is_descr && !outcol->is_cursor)
! 142: return ZEND_HASH_APPLY_KEEP;
! 143:
! 144: switch(outcol->data_type) {
! 145: case SQLT_CLOB:
! 146: case SQLT_BLOB:
! 147: case SQLT_RDD:
! 148: case SQLT_BFILE:
! 149: if (outcol->descid) {
! 150: zend_list_delete(outcol->descid);
! 151: outcol->descid = 0;
! 152: }
! 153: break;
! 154: case SQLT_RSET:
! 155: if (outcol->stmtid) {
! 156: zend_list_delete(outcol->stmtid);
! 157: outcol->stmtid = 0;
! 158: outcol->nested_statement = NULL;
! 159: }
! 160: break;
! 161: default:
! 162: break;
! 163: }
! 164: return ZEND_HASH_APPLY_KEEP;
! 165:
! 166: } /* }}} */
! 167:
! 168:
! 169: /* {{{ php_oci_statement_fetch()
! 170: Fetch a row from the statement */
! 171: int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
! 172: {
! 173: int i;
! 174: void *handlepp;
! 175: ub4 typep, iterp, idxp;
! 176: ub1 in_outp, piecep;
! 177: zend_bool piecewisecols = 0;
! 178:
! 179: php_oci_out_column *column;
! 180:
! 181: if (statement->has_descr && statement->columns) {
! 182: zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch TSRMLS_CC);
! 183: }
! 184:
! 185: PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
! 186:
! 187: if ( statement->errcode == OCI_NO_DATA || nrows == 0 ) {
! 188: if (statement->last_query == NULL) {
! 189: /* reset define-list for refcursors */
! 190: if (statement->columns) {
! 191: zend_hash_destroy(statement->columns);
! 192: efree(statement->columns);
! 193: statement->columns = NULL;
! 194: statement->ncolumns = 0;
! 195: }
! 196: statement->executed = 0;
! 197: }
! 198:
! 199: statement->errcode = 0; /* OCI_NO_DATA is NO error for us!!! */
! 200: statement->has_data = 0;
! 201:
! 202: if (nrows == 0) {
! 203: /* this is exactly what we requested */
! 204: return 0;
! 205: }
! 206: return 1;
! 207: }
! 208:
! 209: /* reset length for all piecewise columns */
! 210: for (i = 0; i < statement->ncolumns; i++) {
! 211: column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
! 212: if (column->piecewise) {
! 213: column->retlen4 = 0;
! 214: piecewisecols = 1;
! 215: }
! 216: }
! 217:
! 218: while (statement->errcode == OCI_NEED_DATA) {
! 219: if (piecewisecols) {
! 220: PHP_OCI_CALL_RETURN(statement->errcode,
! 221: OCIStmtGetPieceInfo,
! 222: (
! 223: statement->stmt,
! 224: statement->err,
! 225: &handlepp,
! 226: &typep,
! 227: &in_outp,
! 228: &iterp,
! 229: &idxp,
! 230: &piecep
! 231: )
! 232: );
! 233:
! 234: /* scan through our columns for a piecewise column with a matching handle */
! 235: for (i = 0; i < statement->ncolumns; i++) {
! 236: column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
! 237: if (column->piecewise && handlepp == column->oci_define) {
! 238: if (!column->data) {
! 239: column->data = (text *) ecalloc(1, PHP_OCI_PIECE_SIZE + 1);
! 240: } else {
! 241: column->data = erealloc(column->data, column->retlen4 + PHP_OCI_PIECE_SIZE + 1);
! 242: }
! 243: column->cb_retlen = PHP_OCI_PIECE_SIZE;
! 244:
! 245: /* and instruct fetch to fetch waiting piece into our buffer */
! 246: PHP_OCI_CALL(OCIStmtSetPieceInfo,
! 247: (
! 248: (void *) column->oci_define,
! 249: OCI_HTYPE_DEFINE,
! 250: statement->err,
! 251: ((char*)column->data) + column->retlen4,
! 252: &(column->cb_retlen),
! 253: piecep,
! 254: &column->indicator,
! 255: &column->retcode
! 256: )
! 257: );
! 258: }
! 259: }
! 260: }
! 261:
! 262: PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
! 263:
! 264: if (piecewisecols) {
! 265: for (i = 0; i < statement->ncolumns; i++) {
! 266: column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
! 267: if (column && column->piecewise && handlepp == column->oci_define) {
! 268: column->retlen4 += column->cb_retlen;
! 269: }
! 270: }
! 271: }
! 272: }
! 273:
! 274: if (statement->errcode == OCI_SUCCESS_WITH_INFO || statement->errcode == OCI_SUCCESS) {
! 275: statement->has_data = 1;
! 276:
! 277: /* do the stuff needed for OCIDefineByName */
! 278: for (i = 0; i < statement->ncolumns; i++) {
! 279: column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
! 280: if (column == NULL) {
! 281: continue;
! 282: }
! 283:
! 284: if (!column->define) {
! 285: continue;
! 286: }
! 287:
! 288: zval_dtor(column->define->zval);
! 289: php_oci_column_to_zval(column, column->define->zval, 0 TSRMLS_CC);
! 290: }
! 291:
! 292: return 0;
! 293: }
! 294:
! 295: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 296: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 297:
! 298: statement->has_data = 0;
! 299:
! 300: return 1;
! 301: }
! 302: /* }}} */
! 303:
! 304: /* {{{ php_oci_statement_get_column()
! 305: Get column from the result set */
! 306: php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, long column_index, char *column_name, int column_name_len TSRMLS_DC)
! 307: {
! 308: php_oci_out_column *column = NULL;
! 309: int i;
! 310:
! 311: if (statement->columns == NULL) { /* we release the columns at the end of a fetch */
! 312: return NULL;
! 313: }
! 314:
! 315: if (column_name) {
! 316: for (i = 0; i < statement->ncolumns; i++) {
! 317: column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
! 318: if (column == NULL) {
! 319: continue;
! 320: } else if (((int) column->name_len == column_name_len) && (!strncmp(column->name, column_name, column_name_len))) {
! 321: return column;
! 322: }
! 323: }
! 324: } else if (column_index != -1) {
! 325: if (zend_hash_index_find(statement->columns, column_index, (void **)&column) == FAILURE) {
! 326: return NULL;
! 327: }
! 328: return column;
! 329: }
! 330:
! 331: return NULL;
! 332: }
! 333: /* }}} */
! 334:
! 335: /* php_oci_define_callback() {{{ */
! 336: sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp)
! 337: {
! 338: php_oci_out_column *outcol = (php_oci_out_column *)ctx;
! 339: TSRMLS_FETCH();
! 340:
! 341: if (!outcol) {
! 342:
! 343: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid context pointer value");
! 344: return OCI_ERROR;
! 345: }
! 346:
! 347: switch(outcol->data_type) {
! 348: case SQLT_RSET: {
! 349: php_oci_statement *nested_stmt;
! 350:
! 351: nested_stmt = php_oci_statement_create(outcol->statement->connection, NULL, 0 TSRMLS_CC);
! 352: if (!nested_stmt) {
! 353: return OCI_ERROR;
! 354: }
! 355: nested_stmt->parent_stmtid = outcol->statement->id;
! 356: zend_list_addref(outcol->statement->id);
! 357: outcol->nested_statement = nested_stmt;
! 358: outcol->stmtid = nested_stmt->id;
! 359:
! 360: *bufpp = nested_stmt->stmt;
! 361: *alenpp = &(outcol->retlen4);
! 362: *piecep = OCI_ONE_PIECE;
! 363: *indpp = &(outcol->indicator);
! 364: *rcpp = &(outcol->retcode);
! 365: return OCI_CONTINUE;
! 366: }
! 367: break;
! 368: case SQLT_RDD:
! 369: case SQLT_BLOB:
! 370: case SQLT_CLOB:
! 371: case SQLT_BFILE: {
! 372: php_oci_descriptor *descr;
! 373: int dtype;
! 374:
! 375: if (outcol->data_type == SQLT_BFILE) {
! 376: dtype = OCI_DTYPE_FILE;
! 377: } else if (outcol->data_type == SQLT_RDD ) {
! 378: dtype = OCI_DTYPE_ROWID;
! 379: } else {
! 380: dtype = OCI_DTYPE_LOB;
! 381: }
! 382:
! 383: descr = php_oci_lob_create(outcol->statement->connection, dtype TSRMLS_CC);
! 384: if (!descr) {
! 385: return OCI_ERROR;
! 386: }
! 387: outcol->descid = descr->id;
! 388: descr->charset_form = outcol->charset_form;
! 389:
! 390: *bufpp = descr->descriptor;
! 391: *alenpp = &(outcol->retlen4);
! 392: *piecep = OCI_ONE_PIECE;
! 393: *indpp = &(outcol->indicator);
! 394: *rcpp = &(outcol->retcode);
! 395:
! 396: return OCI_CONTINUE;
! 397: }
! 398: break;
! 399: }
! 400: return OCI_ERROR;
! 401: }
! 402: /* }}} */
! 403:
! 404: /* {{{ php_oci_statement_execute()
! 405: Execute statement */
! 406: int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
! 407: {
! 408: php_oci_out_column *outcol;
! 409: php_oci_out_column column;
! 410: OCIParam *param = NULL;
! 411: text *colname;
! 412: ub4 counter;
! 413: ub2 define_type;
! 414: ub4 iters;
! 415: ub4 colcount;
! 416: ub2 dynamic;
! 417: dvoid *buf;
! 418:
! 419: switch (mode) {
! 420: case OCI_COMMIT_ON_SUCCESS:
! 421: case OCI_DESCRIBE_ONLY:
! 422: case OCI_DEFAULT:
! 423: /* only these are allowed */
! 424: break;
! 425: default:
! 426: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid execute mode given: %d", mode);
! 427: return 1;
! 428: break;
! 429: }
! 430:
! 431: if (!statement->stmttype) {
! 432: /* get statement type */
! 433: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
! 434:
! 435: if (statement->errcode != OCI_SUCCESS) {
! 436: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 437: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 438: return 1;
! 439: }
! 440: }
! 441:
! 442: if (statement->stmttype == OCI_STMT_SELECT) {
! 443: iters = 0;
! 444: } else {
! 445: iters = 1;
! 446: }
! 447:
! 448: if (statement->last_query) {
! 449: /* if we execute refcursors we don't have a query and
! 450: we don't want to execute!!! */
! 451:
! 452: if (statement->binds) {
! 453: int result = 0;
! 454: zend_hash_apply_with_argument(statement->binds, (apply_func_arg_t) php_oci_bind_pre_exec, (void *)&result TSRMLS_CC);
! 455: if (result) {
! 456: return 1;
! 457: }
! 458: }
! 459:
! 460: /* execute statement */
! 461: PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtExecute, (statement->connection->svc, statement->stmt, statement->err, iters, 0, NULL, NULL, mode));
! 462:
! 463: if (statement->errcode != OCI_SUCCESS) {
! 464: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 465: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 466: return 1;
! 467: }
! 468:
! 469: if (statement->binds) {
! 470: zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec TSRMLS_CC);
! 471: }
! 472:
! 473: if (mode & OCI_COMMIT_ON_SUCCESS) {
! 474: statement->connection->needs_commit = 0;
! 475: } else {
! 476: statement->connection->needs_commit = 1;
! 477: }
! 478: }
! 479:
! 480: if (statement->stmttype == OCI_STMT_SELECT && statement->executed == 0) {
! 481: /* we only need to do the define step is this very statement is executed the first time! */
! 482: statement->executed = 1;
! 483:
! 484: ALLOC_HASHTABLE(statement->columns);
! 485: zend_hash_init(statement->columns, 13, NULL, php_oci_column_hash_dtor, 0);
! 486:
! 487: counter = 1;
! 488:
! 489: /* get number of columns */
! 490: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err));
! 491:
! 492: if (statement->errcode != OCI_SUCCESS) {
! 493: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 494: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 495: return 1;
! 496: }
! 497:
! 498: statement->ncolumns = colcount;
! 499:
! 500: for (counter = 1; counter <= colcount; counter++) {
! 501: memset(&column,0,sizeof(php_oci_out_column));
! 502:
! 503: if (zend_hash_index_update(statement->columns, counter, &column, sizeof(php_oci_out_column), (void**) &outcol) == FAILURE) {
! 504: efree(statement->columns);
! 505: /* out of memory */
! 506: return 1;
! 507: }
! 508:
! 509: /* get column */
! 510: PHP_OCI_CALL_RETURN(statement->errcode, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)¶m, counter));
! 511:
! 512: if (statement->errcode != OCI_SUCCESS) {
! 513: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 514: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 515: return 1;
! 516: }
! 517:
! 518: /* get column datatype */
! 519: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err));
! 520:
! 521: if (statement->errcode != OCI_SUCCESS) {
! 522: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 523: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 524: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 525: return 1;
! 526: }
! 527:
! 528: /* get character set form */
! 529: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_form, (ub4 *)0, OCI_ATTR_CHARSET_FORM, statement->err));
! 530:
! 531: if (statement->errcode != OCI_SUCCESS) {
! 532: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 533: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 534: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 535: return 1;
! 536: }
! 537:
! 538: /* get character set id */
! 539: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_id, (ub4 *)0, OCI_ATTR_CHARSET_ID, statement->err));
! 540:
! 541: if (statement->errcode != OCI_SUCCESS) {
! 542: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 543: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 544: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 545: return 1;
! 546: }
! 547:
! 548: /* get size of the column */
! 549: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err));
! 550:
! 551: if (statement->errcode != OCI_SUCCESS) {
! 552: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 553: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 554: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 555: return 1;
! 556: }
! 557:
! 558: outcol->storage_size4 = outcol->data_size;
! 559: outcol->retlen = outcol->data_size;
! 560:
! 561: /* get scale of the column */
! 562: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err));
! 563:
! 564: if (statement->errcode != OCI_SUCCESS) {
! 565: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 566: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 567: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 568: return 1;
! 569: }
! 570:
! 571: /* get precision of the column */
! 572: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err));
! 573:
! 574: if (statement->errcode != OCI_SUCCESS) {
! 575: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 576: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 577: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 578: return 1;
! 579: }
! 580:
! 581: /* get name of the column */
! 582: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err));
! 583:
! 584: if (statement->errcode != OCI_SUCCESS) {
! 585: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 586: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 587: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 588: return 1;
! 589: }
! 590: PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
! 591:
! 592: outcol->name = estrndup((char*) colname, outcol->name_len);
! 593:
! 594: /* find a user-setted define */
! 595: if (statement->defines) {
! 596: if (zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define) == SUCCESS) {
! 597: if (outcol->define->type) {
! 598: outcol->data_type = outcol->define->type;
! 599: }
! 600: }
! 601: }
! 602:
! 603: buf = 0;
! 604: switch (outcol->data_type) {
! 605: case SQLT_RSET:
! 606: outcol->statement = statement; /* parent handle */
! 607:
! 608: define_type = SQLT_RSET;
! 609: outcol->is_cursor = 1;
! 610: outcol->statement->has_descr = 1;
! 611: outcol->storage_size4 = -1;
! 612: outcol->retlen = -1;
! 613: dynamic = OCI_DYNAMIC_FETCH;
! 614: break;
! 615:
! 616: case SQLT_RDD: /* ROWID */
! 617: case SQLT_BLOB: /* binary LOB */
! 618: case SQLT_CLOB: /* character LOB */
! 619: case SQLT_BFILE: /* binary file LOB */
! 620: outcol->statement = statement; /* parent handle */
! 621:
! 622: define_type = outcol->data_type;
! 623: outcol->is_descr = 1;
! 624: outcol->statement->has_descr = 1;
! 625: outcol->storage_size4 = -1;
! 626: dynamic = OCI_DYNAMIC_FETCH;
! 627: break;
! 628:
! 629: case SQLT_LNG:
! 630: case SQLT_LBI:
! 631: if (outcol->data_type == SQLT_LBI) {
! 632: define_type = SQLT_BIN;
! 633: } else {
! 634: define_type = SQLT_CHR;
! 635: }
! 636: outcol->storage_size4 = PHP_OCI_MAX_DATA_SIZE;
! 637: outcol->piecewise = 1;
! 638: dynamic = OCI_DYNAMIC_FETCH;
! 639: break;
! 640:
! 641: case SQLT_BIN:
! 642: default:
! 643: define_type = SQLT_CHR;
! 644: if (outcol->data_type == SQLT_BIN) {
! 645: define_type = SQLT_BIN;
! 646: }
! 647: if ((outcol->data_type == SQLT_DAT) || (outcol->data_type == SQLT_NUM)
! 648: #ifdef SQLT_TIMESTAMP
! 649: || (outcol->data_type == SQLT_TIMESTAMP)
! 650: #endif
! 651: #ifdef SQLT_TIMESTAMP_TZ
! 652: || (outcol->data_type == SQLT_TIMESTAMP_TZ)
! 653: #endif
! 654: #ifdef SQLT_TIMESTAMP_LTZ
! 655: || (outcol->data_type == SQLT_TIMESTAMP_LTZ)
! 656: #endif
! 657: #ifdef SQLT_INTERVAL_YM
! 658: || (outcol->data_type == SQLT_INTERVAL_YM)
! 659: #endif
! 660: #ifdef SQLT_INTERVAL_DS
! 661: || (outcol->data_type == SQLT_INTERVAL_DS)
! 662: #endif
! 663: ) {
! 664: outcol->storage_size4 = 512; /* XXX this should fit "most" NLS date-formats and Numbers */
! 665: #if defined(SQLT_IBFLOAT) && defined(SQLT_IBDOUBLE)
! 666: } else if (outcol->data_type == SQLT_IBFLOAT || outcol->data_type == SQLT_IBDOUBLE) {
! 667: outcol->storage_size4 = 1024;
! 668: #endif
! 669: } else {
! 670: outcol->storage_size4++; /* add one for string terminator */
! 671: }
! 672:
! 673: outcol->storage_size4 *= 3;
! 674:
! 675: dynamic = OCI_DEFAULT;
! 676: buf = outcol->data = (text *) safe_emalloc(1, outcol->storage_size4, 0);
! 677: memset(buf, 0, outcol->storage_size4);
! 678: break;
! 679: }
! 680:
! 681: if (dynamic == OCI_DYNAMIC_FETCH) {
! 682: PHP_OCI_CALL_RETURN(statement->errcode,
! 683: OCIDefineByPos,
! 684: (
! 685: statement->stmt, /* IN/OUT handle to the requested SQL query */
! 686: (OCIDefine **)&outcol->oci_define, /* IN/OUT pointer to a pointer to a define handle */
! 687: statement->err, /* IN/OUT An error handle */
! 688: counter, /* IN position in the select list */
! 689: (dvoid *)NULL, /* IN/OUT pointer to a buffer */
! 690: outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
! 691: define_type, /* IN The data type */
! 692: (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
! 693: (ub2 *)NULL, /* IN/OUT Pointer to array of length of data fetched */
! 694: (ub2 *)NULL, /* OUT Pointer to array of column-level return codes */
! 695: OCI_DYNAMIC_FETCH /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
! 696: )
! 697: );
! 698:
! 699: } else {
! 700: PHP_OCI_CALL_RETURN(statement->errcode,
! 701: OCIDefineByPos,
! 702: (
! 703: statement->stmt, /* IN/OUT handle to the requested SQL query */
! 704: (OCIDefine **)&outcol->oci_define, /* IN/OUT pointer to a pointer to a define handle */
! 705: statement->err, /* IN/OUT An error handle */
! 706: counter, /* IN position in the select list */
! 707: (dvoid *)buf, /* IN/OUT pointer to a buffer */
! 708: outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
! 709: define_type, /* IN The data type */
! 710: (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
! 711: (ub2 *)&outcol->retlen, /* IN/OUT Pointer to array of length of data fetched */
! 712: (ub2 *)&outcol->retcode, /* OUT Pointer to array of column-level return codes */
! 713: OCI_DEFAULT /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
! 714: )
! 715: );
! 716:
! 717: }
! 718:
! 719: if (statement->errcode != OCI_SUCCESS) {
! 720: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 721: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 722: return 0;
! 723: }
! 724:
! 725: /* additional OCIDefineDynamic() call */
! 726: switch (outcol->data_type) {
! 727: case SQLT_RSET:
! 728: case SQLT_RDD:
! 729: case SQLT_BLOB:
! 730: case SQLT_CLOB:
! 731: case SQLT_BFILE:
! 732: PHP_OCI_CALL_RETURN(statement->errcode,
! 733: OCIDefineDynamic,
! 734: (
! 735: outcol->oci_define,
! 736: statement->err,
! 737: (dvoid *)outcol,
! 738: php_oci_define_callback
! 739: )
! 740: );
! 741:
! 742: break;
! 743: }
! 744: }
! 745: }
! 746:
! 747: return 0;
! 748: }
! 749: /* }}} */
! 750:
! 751: /* {{{ php_oci_statement_cancel()
! 752: Cancel statement */
! 753: int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC)
! 754: {
! 755:
! 756: return php_oci_statement_fetch(statement, 0 TSRMLS_CC);
! 757:
! 758: } /* }}} */
! 759:
! 760: /* {{{ php_oci_statement_free()
! 761: Destroy statement handle and free associated resources */
! 762: void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC)
! 763: {
! 764: if (statement->stmt) {
! 765: if (statement->last_query_len) { /* FIXME: magical */
! 766: PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT));
! 767: } else {
! 768: PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
! 769: }
! 770: statement->stmt = 0;
! 771: }
! 772:
! 773: if (statement->err) {
! 774: PHP_OCI_CALL(OCIHandleFree, (statement->err, OCI_HTYPE_ERROR));
! 775: statement->err = 0;
! 776: }
! 777:
! 778: if (statement->last_query) {
! 779: efree(statement->last_query);
! 780: }
! 781:
! 782: if (statement->columns) {
! 783: zend_hash_destroy(statement->columns);
! 784: efree(statement->columns);
! 785: }
! 786:
! 787: if (statement->binds) {
! 788: zend_hash_destroy(statement->binds);
! 789: efree(statement->binds);
! 790: }
! 791:
! 792: if (statement->defines) {
! 793: zend_hash_destroy(statement->defines);
! 794: efree(statement->defines);
! 795: }
! 796:
! 797: if (statement->parent_stmtid) {
! 798: zend_list_delete(statement->parent_stmtid);
! 799: }
! 800:
! 801: zend_list_delete(statement->connection->rsrc_id);
! 802: efree(statement);
! 803:
! 804: OCI_G(num_statements)--;
! 805: } /* }}} */
! 806:
! 807: /* {{{ php_oci_bind_pre_exec()
! 808: Helper function */
! 809: int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC)
! 810: {
! 811: php_oci_bind *bind = (php_oci_bind *) data;
! 812:
! 813: *(int *)result = 0;
! 814:
! 815: if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
! 816: /* These checks are currently valid for oci_bind_by_name, not
! 817: * oci_bind_array_by_name. Also bind->type and
! 818: * bind->indicator are not used for oci_bind_array_by_name.
! 819: */
! 820: return 0;
! 821: }
! 822: switch (bind->type) {
! 823: case SQLT_NTY:
! 824: case SQLT_BFILEE:
! 825: case SQLT_CFILEE:
! 826: case SQLT_CLOB:
! 827: case SQLT_BLOB:
! 828: case SQLT_RDD:
! 829: if (Z_TYPE_P(bind->zval) != IS_OBJECT) {
! 830: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 831: *(int *)result = 1;
! 832: }
! 833: break;
! 834:
! 835: case SQLT_INT:
! 836: case SQLT_NUM:
! 837: if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) {
! 838: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 839: *(int *)result = 1;
! 840: }
! 841: break;
! 842:
! 843: case SQLT_LBI:
! 844: case SQLT_BIN:
! 845: case SQLT_LNG:
! 846: case SQLT_AFC:
! 847: case SQLT_CHR:
! 848: if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) {
! 849: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 850: *(int *)result = 1;
! 851: }
! 852: break;
! 853:
! 854: case SQLT_RSET:
! 855: if (Z_TYPE_P(bind->zval) != IS_RESOURCE) {
! 856: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 857: *(int *)result = 1;
! 858: }
! 859: break;
! 860: }
! 861:
! 862: /* reset all bind stuff to a normal state..-. */
! 863: bind->indicator = 0;
! 864:
! 865: return 0;
! 866: }
! 867: /* }}} */
! 868:
! 869: /* {{{ php_oci_bind_post_exec()
! 870: Helper function */
! 871: int php_oci_bind_post_exec(void *data TSRMLS_DC)
! 872: {
! 873: php_oci_bind *bind = (php_oci_bind *) data;
! 874: php_oci_connection *connection = bind->parent_statement->connection;
! 875:
! 876: if (bind->indicator == -1) { /* NULL */
! 877: zval *val = bind->zval;
! 878: if (Z_TYPE_P(val) == IS_STRING) {
! 879: *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */
! 880: }
! 881: zval_dtor(val);
! 882: ZVAL_NULL(val);
! 883: } else if (Z_TYPE_P(bind->zval) == IS_STRING
! 884: && Z_STRLEN_P(bind->zval) > 0
! 885: && Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] != '\0') {
! 886: /* The post- PHP 5.3 feature for "interned" strings disallows
! 887: * their reallocation but (i) any IN binds either interned or
! 888: * not should already be null terminated and (ii) for OUT
! 889: * binds, php_oci_bind_out_callback() should have allocated a
! 890: * new string that we can modify here.
! 891: */
! 892: Z_STRVAL_P(bind->zval) = erealloc(Z_STRVAL_P(bind->zval), Z_STRLEN_P(bind->zval)+1);
! 893: Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0';
! 894: } else if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
! 895: int i;
! 896: zval **entry;
! 897: HashTable *hash = HASH_OF(bind->zval);
! 898:
! 899: zend_hash_internal_pointer_reset(hash);
! 900:
! 901: switch (bind->array.type) {
! 902: case SQLT_NUM:
! 903: case SQLT_INT:
! 904: case SQLT_LNG:
! 905: for (i = 0; i < bind->array.current_length; i++) {
! 906: if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 907: zval_dtor(*entry);
! 908: ZVAL_LONG(*entry, ((ub4 *)(bind->array.elements))[i]);
! 909: zend_hash_move_forward(hash);
! 910: } else {
! 911: add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
! 912: }
! 913: }
! 914: break;
! 915: case SQLT_FLT:
! 916: for (i = 0; i < bind->array.current_length; i++) {
! 917: if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 918: zval_dtor(*entry);
! 919: ZVAL_DOUBLE(*entry, ((double *)(bind->array.elements))[i]);
! 920: zend_hash_move_forward(hash);
! 921: } else {
! 922: add_next_index_double(bind->zval, ((double *)(bind->array.elements))[i]);
! 923: }
! 924: }
! 925: break;
! 926: case SQLT_ODT:
! 927: for (i = 0; i < bind->array.current_length; i++) {
! 928: oratext buff[1024];
! 929: ub4 buff_len = 1024;
! 930:
! 931: memset((void*)buff,0,sizeof(buff));
! 932:
! 933: if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 934: PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
! 935: zval_dtor(*entry);
! 936:
! 937: if (connection->errcode != OCI_SUCCESS) {
! 938: connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
! 939: PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
! 940: ZVAL_NULL(*entry);
! 941: } else {
! 942: ZVAL_STRINGL(*entry, (char *)buff, buff_len, 1);
! 943: }
! 944: zend_hash_move_forward(hash);
! 945: } else {
! 946: PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
! 947: if (connection->errcode != OCI_SUCCESS) {
! 948: connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
! 949: PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
! 950: add_next_index_null(bind->zval);
! 951: } else {
! 952: add_next_index_stringl(bind->zval, (char *)buff, buff_len, 1);
! 953: }
! 954: }
! 955: }
! 956: break;
! 957:
! 958: case SQLT_AFC:
! 959: case SQLT_CHR:
! 960: case SQLT_VCS:
! 961: case SQLT_AVC:
! 962: case SQLT_STR:
! 963: case SQLT_LVC:
! 964: for (i = 0; i < bind->array.current_length; i++) {
! 965: /* int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); */
! 966: int curr_element_length = bind->array.element_lengths[i];
! 967: if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 968: zval_dtor(*entry);
! 969: ZVAL_STRINGL(*entry, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
! 970: zend_hash_move_forward(hash);
! 971: } else {
! 972: add_next_index_stringl(bind->zval, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
! 973: }
! 974: }
! 975: break;
! 976: }
! 977: }
! 978:
! 979: return 0;
! 980: }
! 981: /* }}} */
! 982:
! 983: /* {{{ php_oci_bind_by_name()
! 984: Bind zval to the given placeholder */
! 985: int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long maxlength, ub2 type TSRMLS_DC)
! 986: {
! 987: php_oci_collection *bind_collection = NULL;
! 988: php_oci_descriptor *bind_descriptor = NULL;
! 989: php_oci_statement *bind_statement = NULL;
! 990: dvoid *oci_desc = NULL;
! 991: /* dvoid *php_oci_collection = NULL; */
! 992: OCIStmt *oci_stmt = NULL;
! 993: dvoid *bind_data = NULL;
! 994: php_oci_bind bind, *old_bind, *bindp;
! 995: int mode = OCI_DATA_AT_EXEC;
! 996: sb4 value_sz = -1;
! 997:
! 998: switch (type) {
! 999: case SQLT_NTY:
! 1000: {
! 1001: zval **tmp;
! 1002:
! 1003: if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
! 1004: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
! 1005: return 1;
! 1006: }
! 1007:
! 1008: PHP_OCI_ZVAL_TO_COLLECTION_EX(*tmp, bind_collection);
! 1009: value_sz = sizeof(void*);
! 1010: mode = OCI_DEFAULT;
! 1011:
! 1012: if (!bind_collection->collection) {
! 1013: return 1;
! 1014: }
! 1015: }
! 1016: break;
! 1017: case SQLT_BFILEE:
! 1018: case SQLT_CFILEE:
! 1019: case SQLT_CLOB:
! 1020: case SQLT_BLOB:
! 1021: case SQLT_RDD:
! 1022: {
! 1023: zval **tmp;
! 1024:
! 1025: if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
! 1026: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
! 1027: return 1;
! 1028: }
! 1029:
! 1030: PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, bind_descriptor);
! 1031:
! 1032: value_sz = sizeof(void*);
! 1033:
! 1034: oci_desc = bind_descriptor->descriptor;
! 1035:
! 1036: if (!oci_desc) {
! 1037: return 1;
! 1038: }
! 1039: }
! 1040: break;
! 1041:
! 1042: case SQLT_INT:
! 1043: case SQLT_NUM:
! 1044: if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
! 1045: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 1046: return 1;
! 1047: }
! 1048: convert_to_long(var);
! 1049: bind_data = (ub4 *)&Z_LVAL_P(var);
! 1050: value_sz = sizeof(ub4);
! 1051: mode = OCI_DEFAULT;
! 1052: break;
! 1053:
! 1054: case SQLT_LBI:
! 1055: case SQLT_BIN:
! 1056: case SQLT_LNG:
! 1057: case SQLT_AFC:
! 1058: case SQLT_CHR: /* SQLT_CHR is the default value when type was not specified */
! 1059: if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
! 1060: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 1061: return 1;
! 1062: }
! 1063: if (Z_TYPE_P(var) != IS_NULL) {
! 1064: convert_to_string(var);
! 1065: }
! 1066: if (maxlength == -1) {
! 1067: value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0;
! 1068: } else {
! 1069: value_sz = maxlength;
! 1070: }
! 1071: break;
! 1072:
! 1073: case SQLT_RSET:
! 1074: if (Z_TYPE_P(var) != IS_RESOURCE) {
! 1075: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
! 1076: return 1;
! 1077: }
! 1078: PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement);
! 1079: value_sz = sizeof(void*);
! 1080:
! 1081: oci_stmt = bind_statement->stmt;
! 1082:
! 1083: if (!oci_stmt) {
! 1084: return 1;
! 1085: }
! 1086: break;
! 1087:
! 1088: default:
! 1089: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %d", (int)type);
! 1090: return 1;
! 1091: break;
! 1092: }
! 1093:
! 1094: if (value_sz == 0) {
! 1095: value_sz = 1;
! 1096: }
! 1097:
! 1098: if (!statement->binds) {
! 1099: ALLOC_HASHTABLE(statement->binds);
! 1100: zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
! 1101: }
! 1102:
! 1103: memset((void*)&bind,0,sizeof(php_oci_bind));
! 1104: if (zend_hash_find(statement->binds, name, name_len + 1, (void **)&old_bind) == SUCCESS) {
! 1105: bindp = old_bind;
! 1106: if (bindp->zval) {
! 1107: zval_ptr_dtor(&bindp->zval);
! 1108: }
! 1109: } else {
! 1110: zend_hash_update(statement->binds, name, name_len + 1, &bind, sizeof(php_oci_bind), (void **)&bindp);
! 1111: }
! 1112:
! 1113: bindp->descriptor = oci_desc;
! 1114: bindp->statement = oci_stmt;
! 1115: bindp->parent_statement = statement;
! 1116: bindp->zval = var;
! 1117: bindp->type = type;
! 1118: zval_add_ref(&var);
! 1119:
! 1120: PHP_OCI_CALL_RETURN(statement->errcode,
! 1121: OCIBindByName,
! 1122: (
! 1123: statement->stmt, /* statement handle */
! 1124: (OCIBind **)&bindp->bind, /* bind hdl (will alloc) */
! 1125: statement->err, /* error handle */
! 1126: (text*) name, /* placeholder name */
! 1127: name_len, /* placeholder length */
! 1128: (dvoid *)bind_data, /* in/out data */
! 1129: value_sz, /* PHP_OCI_MAX_DATA_SIZE, */ /* max size of input/output data */
! 1130: type, /* in/out data type */
! 1131: (dvoid *)&bindp->indicator, /* indicator (ignored) */
! 1132: (ub2 *)0, /* size array (ignored) */
! 1133: (ub2 *)&bindp->retcode, /* return code (ignored) */
! 1134: (ub4)0, /* maxarr_len (PL/SQL only?) */
! 1135: (ub4 *)0, /* actual array size (PL/SQL only?) */
! 1136: mode /* mode */
! 1137: )
! 1138: );
! 1139:
! 1140: if (statement->errcode != OCI_SUCCESS) {
! 1141: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1142: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1143: return 1;
! 1144: }
! 1145:
! 1146: if (mode == OCI_DATA_AT_EXEC) {
! 1147: PHP_OCI_CALL_RETURN(statement->errcode, OCIBindDynamic,
! 1148: (
! 1149: bindp->bind,
! 1150: statement->err,
! 1151: (dvoid *)bindp,
! 1152: php_oci_bind_in_callback,
! 1153: (dvoid *)bindp,
! 1154: php_oci_bind_out_callback
! 1155: )
! 1156: );
! 1157:
! 1158: if (statement->errcode != OCI_SUCCESS) {
! 1159: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1160: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1161: return 1;
! 1162: }
! 1163: }
! 1164:
! 1165: if (type == SQLT_NTY) {
! 1166: /* Bind object */
! 1167: PHP_OCI_CALL_RETURN(statement->errcode, OCIBindObject,
! 1168: (
! 1169: bindp->bind,
! 1170: statement->err,
! 1171: bind_collection->tdo,
! 1172: (dvoid **) &(bind_collection->collection),
! 1173: (ub4 *) 0,
! 1174: (dvoid **) 0,
! 1175: (ub4 *) 0
! 1176: )
! 1177: );
! 1178:
! 1179: if (statement->errcode) {
! 1180: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1181: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1182: return 1;
! 1183: }
! 1184: }
! 1185:
! 1186: return 0;
! 1187: } /* }}} */
! 1188:
! 1189: /* {{{ php_oci_bind_in_callback()
! 1190: Callback used when binding LOBs and VARCHARs */
! 1191: sb4 php_oci_bind_in_callback(
! 1192: dvoid *ictxp, /* context pointer */
! 1193: OCIBind *bindp, /* bind handle */
! 1194: ub4 iter, /* 0-based execute iteration value */
! 1195: ub4 index, /* index of current array for PL/SQL or row index for SQL */
! 1196: dvoid **bufpp, /* pointer to data */
! 1197: ub4 *alenp, /* size after value/piece has been read */
! 1198: ub1 *piecep, /* which piece */
! 1199: dvoid **indpp) /* indicator value */
! 1200: {
! 1201: php_oci_bind *phpbind;
! 1202: zval *val;
! 1203: TSRMLS_FETCH();
! 1204:
! 1205: if (!(phpbind=(php_oci_bind *)ictxp) || !(val = phpbind->zval)) {
! 1206: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
! 1207: return OCI_ERROR;
! 1208: }
! 1209:
! 1210: if (ZVAL_IS_NULL(val)) {
! 1211: /* we're going to insert a NULL column */
! 1212: phpbind->indicator = -1;
! 1213: *bufpp = 0;
! 1214: *alenp = -1;
! 1215: *indpp = (dvoid *)&phpbind->indicator;
! 1216: } else if ((phpbind->descriptor == 0) && (phpbind->statement == 0)) {
! 1217: /* "normal string bind */
! 1218: convert_to_string(val);
! 1219:
! 1220: *bufpp = Z_STRVAL_P(val);
! 1221: *alenp = Z_STRLEN_P(val);
! 1222: *indpp = (dvoid *)&phpbind->indicator;
! 1223: } else if (phpbind->statement != 0) {
! 1224: /* RSET */
! 1225: *bufpp = phpbind->statement;
! 1226: *alenp = -1; /* seems to be allright */
! 1227: *indpp = (dvoid *)&phpbind->indicator;
! 1228: } else {
! 1229: /* descriptor bind */
! 1230: *bufpp = phpbind->descriptor;
! 1231: *alenp = -1; /* seems to be allright */
! 1232: *indpp = (dvoid *)&phpbind->indicator;
! 1233: }
! 1234:
! 1235: *piecep = OCI_ONE_PIECE; /* pass all data in one go */
! 1236:
! 1237: return OCI_CONTINUE;
! 1238: }/* }}} */
! 1239:
! 1240: /* {{{ php_oci_bind_out_callback()
! 1241: Callback used when binding LOBs and VARCHARs */
! 1242: sb4 php_oci_bind_out_callback(
! 1243: dvoid *octxp, /* context pointer */
! 1244: OCIBind *bindp, /* bind handle */
! 1245: ub4 iter, /* 0-based execute iteration value */
! 1246: ub4 index, /* index of current array for PL/SQL or row index for SQL */
! 1247: dvoid **bufpp, /* pointer to data */
! 1248: ub4 **alenpp, /* size after value/piece has been read */
! 1249: ub1 *piecep, /* which piece */
! 1250: dvoid **indpp, /* indicator value */
! 1251: ub2 **rcodepp) /* return code */
! 1252: {
! 1253: php_oci_bind *phpbind;
! 1254: zval *val;
! 1255: sb4 retval = OCI_ERROR;
! 1256: TSRMLS_FETCH();
! 1257:
! 1258: if (!(phpbind=(php_oci_bind *)octxp) || !(val = phpbind->zval)) {
! 1259: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
! 1260: return retval;
! 1261: }
! 1262:
! 1263: if (Z_TYPE_P(val) == IS_RESOURCE) {
! 1264: /* Processing for ref-cursor out binds */
! 1265: if (phpbind->statement != NULL) {
! 1266: *bufpp = phpbind->statement;
! 1267: *alenpp = &phpbind->dummy_len;
! 1268: *piecep = OCI_ONE_PIECE;
! 1269: *rcodepp = &phpbind->retcode;
! 1270: *indpp = &phpbind->indicator;
! 1271: }
! 1272: retval = OCI_CONTINUE;
! 1273: } else if (Z_TYPE_P(val) == IS_OBJECT) {
! 1274: zval **tmp;
! 1275: php_oci_descriptor *desc;
! 1276:
! 1277: if (!phpbind->descriptor) {
! 1278: return OCI_ERROR;
! 1279: }
! 1280:
! 1281: /* Do not use the cached lob size if the descriptor is an
! 1282: * out-bind as the contents would have been changed for in/out
! 1283: * binds (Bug #46994).
! 1284: */
! 1285: if (zend_hash_find(Z_OBJPROP_P(val), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
! 1286: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find object outbind descriptor property");
! 1287: return OCI_ERROR;
! 1288: }
! 1289: PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, desc);
! 1290: desc->lob_size = -1; /* force OCI8 to update cached size */
! 1291:
! 1292: *alenpp = &phpbind->dummy_len;
! 1293: *bufpp = phpbind->descriptor;
! 1294: *piecep = OCI_ONE_PIECE;
! 1295: *rcodepp = &phpbind->retcode;
! 1296: *indpp = &phpbind->indicator;
! 1297: retval = OCI_CONTINUE;
! 1298: } else {
! 1299: convert_to_string(val);
! 1300: zval_dtor(val);
! 1301:
! 1302: Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */
! 1303: Z_STRVAL_P(val) = ecalloc(1, Z_STRLEN_P(phpbind->zval) + 1);
! 1304:
! 1305: /* XXX we assume that zend-zval len has 4 bytes */
! 1306: *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval);
! 1307: *bufpp = Z_STRVAL_P(phpbind->zval);
! 1308: *piecep = OCI_ONE_PIECE;
! 1309: *rcodepp = &phpbind->retcode;
! 1310: *indpp = &phpbind->indicator;
! 1311: retval = OCI_CONTINUE;
! 1312: }
! 1313:
! 1314: return retval;
! 1315: }
! 1316: /* }}} */
! 1317:
! 1318: /* {{{ php_oci_statement_get_column_helper()
! 1319: Helper function to get column by name and index */
! 1320: php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data)
! 1321: {
! 1322: zval *z_statement, *column_index;
! 1323: php_oci_statement *statement;
! 1324: php_oci_out_column *column;
! 1325:
! 1326: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_statement, &column_index) == FAILURE) {
! 1327: return NULL;
! 1328: }
! 1329:
! 1330: statement = (php_oci_statement *) zend_fetch_resource(&z_statement TSRMLS_CC, -1, "oci8 statement", NULL, 1, le_statement);
! 1331:
! 1332: if (!statement) {
! 1333: return NULL;
! 1334: }
! 1335:
! 1336: if (need_data && !statement->has_data) {
! 1337: return NULL;
! 1338: }
! 1339:
! 1340: if (Z_TYPE_P(column_index) == IS_STRING) {
! 1341: column = php_oci_statement_get_column(statement, -1, Z_STRVAL_P(column_index), Z_STRLEN_P(column_index) TSRMLS_CC);
! 1342: if (!column) {
! 1343: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column name \"%s\"", Z_STRVAL_P(column_index));
! 1344: return NULL;
! 1345: }
! 1346: } else {
! 1347: zval tmp;
! 1348: /* NB: for PHP4 compat only, it should be using 'Z' instead */
! 1349: tmp = *column_index;
! 1350: zval_copy_ctor(&tmp);
! 1351: convert_to_long(&tmp);
! 1352: column = php_oci_statement_get_column(statement, Z_LVAL(tmp), NULL, 0 TSRMLS_CC);
! 1353: if (!column) {
! 1354: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column index \"%ld\"", Z_LVAL(tmp));
! 1355: zval_dtor(&tmp);
! 1356: return NULL;
! 1357: }
! 1358: zval_dtor(&tmp);
! 1359: }
! 1360: return column;
! 1361: } /* }}} */
! 1362:
! 1363: /* {{{ php_oci_statement_get_type()
! 1364: Return type of the statement */
! 1365: int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC)
! 1366: {
! 1367: ub2 statement_type;
! 1368:
! 1369: *type = 0;
! 1370:
! 1371: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
! 1372:
! 1373: if (statement->errcode != OCI_SUCCESS) {
! 1374: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1375: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1376: return 1;
! 1377: }
! 1378:
! 1379: *type = statement_type;
! 1380:
! 1381: return 0;
! 1382: } /* }}} */
! 1383:
! 1384: /* {{{ php_oci_statement_get_numrows()
! 1385: Get the number of rows fetched to the clientside (NOT the number of rows in the result set) */
! 1386: int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC)
! 1387: {
! 1388: ub4 statement_numrows;
! 1389:
! 1390: *numrows = 0;
! 1391:
! 1392: PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err));
! 1393:
! 1394: if (statement->errcode != OCI_SUCCESS) {
! 1395: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1396: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1397: return 1;
! 1398: }
! 1399:
! 1400: *numrows = statement_numrows;
! 1401:
! 1402: return 0;
! 1403: } /* }}} */
! 1404:
! 1405: /* {{{ php_oci_bind_array_by_name()
! 1406: Bind arrays to PL/SQL types */
! 1407: int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC)
! 1408: {
! 1409: php_oci_bind *bind, *bindp;
! 1410:
! 1411: convert_to_array(var);
! 1412:
! 1413: if (maxlength < -1) {
! 1414: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid max length value (%ld)", maxlength);
! 1415: return 1;
! 1416: }
! 1417:
! 1418: switch(type) {
! 1419: case SQLT_NUM:
! 1420: case SQLT_INT:
! 1421: case SQLT_LNG:
! 1422: bind = php_oci_bind_array_helper_number(var, max_table_length TSRMLS_CC);
! 1423: break;
! 1424:
! 1425: case SQLT_FLT:
! 1426: bind = php_oci_bind_array_helper_double(var, max_table_length TSRMLS_CC);
! 1427: break;
! 1428:
! 1429: case SQLT_AFC:
! 1430: case SQLT_CHR:
! 1431: case SQLT_VCS:
! 1432: case SQLT_AVC:
! 1433: case SQLT_STR:
! 1434: case SQLT_LVC:
! 1435: if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(var)) == 0) {
! 1436: php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must provide max length value for empty arrays");
! 1437: return 1;
! 1438: }
! 1439: bind = php_oci_bind_array_helper_string(var, max_table_length, maxlength TSRMLS_CC);
! 1440: break;
! 1441: case SQLT_ODT:
! 1442: bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection TSRMLS_CC);
! 1443: break;
! 1444: default:
! 1445: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %ld", type);
! 1446: return 1;
! 1447: break;
! 1448: }
! 1449:
! 1450: if (bind == NULL) {
! 1451: /* failed to generate bind struct */
! 1452: return 1;
! 1453: }
! 1454:
! 1455: if (!statement->binds) {
! 1456: ALLOC_HASHTABLE(statement->binds);
! 1457: zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
! 1458: }
! 1459:
! 1460: zend_hash_update(statement->binds, name, name_len + 1, bind, sizeof(php_oci_bind), (void **)&bindp);
! 1461:
! 1462: bindp->descriptor = NULL;
! 1463: bindp->statement = NULL;
! 1464: bindp->parent_statement = statement;
! 1465: bindp->bind = NULL;
! 1466: bindp->zval = var;
! 1467: bindp->array.type = type;
! 1468: bindp->indicator = 0; /* not used for array binds */
! 1469: bindp->type = 0; /* not used for array binds */
! 1470:
! 1471: zval_add_ref(&var);
! 1472:
! 1473: PHP_OCI_CALL_RETURN(statement->errcode,
! 1474: OCIBindByName,
! 1475: (
! 1476: statement->stmt,
! 1477: (OCIBind **)&bindp->bind,
! 1478: statement->err,
! 1479: (text *)name,
! 1480: name_len,
! 1481: (dvoid *) bindp->array.elements,
! 1482: (sb4) bind->array.max_length,
! 1483: (ub2)type,
! 1484: (dvoid *)bindp->array.indicators,
! 1485: (ub2 *)bind->array.element_lengths,
! 1486: (ub2 *)0, /* bindp->array.retcodes, */
! 1487: (ub4) max_table_length,
! 1488: (ub4 *) &(bindp->array.current_length),
! 1489: (ub4) OCI_DEFAULT
! 1490: )
! 1491: );
! 1492:
! 1493:
! 1494: if (statement->errcode != OCI_SUCCESS) {
! 1495: efree(bind);
! 1496: statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
! 1497: PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
! 1498: return 1;
! 1499: }
! 1500: efree(bind);
! 1501: return 0;
! 1502: } /* }}} */
! 1503:
! 1504: /* {{{ php_oci_bind_array_helper_string()
! 1505: Bind arrays to PL/SQL types */
! 1506: php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC)
! 1507: {
! 1508: php_oci_bind *bind;
! 1509: ub4 i;
! 1510: HashTable *hash;
! 1511: zval **entry;
! 1512:
! 1513: hash = HASH_OF(var);
! 1514:
! 1515: if (maxlength == -1) {
! 1516: zend_hash_internal_pointer_reset(hash);
! 1517: while (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
! 1518: convert_to_string_ex(entry);
! 1519: if (Z_STRLEN_PP(entry) > maxlength) {
! 1520: maxlength = Z_STRLEN_PP(entry) + 1;
! 1521: }
! 1522: zend_hash_move_forward(hash);
! 1523: }
! 1524: }
! 1525:
! 1526: bind = emalloc(sizeof(php_oci_bind));
! 1527: bind->array.elements = (text *)safe_emalloc(max_table_length * (maxlength + 1), sizeof(text), 0);
! 1528: memset(bind->array.elements, 0, max_table_length * (maxlength + 1) * sizeof(text));
! 1529: bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
! 1530: bind->array.old_length = bind->array.current_length;
! 1531: bind->array.max_length = maxlength;
! 1532: bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
! 1533: memset(bind->array.element_lengths, 0, max_table_length*sizeof(ub2));
! 1534: bind->array.indicators = safe_emalloc(max_table_length, sizeof(sb2), 0);
! 1535: memset(bind->array.indicators, 0, max_table_length*sizeof(sb2));
! 1536:
! 1537: zend_hash_internal_pointer_reset(hash);
! 1538:
! 1539: for (i = 0; i < bind->array.current_length; i++) {
! 1540: if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
! 1541: convert_to_string_ex(entry);
! 1542: bind->array.element_lengths[i] = Z_STRLEN_PP(entry);
! 1543: if (Z_STRLEN_PP(entry) == 0) {
! 1544: bind->array.indicators[i] = -1;
! 1545: }
! 1546: zend_hash_move_forward(hash);
! 1547: } else {
! 1548: break;
! 1549: }
! 1550: }
! 1551:
! 1552: zend_hash_internal_pointer_reset(hash);
! 1553: for (i = 0; i < max_table_length; i++) {
! 1554: if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 1555: int element_length;
! 1556:
! 1557: convert_to_string_ex(entry);
! 1558: element_length = (maxlength > Z_STRLEN_PP(entry)) ? Z_STRLEN_PP(entry) : maxlength;
! 1559:
! 1560: memcpy((text *)bind->array.elements + i*maxlength, Z_STRVAL_PP(entry), element_length);
! 1561: ((text *)bind->array.elements)[i*maxlength + element_length] = '\0';
! 1562:
! 1563: zend_hash_move_forward(hash);
! 1564: } else {
! 1565: ((text *)bind->array.elements)[i*maxlength] = '\0';
! 1566: }
! 1567: }
! 1568: zend_hash_internal_pointer_reset(hash);
! 1569:
! 1570: return bind;
! 1571: } /* }}} */
! 1572:
! 1573: /* {{{ php_oci_bind_array_helper_number()
! 1574: Bind arrays to PL/SQL types */
! 1575: php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC)
! 1576: {
! 1577: php_oci_bind *bind;
! 1578: ub4 i;
! 1579: HashTable *hash;
! 1580: zval **entry;
! 1581:
! 1582: hash = HASH_OF(var);
! 1583:
! 1584: bind = emalloc(sizeof(php_oci_bind));
! 1585: bind->array.elements = (ub4 *)safe_emalloc(max_table_length, sizeof(ub4), 0);
! 1586: bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
! 1587: bind->array.old_length = bind->array.current_length;
! 1588: bind->array.max_length = sizeof(ub4);
! 1589: bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
! 1590: memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
! 1591: bind->array.indicators = NULL;
! 1592:
! 1593: zend_hash_internal_pointer_reset(hash);
! 1594: for (i = 0; i < max_table_length; i++) {
! 1595: if (i < bind->array.current_length) {
! 1596: bind->array.element_lengths[i] = sizeof(ub4);
! 1597: }
! 1598: if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 1599: convert_to_long_ex(entry);
! 1600: ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_PP(entry);
! 1601: zend_hash_move_forward(hash);
! 1602: } else {
! 1603: ((ub4 *)bind->array.elements)[i] = 0;
! 1604: }
! 1605: }
! 1606: zend_hash_internal_pointer_reset(hash);
! 1607:
! 1608: return bind;
! 1609: } /* }}} */
! 1610:
! 1611: /* {{{ php_oci_bind_array_helper_double()
! 1612: Bind arrays to PL/SQL types */
! 1613: php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC)
! 1614: {
! 1615: php_oci_bind *bind;
! 1616: ub4 i;
! 1617: HashTable *hash;
! 1618: zval **entry;
! 1619:
! 1620: hash = HASH_OF(var);
! 1621:
! 1622: bind = emalloc(sizeof(php_oci_bind));
! 1623: bind->array.elements = (double *)safe_emalloc(max_table_length, sizeof(double), 0);
! 1624: bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
! 1625: bind->array.old_length = bind->array.current_length;
! 1626: bind->array.max_length = sizeof(double);
! 1627: bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
! 1628: memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
! 1629: bind->array.indicators = NULL;
! 1630:
! 1631: zend_hash_internal_pointer_reset(hash);
! 1632: for (i = 0; i < max_table_length; i++) {
! 1633: if (i < bind->array.current_length) {
! 1634: bind->array.element_lengths[i] = sizeof(double);
! 1635: }
! 1636: if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 1637: convert_to_double_ex(entry);
! 1638: ((double *)bind->array.elements)[i] = (double) Z_DVAL_PP(entry);
! 1639: zend_hash_move_forward(hash);
! 1640: } else {
! 1641: ((double *)bind->array.elements)[i] = 0;
! 1642: }
! 1643: }
! 1644: zend_hash_internal_pointer_reset(hash);
! 1645:
! 1646: return bind;
! 1647: } /* }}} */
! 1648:
! 1649: /* {{{ php_oci_bind_array_helper_date()
! 1650: Bind arrays to PL/SQL types */
! 1651: php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC)
! 1652: {
! 1653: php_oci_bind *bind;
! 1654: ub4 i;
! 1655: HashTable *hash;
! 1656: zval **entry;
! 1657:
! 1658: hash = HASH_OF(var);
! 1659:
! 1660: bind = emalloc(sizeof(php_oci_bind));
! 1661: bind->array.elements = (OCIDate *)safe_emalloc(max_table_length, sizeof(OCIDate), 0);
! 1662: bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
! 1663: bind->array.old_length = bind->array.current_length;
! 1664: bind->array.max_length = sizeof(OCIDate);
! 1665: bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
! 1666: memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
! 1667: bind->array.indicators = NULL;
! 1668:
! 1669: zend_hash_internal_pointer_reset(hash);
! 1670: for (i = 0; i < max_table_length; i++) {
! 1671: OCIDate oci_date;
! 1672: if (i < bind->array.current_length) {
! 1673: bind->array.element_lengths[i] = sizeof(OCIDate);
! 1674: }
! 1675: if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
! 1676:
! 1677: convert_to_string_ex(entry);
! 1678: PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date));
! 1679:
! 1680: if (connection->errcode != OCI_SUCCESS) {
! 1681: /* failed to convert string to date */
! 1682: efree(bind->array.element_lengths);
! 1683: efree(bind->array.elements);
! 1684: efree(bind);
! 1685: connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
! 1686: PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
! 1687: return NULL;
! 1688: }
! 1689:
! 1690: ((OCIDate *)bind->array.elements)[i] = oci_date;
! 1691: zend_hash_move_forward(hash);
! 1692: } else {
! 1693: PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)"01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date));
! 1694:
! 1695: if (connection->errcode != OCI_SUCCESS) {
! 1696: /* failed to convert string to date */
! 1697: efree(bind->array.element_lengths);
! 1698: efree(bind->array.elements);
! 1699: efree(bind);
! 1700: connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
! 1701: PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
! 1702: return NULL;
! 1703: }
! 1704:
! 1705: ((OCIDate *)bind->array.elements)[i] = oci_date;
! 1706: }
! 1707: }
! 1708: zend_hash_internal_pointer_reset(hash);
! 1709:
! 1710: return bind;
! 1711: } /* }}} */
! 1712:
! 1713: #endif /* HAVE_OCI8 */
! 1714:
! 1715: /*
! 1716: * Local variables:
! 1717: * tab-width: 4
! 1718: * c-basic-offset: 4
! 1719: * End:
! 1720: * vim600: noet sw=4 ts=4 fdm=marker
! 1721: * vim<600: noet sw=4 ts=4
! 1722: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>