From e91914b15dcae4f7da3498d0ec87c78b6b281987 Mon Sep 17 00:00:00 2001 From: Christopher Jones Date: Tue, 6 Oct 2009 22:36:32 +0000 Subject: [PATCH] 1. Introduce connection attribute functions: oci_set_module_name oci_set_action oci_set_client_info oci_set_client_identifier These functions set values that are visible and used by the database. They aid tracing, authentication and auditing. 2. Introduce connection attribute function: oci_set_edition Oracle 11g R2 "editions" allow multiple versions of DB objects to exist at one time. By setting different editions, two different versions of an application can run concurrently, making upgrades or A/B testing easier. 3. Introduce OCI_NO_AUTO_COMMIT as an alias for the OCI_DEFAULT constant (which is not the default value) used by oci_execute(). 4. Allow the oci_set_prefetch value to be 0. This is important in some cases using REF CURSORS in Oracle 11gR2. 5. Set the DRIVER_NAME attribute of Oracle Database 11gR2 connections to aid application tracing. The value used is to "PHP OCI8" followed by the OCI8 version number. Note the version number may get truncated in DB views such as v$session_connect_info. 6. Generate an error if an invalid resource type is used in oci_bind_by_name [DOC] Documentation will be added for the changes --- ext/oci8/README | 6 +- ext/oci8/oci8.c | 143 +++++++++++- ext/oci8/oci8_interface.c | 156 +++++++++++++ ext/oci8/oci8_statement.c | 68 +++++- ext/oci8/package.xml | 95 ++++++-- ext/oci8/php_oci8_int.h | 11 +- ext/oci8/tests/bind_error.phpt | 70 ++++++ ext/oci8/tests/commit.phpt | 60 ++--- ext/oci8/tests/conn_attr.inc | 150 ++++++++++++ ext/oci8/tests/conn_attr_1.phpt | 104 +++++++++ ext/oci8/tests/conn_attr_2.phpt | 111 +++++++++ ext/oci8/tests/conn_attr_3.phpt | 94 ++++++++ ext/oci8/tests/conn_attr_4.phpt | 121 ++++++++++ ext/oci8/tests/conn_attr_5.phpt | 76 ++++++ ext/oci8/tests/debug.phpt | 10 +- ext/oci8/tests/driver_name.phpt | 71 ++++++ ext/oci8/tests/edition_1.phpt | 158 +++++++++++++ ext/oci8/tests/edition_2.phpt | 250 ++++++++++++++++++++ ext/oci8/tests/refcur_prefetch_1.phpt | 256 +++++++++++++++++++++ ext/oci8/tests/refcur_prefetch_2.phpt | 317 ++++++++++++++++++++++++++ ext/oci8/tests/refcur_prefetch_3.phpt | 161 +++++++++++++ ext/oci8/tests/reflection1.phpt | 44 ++++ 22 files changed, 2477 insertions(+), 55 deletions(-) create mode 100644 ext/oci8/tests/bind_error.phpt create mode 100644 ext/oci8/tests/conn_attr.inc create mode 100644 ext/oci8/tests/conn_attr_1.phpt create mode 100644 ext/oci8/tests/conn_attr_2.phpt create mode 100644 ext/oci8/tests/conn_attr_3.phpt create mode 100644 ext/oci8/tests/conn_attr_4.phpt create mode 100644 ext/oci8/tests/conn_attr_5.phpt create mode 100644 ext/oci8/tests/driver_name.phpt create mode 100644 ext/oci8/tests/edition_1.phpt create mode 100644 ext/oci8/tests/edition_2.phpt create mode 100644 ext/oci8/tests/refcur_prefetch_1.phpt create mode 100644 ext/oci8/tests/refcur_prefetch_2.phpt create mode 100644 ext/oci8/tests/refcur_prefetch_3.phpt diff --git a/ext/oci8/README b/ext/oci8/README index 82248d2646..376b70ad41 100644 --- a/ext/oci8/README +++ b/ext/oci8/README @@ -14,7 +14,7 @@ Installing OCI8 ----------- The OCI8 extension allows you to access Oracle databases. It can be -built using Oracle 9.2, 10.2 or 11.1 client libraries, and allows +built using Oracle 9.2, 10.2, 11.1 or 11.2 client libraries, and allows Oracle's standard cross-version connectivity. This release can be used with PHP 6. @@ -450,5 +450,5 @@ system. The bug is specific to Oracle 11.1.0.6 with DRCP connections. The issues it fixes do not affect connections using Oracle's dedicated (the default connection mode) or shared servers. They do not affect -earlier versions of Oracle. The bug is intended to be fixed in Oracle -Database 11.1.0.7 (as yet unreleased). +earlier versions of Oracle. The bug is fixed in Oracle Database +11.1.0.7. diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 491fee1b85..3020b2c147 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -393,6 +393,30 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_prefetch, 0, 0, 2) ZEND_ARG_INFO(0, number_of_rows) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_identifier, 0, 0, 2) + ZEND_ARG_INFO(0, connection_resource) + ZEND_ARG_INFO(0, client_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_edition, 0, 0, 1) + ZEND_ARG_INFO(0, edition_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_module_name, 0, 0, 2) + ZEND_ARG_INFO(0, connection_resource) + ZEND_ARG_INFO(0, module_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_action, 0, 0, 2) + ZEND_ARG_INFO(0, connection_resource) + ZEND_ARG_INFO(0, action) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_info, 0, 0, 2) + ZEND_ARG_INFO(0, connection_resource) + ZEND_ARG_INFO(0, client_information) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_password_change, 0, 0, 4) ZEND_ARG_INFO(0, connection_resource_or_connection_string) ZEND_ARG_INFO(0, username) @@ -620,6 +644,11 @@ PHP_FUNCTION(oci_server_version); PHP_FUNCTION(oci_statement_type); PHP_FUNCTION(oci_num_rows); PHP_FUNCTION(oci_set_prefetch); +PHP_FUNCTION(oci_set_client_identifier); +PHP_FUNCTION(oci_set_edition); +PHP_FUNCTION(oci_set_module_name); +PHP_FUNCTION(oci_set_action); +PHP_FUNCTION(oci_set_client_info); PHP_FUNCTION(oci_password_change); PHP_FUNCTION(oci_lob_save); PHP_FUNCTION(oci_lob_import); @@ -714,6 +743,11 @@ zend_function_entry php_oci_functions[] = { PHP_FE(oci_rollback, arginfo_oci_rollback) PHP_FE(oci_new_descriptor, arginfo_oci_new_descriptor) PHP_FE(oci_set_prefetch, arginfo_oci_set_prefetch) + PHP_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier) + PHP_FE(oci_set_edition, arginfo_oci_set_edition) + PHP_FE(oci_set_module_name, arginfo_oci_set_module_name) + PHP_FE(oci_set_action, arginfo_oci_set_action) + PHP_FE(oci_set_client_info, arginfo_oci_set_client_info) PHP_FE(oci_password_change, arginfo_oci_password_change) PHP_FE(oci_free_collection, arginfo_oci_free_collection) PHP_FE(oci_collection_append, arginfo_oci_collection_append) @@ -977,6 +1011,7 @@ PHP_MINIT_FUNCTION(oci) REGISTER_LONG_CONSTANT("OCI_CRED_EXT",PHP_OCI_CRED_EXT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_DESCRIBE_ONLY",OCI_DESCRIBE_ONLY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_COMMIT_ON_SUCCESS",OCI_COMMIT_ON_SUCCESS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OCI_NO_AUTO_COMMIT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_EXACT_FETCH",OCI_EXACT_FETCH, CONST_CS | CONST_PERSISTENT); /* for $LOB->seek() */ @@ -1031,7 +1066,7 @@ PHP_MINIT_FUNCTION(oci) REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", PHP_OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT); -/* for OCIFetchInto & OCIResult */ +/* for OCIFetchInto & OCIResult */ REGISTER_LONG_CONSTANT("OCI_ASSOC",PHP_OCI_ASSOC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_NUM",PHP_OCI_NUM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OCI_BOTH",PHP_OCI_BOTH, CONST_CS | CONST_PERSISTENT); @@ -1059,6 +1094,8 @@ PHP_RINIT_FUNCTION(oci) OCI_G(debug_mode) = 0; /* start "fresh" */ OCI_G(num_links) = OCI_G(num_persistent); OCI_G(errcode) = 0; + OCI_G(edition).s = NULL; + OCI_G(edition_len) = 0; return SUCCESS; } @@ -1080,6 +1117,10 @@ PHP_RSHUTDOWN_FUNCTION(oci) */ zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC); + if (OCI_G(edition).s) { + efree(OCI_G(edition).s); + } + return SUCCESS; } @@ -1594,6 +1635,12 @@ php_oci_connection *php_oci_do_connect_ex(zstr username, int username_len, zstr } smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0); + /* Add edition attribute to the hash */ + if (OCI_G(edition).s){ + smart_str_appendl_ex(&hashed_details, OCI_G(edition).s, (ub4) USTR_BYTES(type, OCI_G(edition_len)), 0); + } + smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0); + if (password_len) { ulong password_hash; password_hash = zend_u_inline_hash_func(type, password, password_len); @@ -2413,6 +2460,7 @@ static php_oci_spool *php_oci_create_spool(zstr username, int username_len, zstr php_oci_spool *session_pool = NULL; zend_bool iserror = 0; ub4 poolmode = OCI_DEFAULT; /* Mode to be passed to OCISessionPoolCreate */ + OCIAuthInfo *spoolAuth = NULL; /*Allocate sessionpool out of persistent memory */ session_pool = (php_oci_spool *) calloc(1, sizeof(php_oci_spool)); @@ -2457,6 +2505,56 @@ static php_oci_spool *php_oci_create_spool(zstr username, int username_len, zstr poolmode = OCI_SPC_HOMOGENEOUS; #endif +#if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2))) + /* Allocate auth handle for session pool {{{ */ + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL)); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + iserror = 1; + goto exit_create_spool; + } /* }}} */ + + /* Set the edition attribute on the auth handle {{{ */ + if (OCI_G(edition).s) { + PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition).s, (ub4)USTR_BYTES(type, OCI_G(edition_len)), (ub4)OCI_ATTR_EDITION, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + iserror = 1; + goto exit_create_spool; + } + } /* }}} */ + + /* Set the driver name attribute on the auth handle {{{ */ + { + zval *tmp; + + MAKE_STD_ZVAL(tmp); + ZVAL_STRINGL(tmp, PHP_OCI8_DRIVER_NAME, sizeof(PHP_OCI8_DRIVER_NAME)-1, 1); + convert_to_unicode(tmp); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) Z_UNIVAL_P(tmp).s, (ub4) UBYTES(Z_UNILEN_P(tmp)), (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err))); + + zval_ptr_dtor(&tmp); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + iserror = 1; + goto exit_create_spool; + } + } /* }}} */ + + /* Set the auth handle on the session pool {{{ */ + PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + iserror = 1; + goto exit_create_spool; + } /* }}} */ +#endif + /* Create the homogeneous session pool - We have different session pools for every different * username, password, charset and dbname. */ @@ -2487,6 +2585,10 @@ exit_create_spool: session_pool = NULL; } + if (spoolAuth) { + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO)); + } + if (OCI_G(debug_mode)) { php_printf ("OCI8 DEBUG L1: create_spool: (%p) at (%s:%d) \n", session_pool, __FILE__, __LINE__); } @@ -2511,6 +2613,11 @@ static php_oci_spool *php_oci_get_spool(zstr username, int username_len, zstr pa smart_str_appendl_ex(&spool_hashed_details, "oci8spool***", sizeof("oci8spool***") - 1, 0); smart_str_appendl_ex(&spool_hashed_details, username.s, USTR_BYTES(type, username_len), 0); smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0); + /* Add edition attribute to the hash */ + if (OCI_G(edition).s){ + smart_str_appendl_ex(&spool_hashed_details, OCI_G(edition).s, (ub4)USTR_BYTES(type, OCI_G(edition_len)), 0); + } + smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0); if (password_len) { ulong password_hash; password_hash = zend_u_inline_hash_func(type, password, password_len); @@ -2525,7 +2632,7 @@ static php_oci_spool *php_oci_get_spool(zstr username, int username_len, zstr pa smart_str_append_unsigned_ex(&spool_hashed_details, charsetid, 0); - /* Session Pool Hash Key : oci8spool***username**hashedpassword**dbname**charset */ + /* Session Pool Hash Key : oci8spool***username**edition**hashedpassword**dbname**charset */ smart_str_0(&spool_hashed_details); php_strtolower(spool_hashed_details.c, spool_hashed_details.len); @@ -2663,6 +2770,38 @@ static int php_oci_old_create_session(php_oci_connection *connection, zstr dbnam } }/* }}} */ + /* Set the edition attribute on the session handle {{{ */ +#if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2))) + if (OCI_G(edition).s) { + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(edition).s, (ub4) USTR_BYTES(type, OCI_G(edition_len)), (ub4) OCI_ATTR_EDITION, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + return 1; + } + } +#endif /* }}} */ + + /* Set the driver name attribute on the session handle {{{ */ +#if (OCI_MAJOR_VERSION >= 11) + { + zval *tmp; + + MAKE_STD_ZVAL(tmp); + ZVAL_STRINGL(tmp, PHP_OCI8_DRIVER_NAME, sizeof(PHP_OCI8_DRIVER_NAME)-1, 1); + convert_to_unicode(tmp); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) Z_UNIVAL_P(tmp).s, (ub4) UBYTES(Z_UNILEN_P(tmp)), (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err))); + + zval_ptr_dtor(&tmp); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + return 1; + } + } +#endif /* }}} */ + /* Set the server handle in the service handle {{{ */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err))); diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 68a338d6fc..d096bd5747 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1749,6 +1749,162 @@ PHP_FUNCTION(oci_set_prefetch) } /* }}} */ +/* {{{ proto bool oci_set_client_identifier(resource connection, string value) + Sets the client identifier attribute on the connection */ +PHP_FUNCTION(oci_set_client_identifier) +{ + zval *z_connection; + php_oci_connection *connection; + zstr client_id; + zend_uchar client_id_type; + long client_id_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &z_connection, &client_id, &client_id_len, &client_id_type) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_id.s, (ub4) USTR_BYTES(client_id_type, client_id_len), (ub4) OCI_ATTR_CLIENT_IDENTIFIER, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool oci_set_edition(string value) + Sets the edition attribute for all subsequent connections created */ +PHP_FUNCTION(oci_set_edition) +{ +#if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2))) + zstr edition; + zend_uchar edition_type; + long edition_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &edition, &edition_len, &edition_type) == FAILURE) { + return; + } + + if (OCI_G(edition).s) { + efree(OCI_G(edition).s); + OCI_G(edition).s = NULL; + OCI_G(edition_len) = 0; + } + + if (edition_len) { + OCI_G(edition).s = safe_emalloc(1, USTR_BYTES(edition_type, edition_len), 0); + memcpy(OCI_G(edition).s, edition.s, USTR_BYTES(edition_type, edition_len)); + OCI_G(edition_len) = edition_len; + } + + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ + +/* {{{ proto bool oci_set_module_name(resource connection, string value) + Sets the module attribute on the connection */ +PHP_FUNCTION(oci_set_module_name) +{ +#if (OCI_MAJOR_VERSION >= 10) + zval *z_connection; + php_oci_connection *connection; + zstr module; + zend_uchar module_type; + long module_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &z_connection, &module, &module_len, &module_type) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) module.s, (ub4) USTR_BYTES(module_type, module_len), (ub4) OCI_ATTR_MODULE, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ + +/* {{{ proto bool oci_set_action(resource connection, string value) + Sets the action attribute on the connection */ +PHP_FUNCTION(oci_set_action) +{ +#if (OCI_MAJOR_VERSION >= 10) + zval *z_connection; + php_oci_connection *connection; + zstr action; + zend_uchar action_type; + long action_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &z_connection, &action, &action_len, &action_type) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) action.s, (ub4) USTR_BYTES(action_type, action_len), (ub4) OCI_ATTR_ACTION, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ + +/* {{{ proto bool oci_set_client_info(resource connection, string value) + Sets the client info attribute on the connection */ +PHP_FUNCTION(oci_set_client_info) +{ +#if (OCI_MAJOR_VERSION >= 10) + zval *z_connection; + php_oci_connection *connection; + zstr client_info; + zend_uchar client_info_type; + long client_info_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &z_connection, &client_info, &client_info_len, &client_info_type) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_info.s, (ub4) USTR_BYTES(client_info_type, client_info_len), (ub4) OCI_ATTR_CLIENT_INFO, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ + /* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password) U Changes the password of an account */ PHP_FUNCTION(oci_password_change) diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 3fc98b8a0e..622481622e 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -98,7 +98,7 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, zst statement->parent_stmtid = 0; zend_list_addref(statement->connection->rsrc_id); - if (OCI_G(default_prefetch) > 0) { + if (OCI_G(default_prefetch) >= 0) { php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC); } @@ -116,8 +116,8 @@ int php_oci_statement_set_prefetch(php_oci_statement *statement, long size TSRML { ub4 prefetch = size; - if (size < 1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows has to be greater than or equal to 1"); + if (size < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0"); return 1; } @@ -419,7 +419,11 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) we don't want to execute!!! */ if (statement->binds) { - zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_pre_exec TSRMLS_CC); + int result = 0; + zend_hash_apply_with_argument(statement->binds, (apply_func_arg_t) php_oci_bind_pre_exec, (void *)&result TSRMLS_CC); + if (result) { + return 1; + } } /* execute statement */ @@ -770,9 +774,50 @@ void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC) /* {{{ php_oci_bind_pre_exec() Helper function */ -int php_oci_bind_pre_exec(void *data TSRMLS_DC) +int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC) { php_oci_bind *bind = (php_oci_bind *) data; + *(int *)result = 0; + + switch (bind->type) { + case SQLT_NTY: + case SQLT_BFILEE: + case SQLT_CFILEE: + case SQLT_CLOB: + case SQLT_BLOB: + case SQLT_RDD: + if (Z_TYPE_P(bind->zval) != IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + *(int *)result = 1; + } + break; + + case SQLT_INT: + case SQLT_NUM: + if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + *(int *)result = 1; + } + break; + + case SQLT_LBI: + case SQLT_BIN: + case SQLT_LNG: + case SQLT_AFC: + case SQLT_CHR: + if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + *(int *)result = 1; + } + break; + + case SQLT_RSET: + if (Z_TYPE_P(bind->zval) != IS_RESOURCE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + *(int *)result = 1; + } + break; + } /* reset all bind stuff to a normal state..-. */ @@ -967,6 +1012,10 @@ int php_oci_bind_by_name(php_oci_statement *statement, zstr name, int name_len, case SQLT_INT: case SQLT_NUM: + if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + return 1; + } convert_to_long(var); bind_data = (ub4 *)&Z_LVAL_P(var); value_sz = sizeof(ub4); @@ -978,6 +1027,10 @@ int php_oci_bind_by_name(php_oci_statement *statement, zstr name, int name_len, case SQLT_LNG: case SQLT_AFC: case SQLT_CHR: /* SQLT_CHR is the default value when type was not specified */ + if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + return 1; + } if (Z_TYPE_P(var) != IS_NULL) { convert_to_unicode(var); } @@ -999,6 +1052,10 @@ int php_oci_bind_by_name(php_oci_statement *statement, zstr name, int name_len, break; case SQLT_RSET: + if (Z_TYPE_P(var) != IS_RESOURCE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind"); + return 1; + } PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement); value_sz = sizeof(void*); @@ -1038,6 +1095,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, zstr name, int name_len, bindp->statement = oci_stmt; bindp->parent_statement = statement; bindp->zval = var; + bindp->type = type; zval_add_ref(&var); PHP_OCI_CALL_RETURN(statement->errcode, diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml index de1639fd41..84a9235d2f 100644 --- a/ext/oci8/package.xml +++ b/ext/oci8/package.xml @@ -6,7 +6,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> oci8 pecl.php.net Extension for Oracle Database - This extension allows you to access Oracle databases using the Oracle Call Interface (OCI8). It can be built with PHP 4.3.9 to 5.x. It can be linked with Oracle 9.2, 10.2 or 11.1 client libraries. + This extension allows you to access Oracle databases using the Oracle Call Interface (OCI8). It can be built with PHP 4.3.9 to 5.x. It can be linked with Oracle 9.2, 10.2, 11.1, or 11.2 client libraries. Christopher Jones @@ -33,25 +33,52 @@ http://pear.php.net/dtd/package-2.0.xsd"> no - 2009-03-16 - + 2009-10-06 + - 1.3.5 - 1.3.4 + 1.4.0 + 1.4.0 - stable - stable + alpha + alpha PHP - Fixed Bug #47243 (Crash at end of request shutdown on Windows) -Fixed Bug #46994 (CLOB size does not update when using CLOB IN OUT param in stored procedure) -Fixed Bug #46623 (phpinfo doesn't show compile time ORACLE_HOME with phpize) -Fixed bug #45458 (Numeric keys for associative arrays are not handled properly) Note: not fixed when building with PHP 4 due to lack of PHP internal helper. -Fixed PECL Bug #16035 (oci_connect without ORACLE_HOME defined causes segfault) -Fixed PECL Bug #15988 (sqlnet.ora isn't read with older Oracle libraries) -Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Instant Client RPM install) + + 1. Introduce connection attribute functions: + + oci_set_module_name + oci_set_action + oci_set_client_info + oci_set_client_identifier + + These set values that are visible/used by the database. They + are useful for tracing, authentication and auditing. + + 2. Introduce connection attribute function: + + oci_set_edition + + Oracle 11g R2 "editions" allow multiple versions of DB objects + to exist at one time. By setting different editions, two + different versions of an application can run concurrently, + making upgrading easier and faster. + + 3. Set the DRIVER_NAME attribute of Oracle Database 11gR2 + connections to aid application tracing. The value used is to + "PHP OCI8" followed by the OCI8 version number. Note the + version number may get truncated in DB views such as + v$session_connect_info. + + 4. Allow the oci_set_prefetch value to be 0. This is important in + some cases using REF CURSORS in Oracle 11gR2. + + 5. Introduce OCI_NO_AUTO_COMMIT as an alias for the OCI_DEFAULT + constant (which is not the default value) used by oci_execute(). + + 6. Generate an error if an invalid resource type is used in + oci_bind_by_name @@ -86,6 +113,7 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + @@ -156,6 +184,12 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + + + + + + @@ -207,8 +241,11 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + + + @@ -284,6 +321,7 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + @@ -296,12 +334,16 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + + + + @@ -316,6 +358,7 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + @@ -334,8 +377,9 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst - 6.0.0 + 4.3.9 6.0.0 + 6.0.0 1.4.0b1 @@ -348,6 +392,27 @@ Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Inst + + + 1.3.5 + 1.3.4 + + + stable + stable + + PHP + +Fixed Bug #47243 (Crash at end of request shutdown on Windows) +Fixed Bug #46994 (CLOB size does not update when using CLOB IN OUT param in stored procedure) +Fixed Bug #46623 (phpinfo doesn't show compile time ORACLE_HOME with phpize) +Fixed bug #45458 (Numeric keys for associative arrays are not handled properly) Note: not fixed when building with PHP 4 due to lack of PHP internal helper. +Fixed PECL Bug #16035 (oci_connect without ORACLE_HOME defined causes segfault) +Fixed PECL Bug #15988 (sqlnet.ora isn't read with older Oracle libraries) +Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an Instant Client RPM install) + + + 1.3.4 diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 06c77c5504..cf2b627391 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -101,6 +101,12 @@ extern zend_class_entry *oci_coll_class_entry_ptr; #error Invalid value for PHP_OCI_CRED_EXT #endif +/* + * Name passed to Oracle for tracing. Note some DB views only show + * the first nine characters of the driver name. + */ +#define PHP_OCI8_DRIVER_NAME "PHP OCI8 " PHP_OCI8_VERSION + /* }}} */ typedef enum { @@ -209,6 +215,7 @@ typedef struct { /* php_oci_bind {{{ */ dvoid *descriptor; /* used for binding of LOBS etc */ OCIStmt *statement; /* used for binding REFCURSORs */ php_oci_statement *parent_statement; /* pointer to the parent statement */ + ub2 type; /* bind type */ struct { void *elements; sb2 *indicators; @@ -450,7 +457,7 @@ php_oci_out_column * php_oci_statement_get_column (php_oci_statement *, long, zs int php_oci_statement_execute (php_oci_statement *, ub4 TSRMLS_DC); int php_oci_statement_cancel (php_oci_statement * TSRMLS_DC); void php_oci_statement_free (php_oci_statement * TSRMLS_DC); -int php_oci_bind_pre_exec(void *data TSRMLS_DC); +int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC); int php_oci_bind_post_exec(void *data TSRMLS_DC); int php_oci_bind_by_name(php_oci_statement *, zstr, int, zval*, long, ub2, zend_uchar TSRMLS_DC); sb4 php_oci_bind_in_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 *, ub1 *, dvoid **); @@ -491,6 +498,8 @@ ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ */ zend_bool in_call; char *connection_class; zend_bool events; + zstr edition; + int edition_len; ZEND_END_MODULE_GLOBALS(oci) /* }}} */ #ifdef ZTS diff --git a/ext/oci8/tests/bind_error.phpt b/ext/oci8/tests/bind_error.phpt new file mode 100644 index 0000000000..ad66ad59fe --- /dev/null +++ b/ext/oci8/tests/bind_error.phpt @@ -0,0 +1,70 @@ +--TEST-- +Test some oci_bind_by_name error conditions +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Insert value +bool(true) +Test 1 - Assign a resource to the bind variable and execute + +Warning: oci_execute(): Invalid variable used for bind in %s on line %d +bool(false) +Test 2 - Re-bind a resource + +Warning: oci_bind_by_name(): Invalid variable used for bind in %s on line %d + +Warning: oci_execute(): Invalid variable used for bind in %s on line %d +bool(false) +resource(%d) of type (oci8 connection) +Test 3 - Resource mismatch !! + +Warning: oci_bind_by_name(): Invalid variable used for bind in %s on line %d + +Warning: oci_execute(): ORA-01008: %s on line %d +bool(false) +Done diff --git a/ext/oci8/tests/commit.phpt b/ext/oci8/tests/commit.phpt index 73efe4b2a3..836d2cd1df 100644 --- a/ext/oci8/tests/commit.phpt +++ b/ext/oci8/tests/commit.phpt @@ -1,28 +1,36 @@ --TEST-- -oci_commit()/oci_rollback() +Test OCI_NO_AUTO_COMMIT constant --SKIPIF-- --FILE-- ---EXPECT-- +--EXPECTF-- bool(true) int(0) array(5) { - [u"ID"]=> + [%u|b%"ID"]=> array(0) { } - [u"VALUE"]=> + [%u|b%"VALUE"]=> array(0) { } - [u"BLOB"]=> + [%u|b%"BLOB"]=> array(0) { } - [u"CLOB"]=> + [%u|b%"CLOB"]=> array(0) { } - [u"STRING"]=> + [%u|b%"STRING"]=> array(0) { } } bool(true) int(4) array(5) { - [u"ID"]=> + [%u|b%"ID"]=> array(4) { [0]=> - unicode(1) "1" + %string|unicode%(1) "1" [1]=> - unicode(1) "1" + %string|unicode%(1) "1" [2]=> - unicode(1) "1" + %string|unicode%(1) "1" [3]=> - unicode(1) "1" + %string|unicode%(1) "1" } - [u"VALUE"]=> + [%u|b%"VALUE"]=> array(4) { [0]=> - unicode(1) "1" + %string|unicode%(1) "1" [1]=> - unicode(1) "1" + %string|unicode%(1) "1" [2]=> - unicode(1) "1" + %string|unicode%(1) "1" [3]=> - unicode(1) "1" + %string|unicode%(1) "1" } - [u"BLOB"]=> + [%u|b%"BLOB"]=> array(4) { [0]=> NULL @@ -122,7 +130,7 @@ array(5) { [3]=> NULL } - [u"CLOB"]=> + [%u|b%"CLOB"]=> array(4) { [0]=> NULL @@ -133,7 +141,7 @@ array(5) { [3]=> NULL } - [u"STRING"]=> + [%u|b%"STRING"]=> array(4) { [0]=> NULL diff --git a/ext/oci8/tests/conn_attr.inc b/ext/oci8/tests/conn_attr.inc new file mode 100644 index 0000000000..746b6b7ea6 --- /dev/null +++ b/ext/oci8/tests/conn_attr.inc @@ -0,0 +1,150 @@ + 1[012]\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 10g or greater client "); + } +} +else { + die ("skip test expected to work only with Oracle 10g or greater server"); +} + +?> +--FILE-- + +--EXPECTF-- +**Test 1.1 - Default values for the attributes ************** +Testing with oci_connect() +The value of MODULE is %s +The value of ACTION is +The value of CLIENT_INFO is +The value of CLIENT_IDENTIFIER is +**Test 1.2 - Set and get values for the attributes ************** +Testing with oci_connect() +Value of MODULE has been set successfully +The value of MODULE is PHP TEST1 +Value of ACTION has been set successfully +The value of ACTION is TASK1 +Value of CLIENT_INFO has been set successfully +The value of CLIENT_INFO is INFO11 +Value of CLIENT_IDENTIFIER has been set successfully +The value of CLIENT_IDENTIFIER is ID001 +Testing with oci_pconnect() +Value of MODULE has been set successfully +The value of MODULE is PHP TEST2 +Value of ACTION has been set successfully +The value of ACTION is TASK2 +Value of CLIENT_INFO has been set successfully +The value of CLIENT_INFO is INFO12 +Value of CLIENT_IDENTIFIER has been set successfully +The value of CLIENT_IDENTIFIER is ID002 +Testing with oci_new_connect() +Value of MODULE has been set successfully +The value of MODULE is PHP TEST3 +Value of ACTION has been set successfully +The value of ACTION is TASK3 +Value of CLIENT_INFO has been set successfully +The value of CLIENT_INFO is INFO13 +Value of CLIENT_IDENTIFIER has been set successfully +The value of CLIENT_IDENTIFIER is ID003 +Done diff --git a/ext/oci8/tests/conn_attr_2.phpt b/ext/oci8/tests/conn_attr_2.phpt new file mode 100644 index 0000000000..f8ad5e2420 --- /dev/null +++ b/ext/oci8/tests/conn_attr_2.phpt @@ -0,0 +1,111 @@ +--TEST-- +Set and get of connection attributes across persistent connections and sysdba connection. +--SKIPIF-- + 1[012]\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 10g or greater version of client"); + } +} +else { + die ("skip test expected to work only with Oracle 10g or greater version of server"); +} +?> +--INI-- +oci8.privileged_connect = On +--FILE-- + + +--EXPECTF-- +**Set values using pconnect-1** +resource(%d) of type (oci8 persistent connection) +Value of MODULE has been set successfully +Value of ACTION has been set successfully +Value of CLIENT_INFO has been set successfully +Value of CLIENT_IDENTIFIER has been set successfully + +**Get values using pconnect-2** +resource(%d) of type (oci8 persistent connection) +The value of MODULE is PHP TEST100 +The value of ACTION is TASK100 +The value of CLIENT_INFO is INFO1100 +The value of CLIENT_IDENTIFIER is ID00100 + +**Get values using pconnect-3** +resource(%d) of type (oci8 persistent connection) +The value of MODULE is PHP TEST100 +The value of ACTION is TASK100 +The value of CLIENT_INFO is INFO1100 +The value of CLIENT_IDENTIFIER is ID00100 + +**Re-open a pconnect()** +resource(%d) of type (oci8 persistent connection) +The value of MODULE is PHP TEST100 +The value of ACTION is TASK100 +The value of CLIENT_INFO is INFO1100 +The value of CLIENT_IDENTIFIER is ID00100 + +Warning: oci_pconnect(): ORA-01031: %s on line %d +bool(false) +Done diff --git a/ext/oci8/tests/conn_attr_3.phpt b/ext/oci8/tests/conn_attr_3.phpt new file mode 100644 index 0000000000..8b6d921230 --- /dev/null +++ b/ext/oci8/tests/conn_attr_3.phpt @@ -0,0 +1,94 @@ +--TEST-- +Set and get of connection attributes with oci_close(). +--SKIPIF-- + 1[012]\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 10g or greater version of client"); + } +} +else { + die ("skip test expected to work only with Oracle 10g or greater version of server"); +} +?> +--FILE-- + +--EXPECTF-- +**Test Set and get values for the attributes with oci_close() ************ +Testing with oci_connect() +resource(%d) of type (oci8 connection) +Value of ACTION has been set successfully +The value of ACTION is TASK1 +Testing with oci_connect() +resource(%d) of type (oci8 connection) +The value of ACTION is +Testing with oci_pconnect() +resource(%d) of type (oci8 persistent connection) +Value of MODULE has been set successfully +The value of MODULE is PHP TEST2 +Testing with oci_pconnect() +resource(%d) of type (oci8 persistent connection) +The value of MODULE is PHP TEST2 +Testing with oci_new_connect() +resource(%d) of type (oci8 connection) +Value of CLIENT_INFO has been set successfully +Value of CLIENT_IDENTIFIER has been set successfully +The value of CLIENT_INFO is INFO13 +The value of CLIENT_IDENTIFIER is ID003 +Testing with oci_new_connect() +resource(%d) of type (oci8 connection) +The value of CLIENT_INFO is +The value of CLIENT_IDENTIFIER is +Done diff --git a/ext/oci8/tests/conn_attr_4.phpt b/ext/oci8/tests/conn_attr_4.phpt new file mode 100644 index 0000000000..2ef2673fd1 --- /dev/null +++ b/ext/oci8/tests/conn_attr_4.phpt @@ -0,0 +1,121 @@ +--TEST-- +Set and get of connection attributes with errors. +--SKIPIF-- + 1[012]\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 10g or greater version of client"); + } +} +else { + die ("skip test expected to work only with Oracle 10g or greater version of server"); +} +?> +--FILE-- + 64 !!!!!this is a very huge string with a length > 64 !!!!!this is a very huge string with a length > 64 !!!!!this is a very huge string with a length > 64 !!!!!'); + +foreach($values_array as $val ) { + oci_set_module_name($c1,$val); + oci_set_client_identifier($c1,$val); + oci_set_client_info($c1,$val); + $r = oci_set_action($c1,$val); + if ($r) { + echo "Values set succesfully to $val\n"; + foreach($attr_array as $attr) { + get_attr($c1,$attr); + } + } +} + +clean_up($c); +echo "Done\n"; +?> +--EXPECTF-- +**Test Negative cases************ + +Invalid Connection resource + +Warning: oci_set_action() expects parameter 1 to be resource, null given in %s on line %d +NULL + +Invalid Connection resource 2 + +Warning: oci_set_client_info() expects parameter 1 to be resource, %s given in %s on line %d +NULL + +Invalid Value + +Warning: oci_set_action() expects parameter 2 to be %s, resource given in %s on line %d +NULL + +Set Values multiple times +bool(true) +bool(true) +bool(true) +bool(true) +The value of ACTION is ACTION1 + +Setting to different values +Values set succesfully to 1000 +The value of MODULE is 1000 +The value of ACTION is 1000 +The value of CLIENT_INFO is 1000 +The value of CLIENT_IDENTIFIER is 1000 +Values set succesfully to +The value of MODULE is +The value of ACTION is +The value of CLIENT_INFO is +The value of CLIENT_IDENTIFIER is + +Warning: oci_set_module_name(): ORA-24960: %s OCI_ATTR_MODULE %s on line %d + +Warning: oci_set_client_identifier(): ORA-24960: %s OCI_ATTR_CLIENT_IDENTIFIER %s on line %d + +Warning: oci_set_client_info(): ORA-24960: %s OCI_ATTR_CLIENT_INFO %s on line %d + +Warning: oci_set_action(): ORA-24960: %s OCI_ATTR_ACTION %s on line %d +Done diff --git a/ext/oci8/tests/conn_attr_5.phpt b/ext/oci8/tests/conn_attr_5.phpt new file mode 100644 index 0000000000..9f6b6c7247 --- /dev/null +++ b/ext/oci8/tests/conn_attr_5.phpt @@ -0,0 +1,76 @@ +--TEST-- +Set and get connection attributes with scope end. +--SKIPIF-- + 1[012]\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 10g or greater version of client"); + } +} +else { + die ("skip test expected to work only with Oracle 10g or greater version of server"); +} +?> +--FILE-- + +--EXPECTF-- +**Test - Set and get values for the attributes with scope end ************ +Testing with oci_connect() +Value of CLIENT_INFO has been set successfully +Value of CLIENT_IDENTIFIER has been set successfully +Testing with oci_new_connect() +Value of ACTION has been set successfully +Testing with oci_pconnect() +Value of MODULE has been set successfully +Get the Values from a different scope +Testing with oci_connect() +The value of CLIENT_INFO is +The value of CLIENT_IDENTIFIER is +Testing with oci_new_connect() +The value of ACTION is +Testing with oci_pconnect() +The value of MODULE is PHP TEST50 +Done diff --git a/ext/oci8/tests/debug.phpt b/ext/oci8/tests/debug.phpt index 91bd7779fe..be1f0bcd91 100644 --- a/ext/oci8/tests/debug.phpt +++ b/ext/oci8/tests/debug.phpt @@ -6,9 +6,9 @@ if (!extension_loaded('oci8')) die("skip no oci8 extension"); ob_start(); phpinfo(INFO_MODULES); $phpinfo = ob_get_clean(); -$iv = preg_match('/Oracle .*Version => 11/', $phpinfo); +$iv = preg_match('/Oracle .*Version => (11\.2|12\.)/', $phpinfo); if ($iv !== 1) { - die ("skip expected output only valid when using Oracle 11g client libraries"); + die ("skip expected output only valid when using Oracle 11gR2+ client libraries"); } ?> --FILE-- @@ -33,8 +33,12 @@ OCI8 DEBUG L1: Got NO cached connection at (%s:%d) OCI8 DEBUG: OCIEnvNlsCreate at (%s:%d) OCI8 DEBUG: OCIHandleAlloc at (%s:%d) OCI8 DEBUG: OCIHandleAlloc at (%s:%d) +OCI8 DEBUG: OCIHandleAlloc at (%s:%d) +OCI8 DEBUG: OCIAttrSet at (%s:%d) +OCI8 DEBUG: OCIAttrSet at (%s:%d) OCI8 DEBUG: OCISessionPoolCreate at (%s:%d) OCI8 DEBUG: OCIAttrSet at (%s:%d) +OCI8 DEBUG: OCIHandleFree at (%s:%d) OCI8 DEBUG L1: create_spool: (%s:%d) OCI8 DEBUG L1: using shared pool: (%s:%d) OCI8 DEBUG: OCIHandleAlloc at (%s:%d) @@ -43,7 +47,7 @@ OCI8 DEBUG: OCIAttrSet at (%s:%d) OCI8 DEBUG: OCIAttrSet at (%s:%d) OCI8 DEBUG: OCIAttrGet at (%s:%d) OCI8 DEBUG: OCIAttrGet at (%s:%d) -OCI8 DEBUG L1: (%s:%d) +OCI8 DEBUG L1: (numopen=0)(numbusy=0) at (%s:%d) OCI8 DEBUG: OCISessionGet at (%s:%d) OCI8 DEBUG: OCIAttrGet at (%s:%d) OCI8 DEBUG: OCIAttrGet at (%s:%d) diff --git a/ext/oci8/tests/driver_name.phpt b/ext/oci8/tests/driver_name.phpt new file mode 100644 index 0000000000..a5076a5c12 --- /dev/null +++ b/ext/oci8/tests/driver_name.phpt @@ -0,0 +1,71 @@ +--TEST-- +Verify that the Driver Name attribute is set +--SKIPIF-- + (11.2|12)\./', $phpinfo); + if ($iv != 1) { + die ("skip test expected to work only with Oracle 11g or greater version of client"); + } +} +else { + die ("skip test expected to work only with Oracle 11g or greater version of server"); +} + +?> +--FILE-- + +--EXPECT-- +**Test 1.1 - Default values for the attribute ************** +The value of DRIVER_NAME is PHP OCI8 + +***Test 1.2 - Get the values from different connections ************** +Testing with oci_pconnect() +The value of DRIVER_NAME is PHP OCI8 +Testing with oci_new_connect() +The value of DRIVER_NAME is PHP OCI8 +Done diff --git a/ext/oci8/tests/edition_1.phpt b/ext/oci8/tests/edition_1.phpt new file mode 100644 index 0000000000..ae27b04396 --- /dev/null +++ b/ext/oci8/tests/edition_1.phpt @@ -0,0 +1,158 @@ +--TEST-- +Basic test for setting Oracle 11gR2 "edition" attribute +--SKIPIF-- + (11\.2|12)/', $phpinfo); + if ($iv != 1) { + die ("skip tests a feature that works only with Oracle 11gR2 or greater version of client"); + } +} +else { + die ("skip tests a feature that works only with Oracle 11gR2 or greater version of server"); +} + +?> +--FILE-- + +--XFAIL-- +OCI does not have UTF16 support for OCI_ATTR_EDITION +--EXPECTF-- +The value of edition has been successfully set +The value of current EDITION is MYEDITION +array(3) { + [0]=> + %unicode|string%(%d) "mike" + [1]=> + %unicode|string%(%d) "30" + [2]=> + %unicode|string%(%d) "Senior engineer" +} +array(3) { + [0]=> + %unicode|string%(%d) "juan" + [1]=> + %unicode|string%(%d) "25" + [2]=> + %unicode|string%(%d) "engineer" +} + The value of edition has been successfully set +The value of current EDITION is MYEDITION1 +array(4) { + [0]=> + %unicode|string%(%d) "mike" + [1]=> + %unicode|string%(%d) "30" + [2]=> + %unicode|string%(%d) "Senior engineer" + [3]=> + %unicode|string%(%d) "200" +} +array(4) { + [0]=> + %unicode|string%(%d) "juan" + [1]=> + %unicode|string%(%d) "25" + [2]=> + %unicode|string%(%d) "engineer" + [3]=> + %unicode|string%(%d) "100" +} +version of view_ed in MYEDITION +The value of current EDITION is MYEDITION +array(3) { + [0]=> + %unicode|string%(%d) "mike" + [1]=> + %unicode|string%(%d) "30" + [2]=> + %unicode|string%(%d) "Senior engineer" +} +array(3) { + [0]=> + %unicode|string%(%d) "juan" + [1]=> + %unicode|string%(%d) "25" + [2]=> + %unicode|string%(%d) "engineer" +} +Done diff --git a/ext/oci8/tests/edition_2.phpt b/ext/oci8/tests/edition_2.phpt new file mode 100644 index 0000000000..696ce7b984 --- /dev/null +++ b/ext/oci8/tests/edition_2.phpt @@ -0,0 +1,250 @@ +--TEST-- +Set and check Oracle 11gR2 "edition" attribute +--SKIPIF-- + (11\.2|12)/', $phpinfo); + if ($iv != 1) { + die ("skip tests a feature that works only with Oracle 11gR2 or greater version of client"); + } +} +else { + die ("skip tests a feature that works only with Oracle 11gR2 or greater version of server"); +} + +?> +--FILE-- + +--XFAIL-- +OCI does not have UTF16 support for OCI_ATTR_EDITION +--EXPECTF-- +**Test 1.1 - Default value for the attribute ************** +The value of current EDITION is ORA$BASE + + +**Test 1.2 - Set a value and get the same with different connections ********* + The value of edition has been successfully set +Testing with oci_connect() +The value of current EDITION is MYEDITION +Testing with oci_pconnect() +The value of current EDITION is MYEDITION +Testing with oci_new_connect() +The value of current EDITION is MYEDITION +The value of current EDITION is MYEDITION + + +**Test 1.3 change the value and verify with existing conenctions.********* + The value of edition has been successfully set +The value of current EDITION is MYEDITION +The value of current EDITION is MYEDITION +Testing with oci_new_connect() +The value of current EDITION is MYEDITION1 +Testing with oci_pconnect() +The value of current EDITION is MYEDITION1 +Testing with oci_connect() +The value of current EDITION is MYEDITION1 + + +**Test 1.4 - with different type of values ********* + The value of edition has been successfully set +Testing with oci_connect() + +Warning: oci_connect(): ORA-38801: %s ORA_EDITION in %s on line %d + The value of edition has been successfully set +Testing with oci_connect() +The value of current EDITION is ORA$BASE + The value of edition has been successfully set +Testing with oci_connect() + +Warning: oci_connect(): ORA-38801: %s ORA_EDITION in %s on line %d + The value of edition has been successfully set +Testing with oci_connect() + +Warning: oci_connect(): ORA-38801: %s ORA_EDITION in %s on line %d + + +**Test 1.5 - Negative case with an invalid string value. ********* +Testing with oci_new_connect() + +Warning: oci_new_connect(): ORA-38801: %s ORA_EDITION in %s on line %d + The value of edition has been successfully set + + +**Test 1.6 - Set Multiple times.***** + The value of edition has been successfully set + The value of edition has been successfully set +Testing with oci_connect() +The value of current EDITION is MYEDITION1 + + +**Test 1.7 - Test with ALTER SESSION statement to change the edition ******* + The value of edition has been successfully set +Testing with oci_new_connect() +get the value set to MYEDITION with oci_set_edition +The value of current EDITION is MYEDITION +Get the value set to MYEDITION1 with alter session +The value of current EDITION is MYEDITION1 + Get the value with a new connection +Testing with oci_connect() +The value of current EDITION is MYEDITION + Set the value back using oci-set_edition + The value of edition has been successfully set +The value of current EDITION is MYEDITION + Get the value with a new conenction +Testing with oci_connect() +The value of current EDITION is MYEDITION + + +**Test 1.8 - Test setting the attribute with scope ends******* + The value of edition has been successfully set +The value of current EDITION is MYEDITION1 +Done + diff --git a/ext/oci8/tests/refcur_prefetch_1.phpt b/ext/oci8/tests/refcur_prefetch_1.phpt new file mode 100644 index 0000000000..c603fdd5bb --- /dev/null +++ b/ext/oci8/tests/refcur_prefetch_1.phpt @@ -0,0 +1,256 @@ +--TEST-- +Prefetch with REF cursor. Test different values for prefetch with oci_set_prefetch(). +--SKIPIF-- + (11\.2|12\.)/', $phpinfo); +if ($iv == 1) { + $sv = oci_server_version($c); + $sv = preg_match('/Release 1[012]\./', $sv, $matches); + if ($sv != 1) { + die ("skip expected output only valid when using Oracle 10g or greater server"); + } +} +else { + die ("skip expected output only valid when using Oracle 11.2 or greater client"); +} +?> +--FILE-- + +--EXPECTF-- +----------------------------------------------- +Test with Prefetch value set to 0 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "1" +%unicode|string%(%d) "test1" +----------------------------------------------- +Test with Prefetch value set to 1 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "2" +%unicode|string%(%d) "test2" +----------------------------------------------- +Test with Prefetch value set to 501 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} + +Warning: oci_execute(): ORA-01002: %s +ORA-06512: at "SYSTEM.REFCURPKG", line %d +ORA-06512: at line %d in %s on line %d +Fetch Row from PL/SQL +NULL +NULL +----------------------------------------------- +Test with Prefetch value set to 499 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "500" +%unicode|string%(%d) "test500" +----------------------------------------------- +Test with Prefetch value set to 250 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "251" +%unicode|string%(%d) "test251" +----------------------------------------------- +Test with Prefetch value set to 12345 +----------------------------------------------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} + +Warning: oci_execute(): ORA-01002: %s +ORA-06512: at "SYSTEM.REFCURPKG", line %d +ORA-06512: at line %d in %s on line %d +Fetch Row from PL/SQL +NULL +NULL +----------------------------------------------- +Test with Prefetch value set to -12345 +----------------------------------------------- + +Warning: oci_set_prefetch(): Number of rows to be prefetched has to be greater than or equal to 0 in %s on line %d +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "101" +%unicode|string%(%d) "test101" +----------------------------------------------- +Test with Prefetch value set to -1 +----------------------------------------------- + +Warning: oci_set_prefetch(): Number of rows to be prefetched has to be greater than or equal to 0 in %s on line %d +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "101" +%unicode|string%(%d) "test101" +Done diff --git a/ext/oci8/tests/refcur_prefetch_2.phpt b/ext/oci8/tests/refcur_prefetch_2.phpt new file mode 100644 index 0000000000..751ffa78f0 --- /dev/null +++ b/ext/oci8/tests/refcur_prefetch_2.phpt @@ -0,0 +1,317 @@ +--TEST-- +Prefetch with REF cursor. Test No 2 +--SKIPIF-- + (11\.2|12\.)/', $phpinfo); +if ($iv == 1) { + $sv = oci_server_version($c); + $sv = preg_match('/Release 1[012]\./', $sv, $matches); + if ($sv != 1) { + die ("skip expected output only valid when using Oracle 10g or greater server"); + } +} +else { + die ("skip expected output only valid when using Oracle 11.1 or greater client"); +} +?> +--FILE-- + +--EXPECTF-- +------Test 1- Check Roundtrips with prefetch 0 and 5 ----------- +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +array(2) { + [0]=> + %unicode|string%(%d) "1" + [1]=> + %unicode|string%(%d) "test1" +} +array(2) { + [0]=> + %unicode|string%(%d) "2" + [1]=> + %unicode|string%(%d) "test2" +} +array(2) { + [0]=> + %unicode|string%(%d) "3" + [1]=> + %unicode|string%(%d) "test3" +} +array(2) { + [0]=> + %unicode|string%(%d) "4" + [1]=> + %unicode|string%(%d) "test4" +} +Number of roundtrips made with prefetch count 0 for 5 rows is 6 +array(2) { + [0]=> + %unicode|string%(%d) "5" + [1]=> + %unicode|string%(%d) "test5" +} +array(2) { + [0]=> + %unicode|string%(%d) "6" + [1]=> + %unicode|string%(%d) "test6" +} +array(2) { + [0]=> + %unicode|string%(%d) "7" + [1]=> + %unicode|string%(%d) "test7" +} +array(2) { + [0]=> + %unicode|string%(%d) "8" + [1]=> + %unicode|string%(%d) "test8" +} +array(2) { + [0]=> + %unicode|string%(%d) "9" + [1]=> + %unicode|string%(%d) "test9" +} +Number of roundtrips made with prefetch count 5 for 5 rows is 2 +------Test 2 - Set Prefetch before PL/SQL fetch ---------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "101" +%unicode|string%(%d) "test101" +------Test 3 - Set Prefetch after PL/SQL fetch ---------- + +Warning: oci_execute(): ORA-01001: %s +ORA-06512: at "SYSTEM.REFCURPKG", line %d +ORA-06512: at line %d in %s on line %d +Fetch Row from PL/SQL +%unicode|string%(%d) "101" +%unicode|string%(%d) "test101" +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +------Test 4- Overwrite prefetch----------- +Fetch Row from PHP +array(2) { + [0]=> + %unicode|string%(%d) "0" + [1]=> + %unicode|string%(%d) "test0" +} +Fetch Row from PL/SQL +%unicode|string%(%d) "101" +%unicode|string%(%d) "test101" +Done diff --git a/ext/oci8/tests/refcur_prefetch_3.phpt b/ext/oci8/tests/refcur_prefetch_3.phpt new file mode 100644 index 0000000000..0666a96e90 --- /dev/null +++ b/ext/oci8/tests/refcur_prefetch_3.phpt @@ -0,0 +1,161 @@ +--TEST-- +Prefetch with Nested cursors with INI setting. +--INI-- +oci8.default_prefetch=5 +--SKIPIF-- + (11\.2|12\.)/', $phpinfo); +if ($iv == 1) { + $sv = oci_server_version($c); + $sv = preg_match('/Release (11\.2|12\.)/', $sv, $matches); + if ($sv != 1) { + die ("skip expected output only valid when using Oracle 11.2 or greater server"); + } +} +else { + die ("skip expected output only valid when using Oracle 11.2 or greater client"); +} + +?> +--FILE-- + +--EXPECTF-- +----------------------------------------------- +Test with Nested Cursors +----------------------------------------------- +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test0" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test1" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test2" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test3" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test4" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test5" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test6" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test7" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test8" +} +Fetch Row using Nested cursor Query +array(1) { + [0]=> + %unicode|string%(%d) "test9" +} +Number of roundtrips made with prefetch count 5 for 10 rows is 3 +Done diff --git a/ext/oci8/tests/reflection1.phpt b/ext/oci8/tests/reflection1.phpt index 62ee02b840..5f2e73d80b 100644 --- a/ext/oci8/tests/reflection1.phpt +++ b/ext/oci8/tests/reflection1.phpt @@ -121,6 +121,11 @@ reflection::export(new reflectionfunction('ocicollassignelem')); reflection::export(new reflectionfunction('ocicollsize')); reflection::export(new reflectionfunction('ocicollmax')); reflection::export(new reflectionfunction('ocicolltrim')); +reflection::export(new reflectionfunction('oci_set_edition')); +reflection::export(new reflectionfunction('oci_set_module_name')); +reflection::export(new reflectionfunction('oci_set_action')); +reflection::export(new reflectionfunction('oci_set_client_info')); +reflection::export(new reflectionfunction('oci_set_client_identifier')); ?> ===DONE=== @@ -1049,4 +1054,43 @@ Function [ function ocicolltrim ] { } } +Function [ function oci_set_edition ] { + + - Parameters [1] { + Parameter #0 [ $edition_name ] + } +} + +Function [ function oci_set_module_name ] { + + - Parameters [2] { + Parameter #0 [ $connection_resource ] + Parameter #1 [ $module_name ] + } +} + +Function [ function oci_set_action ] { + + - Parameters [2] { + Parameter #0 [ $connection_resource ] + Parameter #1 [ $action ] + } +} + +Function [ function oci_set_client_info ] { + + - Parameters [2] { + Parameter #0 [ $connection_resource ] + Parameter #1 [ $client_information ] + } +} + +Function [ function oci_set_client_identifier ] { + + - Parameters [2] { + Parameter #0 [ $connection_resource ] + Parameter #1 [ $client_identifier ] + } +} + ===DONE=== -- 2.40.0