From 37b4db2d00d7c3145019244c9c44a2c8e84a03cc Mon Sep 17 00:00:00 2001 From: Antony Dovgal Date: Thu, 1 Mar 2007 22:27:44 +0000 Subject: [PATCH] allocate descriptors dynamically --- ext/oci8/oci8_statement.c | 125 +++++++++++++++++++++++++++++--------- ext/oci8/php_oci8_int.h | 3 +- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 95e40bf598..87def8bcd8 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -314,6 +314,77 @@ php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, l } /* }}} */ +/* php_oci_define_callback() {{{ */ +sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp) +{ + php_oci_out_column *outcol = (php_oci_out_column *)ctx; + + if (!outcol) { + TSRMLS_FETCH(); + + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid context pointer value"); + return OCI_ERROR; + } + + switch(outcol->data_type) { + case SQLT_RSET: { + php_oci_statement *nested_stmt; + TSRMLS_FETCH(); + + nested_stmt = php_oci_statement_create(outcol->statement->connection, NULL, 0 TSRMLS_CC); + if (!nested_stmt) { + return OCI_ERROR; + } + zend_list_addref(outcol->statement->id); + outcol->nested_statement = nested_stmt; + outcol->stmtid = nested_stmt->id; + + *bufpp = nested_stmt->stmt; + *alenpp = &(outcol->retlen4); + *piecep = OCI_ONE_PIECE; + *indpp = &(outcol->indicator); + *rcpp = &(outcol->retcode); + return OCI_CONTINUE; + } + break; + case SQLT_RDD: + case SQLT_BLOB: + case SQLT_CLOB: + case SQLT_BFILE: { + php_oci_descriptor *descr; + int dtype; + TSRMLS_FETCH(); + + if (outcol->data_type == SQLT_BFILE) { + dtype = OCI_DTYPE_FILE; + } else if (outcol->data_type == SQLT_RDD ) { + dtype = OCI_DTYPE_ROWID; + } else { + dtype = OCI_DTYPE_LOB; + } + + descr = php_oci_lob_create(outcol->statement->connection, dtype TSRMLS_CC); + if (!descr) { + return OCI_ERROR; + } + zend_list_addref(outcol->statement->id); + outcol->descid = descr->id; + descr->charset_form = outcol->charset_form; + + *bufpp = descr->descriptor; + *alenpp = &(outcol->retlen4); + *piecep = OCI_ONE_PIECE; + *indpp = &(outcol->indicator); + *rcpp = &(outcol->retcode); + + return OCI_CONTINUE; + } + break; + } + return OCI_ERROR; +} +/* }}} */ + /* {{{ php_oci_statement_execute() Execute statement */ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) @@ -327,9 +398,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) ub4 iters; ub4 colcount; ub2 dynamic; - int dtype; dvoid *buf; - php_oci_descriptor *descr; switch (mode) { case OCI_COMMIT_ON_SUCCESS: @@ -417,8 +486,6 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) return 1; } - outcol->statement = statement; - /* get column */ PHP_OCI_CALL_RETURN(statement->errcode, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)¶m, counter)); @@ -516,45 +583,25 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) buf = 0; switch (outcol->data_type) { case SQLT_RSET: - outcol->statement = php_oci_statement_create(statement->connection, NULL, 0 TSRMLS_CC); - outcol->stmtid = outcol->statement->id; - outcol->statement->nested = 1; + outcol->statement = statement; /* parent handle */ define_type = SQLT_RSET; outcol->is_cursor = 1; outcol->storage_size4 = -1; outcol->retlen = -1; - dynamic = OCI_DEFAULT; - buf = &(outcol->statement->stmt); - zend_list_addref(statement->id); + dynamic = OCI_DYNAMIC_FETCH; break; case SQLT_RDD: /* ROWID */ case SQLT_BLOB: /* binary LOB */ case SQLT_CLOB: /* character LOB */ case SQLT_BFILE: /* binary file LOB */ + outcol->statement = statement; /* parent handle */ + define_type = outcol->data_type; outcol->is_descr = 1; outcol->storage_size4 = -1; - dynamic = OCI_DEFAULT; - - if (outcol->data_type == SQLT_BFILE) { - dtype = OCI_DTYPE_FILE; - } else if (outcol->data_type == SQLT_RDD ) { - dtype = OCI_DTYPE_ROWID; - } else { - dtype = OCI_DTYPE_LOB; - } - - descr = php_oci_lob_create(statement->connection, dtype TSRMLS_CC); - if (!descr) { - efree(outcol->name); - return 1; - } - outcol->descid = descr->id; - buf = &(descr->descriptor); - descr->charset_form = outcol->charset_form; - /* descr->charset_id = outcol->charset_id; */ + dynamic = OCI_DYNAMIC_FETCH; break; case SQLT_LNG: @@ -643,6 +690,26 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 0; } + + /* additional OCIDefineDynamic() call */ + switch (outcol->data_type) { + case SQLT_RSET: + case SQLT_RDD: + case SQLT_BLOB: + case SQLT_CLOB: + case SQLT_BFILE: + PHP_OCI_CALL_RETURN(statement->errcode, + OCIDefineDynamic, + ( + outcol->oci_define, + statement->err, + (dvoid *)outcol, + php_oci_define_callback + ) + ); + + break; + } } } diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index f8670154ae..8737bef6b2 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -194,7 +194,8 @@ typedef struct { /* php_oci_bind {{{ */ } php_oci_bind; /* }}} */ typedef struct { /* php_oci_out_column {{{ */ - php_oci_statement *statement; /* statement handle. used when fetching REFCURSORS */ + php_oci_statement *statement; /* statement handle. used when fetching REFCURSORS */ + php_oci_statement *nested_statement; /* statement handle. used when fetching REFCURSORS */ OCIDefine *oci_define; /* define handle */ char *name; /* column name */ ub4 name_len; /* column name length */ -- 2.50.1