Skip to content

Commit

Permalink
Merge branch 'PHP-7.0' into PHP-7.1
Browse files Browse the repository at this point in the history
* PHP-7.0:
  oci8 - Implementation of Oracle TAF Callback
  • Loading branch information
cjbj committed Jun 20, 2017
2 parents 058bec9 + ec6ac50 commit b742a18
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 4 deletions.
4 changes: 2 additions & 2 deletions ext/oci8/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ if test "$PHP_OCI8" != "no"; then

PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD)
PHP_ADD_LIBPATH($OCI8_DIR/$OCI8_LIB_DIR, OCI8_SHARED_LIBADD)
PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c oci8_failover.c, $ext_shared)
AC_DEFINE(HAVE_OCI8,1,[Defined to 1 if the PHP OCI8 extension for Oracle Database is configured])

PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
Expand Down Expand Up @@ -406,7 +406,7 @@ if test "$PHP_OCI8" != "no"; then

AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[Defined to 1 if OCI8 configuration located Oracle's Instant Client libraries])

PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c oci8_failover.c, $ext_shared)
AC_DEFINE(HAVE_OCI8,1,[Defined to 1 if the PHP OCI8 extension for Oracle Database is configured])

PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
Expand Down
4 changes: 2 additions & 2 deletions ext/oci8/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ if (PHP_OCI8_11G != "no") {
if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8_11G", oci8_11g_inc_paths) &&
CHECK_LIB("oci.lib", "oci8_11g", oci8_11g_lib_paths))
{
EXTENSION('oci8_11g', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c', null, null, null, "ext\\oci8_11g")
EXTENSION('oci8_11g', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c oci8_failover.c', null, null, null, "ext\\oci8_11g")

AC_DEFINE('HAVE_OCI8', 1);
AC_DEFINE('HAVE_OCI_INSTANT_CLIENT', 1);
Expand Down Expand Up @@ -115,7 +115,7 @@ if (PHP_OCI8_12C != "no") {
if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8_12C", oci8_12c_inc_paths) &&
CHECK_LIB("oci.lib", "oci8_12c", oci8_12c_lib_paths))
{
EXTENSION('oci8_12c', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c', null, null, null, "ext\\oci8_12c")
EXTENSION('oci8_12c', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c oci8_failover.c', null, null, null, "ext\\oci8_12c")

AC_DEFINE('HAVE_OCI8', 1);
AC_DEFINE('HAVE_OCI_INSTANT_CLIENT', 1);
Expand Down
38 changes: 38 additions & 0 deletions ext/oci8/oci8.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_collection, 0, 0, 2)
ZEND_ARG_INFO(0, type_name)
ZEND_ARG_INFO(0, schema_name)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_register_taf_callback, 0, 0, 1)
ZEND_ARG_INFO(0, connection_resource)
ZEND_ARG_INFO(0, function_name)
ZEND_END_ARG_INFO()
/* }}} */

/* {{{ LOB Method arginfo */
Expand Down Expand Up @@ -701,6 +706,7 @@ PHP_FUNCTION(oci_collection_assign);
PHP_FUNCTION(oci_collection_size);
PHP_FUNCTION(oci_collection_max);
PHP_FUNCTION(oci_collection_trim);
PHP_FUNCTION(oci_register_taf_callback);
/* }}} */

/* {{{ extension definition structures
Expand Down Expand Up @@ -783,6 +789,7 @@ static const zend_function_entry php_oci_functions[] = {
PHP_FE(oci_collection_max, arginfo_oci_collection_max)
PHP_FE(oci_collection_trim, arginfo_oci_collection_trim)
PHP_FE(oci_new_collection, arginfo_oci_new_collection)
PHP_FE(oci_register_taf_callback, arginfo_oci_register_taf_callback)

PHP_FALIAS(oci_free_cursor, oci_free_statement, arginfo_oci_free_statement)
PHP_FALIAS(ocifreecursor, oci_free_statement, arginfo_oci_free_statement)
Expand Down Expand Up @@ -1129,6 +1136,20 @@ PHP_MINIT_FUNCTION(oci)
REGISTER_LONG_CONSTANT("OCI_TEMP_CLOB",OCI_TEMP_CLOB, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_TEMP_BLOB",OCI_TEMP_BLOB, CONST_CS | CONST_PERSISTENT);

/* for Transparent Application Failover */
REGISTER_LONG_CONSTANT("OCI_FO_END", OCI_FO_END, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_ABORT", OCI_FO_ABORT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_REAUTH", OCI_FO_REAUTH, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_BEGIN", OCI_FO_BEGIN, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_ERROR", OCI_FO_ERROR, CONST_CS | CONST_PERSISTENT);

REGISTER_LONG_CONSTANT("OCI_FO_NONE", OCI_FO_NONE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_SESSION", OCI_FO_SESSION, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_SELECT", OCI_FO_SELECT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_FO_TXNAL", OCI_FO_TXNAL, CONST_CS | CONST_PERSISTENT);

REGISTER_LONG_CONSTANT("OCI_FO_RETRY", OCI_FO_RETRY, CONST_CS | CONST_PERSISTENT);

return SUCCESS;
}

Expand Down Expand Up @@ -1930,6 +1951,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
connection->hash_key = zend_string_dup(hashed_details.s, 0);
connection->is_persistent = 0;
ZVAL_UNDEF(&connection->taf_callback);
#ifdef HAVE_OCI8_DTRACE
connection->client_id = NULL;
#endif
Expand All @@ -1944,6 +1966,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
return NULL;
}
connection->is_persistent = 1;
ZVAL_UNDEF(&connection->taf_callback);
#ifdef HAVE_OCI8_DTRACE
connection->client_id = NULL;
#endif
Expand All @@ -1952,6 +1975,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
connection->hash_key = zend_string_dup(hashed_details.s, 0);
connection->is_persistent = 0;
ZVAL_UNDEF(&connection->taf_callback);
#ifdef HAVE_OCI8_DTRACE
connection->client_id = NULL;
#endif
Expand Down Expand Up @@ -2225,6 +2249,15 @@ static int php_oci_connection_close(php_oci_connection *connection)
connection->client_id = NULL;
}
#endif /* HAVE_OCI8_DTRACE */

if (!Z_ISUNDEF(connection->taf_callback)) {
/* If it's NULL, then its value should be freed already */
if (!Z_ISNULL(connection->taf_callback)) {
zval_ptr_dtor(&connection->taf_callback);
}
ZVAL_UNDEF(&connection->taf_callback);
}

pefree(connection, connection->is_persistent);
connection = NULL;
OCI_G(in_call) = in_call_save;
Expand Down Expand Up @@ -2667,6 +2700,11 @@ static int php_oci_persistent_helper(zval *zv)
if (le->type == le_pconnection) {
connection = (php_oci_connection *)le->ptr;

/* Remove TAF callback function as it's bound to current request */
if (connection->used_this_request && !Z_ISUNDEF(connection->taf_callback) && !Z_ISNULL(connection->taf_callback)) {
php_oci_disable_taf_callback(connection);
}

if (!connection->used_this_request && OCI_G(persistent_timeout) != -1) {
#ifdef HAVE_OCI8_DTRACE
if (DTRACE_OCI8_CONNECT_EXPIRY_ENABLED()) {
Expand Down
162 changes: 162 additions & 0 deletions ext/oci8/oci8_failover.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Stig Sæther Bakken <[email protected]> |
| Thies C. Arntzen <[email protected]> |
| |
| Collection support by Andy Sautins <[email protected]> |
| Temporary LOB support by David Benson <[email protected]> |
| ZTS per process OCIPLogon by Harald Radi <[email protected]> |
| |
| Redesigned by: Antony Dovgal <[email protected]> |
| Andi Gutmans <[email protected]> |
| Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
*/



#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "php_ini.h"

#if HAVE_OCI8

#include "php_oci8.h"
#include "php_oci8_int.h"

/* {{{ callback_fn()
OCI TAF callback function, calling userspace function */
sb4 callback_fn(OCISvcCtx *svchp, OCIEnv *envhp, php_oci_connection *fo_ctx, ub4 fo_type, ub4 fo_event)
{
/* Create zval */
zval retval, params[3];

/* Default return value */
sb4 returnValue = 0;

/* Check if userspace callback function was disabled */
if (Z_ISUNDEF(fo_ctx->taf_callback) || Z_ISNULL(fo_ctx->taf_callback)) {
return 0;
}

/* Initialize zval */
ZVAL_RES(&params[0], fo_ctx->id);
ZVAL_LONG(&params[1], fo_event);
ZVAL_LONG(&params[2], fo_type);

/* Call user function (if possible) */
if (call_user_function(EG(function_table), NULL, &fo_ctx->taf_callback, &retval, 3, params) == FAILURE) {
php_error_docref(NULL, E_WARNING, "Unable to call taf callback function, is it defined?");
}

/* Set return value */
if (Z_TYPE(retval) == IS_LONG) {
returnValue = (sb4) Z_LVAL(retval);
}

/* Setting params[0] to null so ressource isn't destroyed on zval_dtor */
ZVAL_NULL(&params[0]);

/* Cleanup */
zval_dtor(&retval);
zval_dtor(&params[0]);
zval_dtor(&params[1]);
zval_dtor(&params[2]);

return returnValue;
}
/* }}} */

/* {{{ php_oci_disable_taf_callback()
Disables the userspace callback function for Oracle TAF,
while keeping the OCI callback alive */
int php_oci_disable_taf_callback(php_oci_connection *connection)
{
return php_oci_register_taf_callback(connection, NULL);
}
/* }}} */

/* {{{ php_oci_register_taf_callback()
Register a callback function for Oracle TAF */
int php_oci_register_taf_callback(php_oci_connection *connection, zval *callback)
{
sword errstatus;
int registered = 0;

/* temporary failover callback structure */
OCIFocbkStruct failover;

if (!callback) {
/* Disable callback */
if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) {
return 0; // Nothing to disable
}

registered = 1;
zval_ptr_dtor(&connection->taf_callback);
ZVAL_NULL(&connection->taf_callback);
} else {
if (!Z_ISUNDEF(connection->taf_callback)) {
registered = 1;
if (!Z_ISNULL(connection->taf_callback)) {
zval_ptr_dtor(&connection->taf_callback);
ZVAL_NULL(&connection->taf_callback);
}
}

/* Set userspace callback function */
ZVAL_COPY(&connection->taf_callback, callback);
}

/* OCI callback function already registered */
if (registered) {
return 0;
}

/* set context */
failover.fo_ctx = connection;

/* set callback function */
failover.callback_function = &callback_fn;

/* do the registration */
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (connection->server, (ub4) OCI_HTYPE_SERVER, (void *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, connection->err));

if (errstatus != OCI_SUCCESS) {
zval_ptr_dtor(&connection->taf_callback);
ZVAL_UNDEF(&connection->taf_callback);
connection->errcode = php_oci_error(connection->err, errstatus);
return 1;
}

/* successful conclusion */
return 0;
}
/* }}} */

#endif /* HAVE_OCI8 */

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
36 changes: 36 additions & 0 deletions ext/oci8/oci8_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@
#define OCI_STMT_CALL 10
#endif

/* {{{ proto bool oci_register_taf_callback( resource connection [, mixed callback] )
Register a callback function for Oracle Transparent Application Failover (TAF) */
PHP_FUNCTION(oci_register_taf_callback)
{
zval *z_connection;
php_oci_connection *connection;
zval *callback;
zend_string *callback_name;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!", &z_connection, &callback) == FAILURE) {
return;
}

if (callback) {
if (!zend_is_callable(callback, 0, &callback_name)) {
php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(callback_name));
zend_string_release(callback_name);
RETURN_FALSE;
}

zend_string_release(callback_name);
}

PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);

if (php_oci_register_taf_callback(connection, callback) == 0) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
/* }}} */

/* {{{ proto bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])
Define a PHP variable to an Oracle column by name */
/* if you want to define a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE defining!!! */
Expand Down Expand Up @@ -1553,6 +1586,9 @@ PHP_FUNCTION(oci_close)
internally Zend engine increments
RefCount value by 1 */
zend_list_close(connection->id);

/* Disable Oracle TAF */
php_oci_disable_taf_callback(connection);

/* ZVAL_NULL(z_connection); */

Expand Down
1 change: 1 addition & 0 deletions ext/oci8/php_oci8.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
extern zend_module_entry oci8_module_entry;
#define phpext_oci8_ptr &oci8_module_entry
#define phpext_oci8_11g_ptr &oci8_module_entry
#define phpext_oci8_12c_ptr &oci8_module_entry


PHP_MINIT_FUNCTION(oci);
Expand Down
9 changes: 9 additions & 0 deletions ext/oci8/php_oci8_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ typedef struct {
#ifdef HAVE_OCI8_DTRACE
char *client_id; /* The oci_set_client_identifier() value */
#endif

zval taf_callback; /* The Oracle TAF callback function in the userspace */
} php_oci_connection;
/* }}} */

Expand Down Expand Up @@ -531,6 +533,13 @@ ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ Module globals */
char *edition;
ZEND_END_MODULE_GLOBALS(oci) /* }}} */

/* {{{ transparent failover related prototypes */

int php_oci_register_taf_callback(php_oci_connection *connection, zval *callback);
int php_oci_disable_taf_callback(php_oci_connection *connection);

/* }}} */

#ifdef ZTS
#define OCI_G(v) TSRMG(oci_globals_id, zend_oci_globals *, v)
#else
Expand Down

0 comments on commit b742a18

Please sign in to comment.