1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Stig Sæther Bakken <ssb@php.net> |
14 | Thies C. Arntzen <thies@thieso.net> |
15 | |
16 | Collection support by Andy Sautins <asautins@veripost.net> |
17 | Temporary LOB support by David Benson <dbenson@mancala.com> |
18 | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
19 | |
20 | Redesigned by: Antony Dovgal <antony@zend.com> |
21 | Andi Gutmans <andi@php.net> |
22 | Wez Furlong <wez@omniti.com> |
23 +----------------------------------------------------------------------+
24 */
25
26
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "php.h"
33 #include "ext/standard/info.h"
34 #include "php_ini.h"
35
36 #ifdef HAVE_OCI8
37
38 #include "php_oci8.h"
39 #include "php_oci8_int.h"
40
41 /* {{{ callback_fn()
42 OCI TAF callback function, calling userspace function */
callback_fn(void * svchp,void * envhp,void * fo_ctx,ub4 fo_type,ub4 fo_event)43 sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_event)
44 {
45 /* Create zval */
46 zval retval, params[3];
47 php_oci_connection *connection = (php_oci_connection*)fo_ctx;
48
49 /* Default return value */
50 sb4 returnValue = 0;
51
52 /* Check if userspace callback function was unregistered */
53 if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) {
54 return 0;
55 }
56
57 /* Initialize zval */
58 ZVAL_RES(¶ms[0], connection->id);
59 ZVAL_LONG(¶ms[1], fo_event);
60 ZVAL_LONG(¶ms[2], fo_type);
61
62 /* Call user function (if possible) */
63 if (call_user_function(NULL, NULL, &connection->taf_callback, &retval, 3, params) == FAILURE) {
64 php_error_docref(NULL, E_WARNING, "Unable to call Oracle TAF callback function");
65 }
66
67 /* Set return value */
68 if (Z_TYPE(retval) == IS_LONG) {
69 returnValue = (sb4) Z_LVAL(retval);
70 }
71
72 /* Setting params[0] to null so resource isn't destroyed on zval_ptr_dtor */
73 ZVAL_NULL(¶ms[0]);
74
75 /* Cleanup */
76 zval_ptr_dtor(&retval);
77 zval_ptr_dtor(¶ms[0]);
78 zval_ptr_dtor(¶ms[1]);
79 zval_ptr_dtor(¶ms[2]);
80
81 return returnValue;
82 }
83 /* }}} */
84
85 /* {{{ php_oci_unregister_taf_callback()
86 Unregister the userspace callback function for Oracle TAF,
87 while keeping the OCI callback alive */
php_oci_unregister_taf_callback(php_oci_connection * connection)88 int php_oci_unregister_taf_callback(php_oci_connection *connection)
89 {
90 return php_oci_register_taf_callback(connection, NULL);
91 }
92 /* }}} */
93
94 /* {{{ php_oci_register_taf_callback()
95 Register a callback function for Oracle TAF */
php_oci_register_taf_callback(php_oci_connection * connection,zval * callback)96 int php_oci_register_taf_callback(php_oci_connection *connection, zval *callback)
97 {
98 sword errstatus;
99 int registered = 0;
100
101 /* temporary failover callback structure */
102 OCIFocbkStruct failover;
103
104 if (!callback) {
105 /* Unregister callback */
106 if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) {
107 return 0; // Nothing to unregister
108 }
109
110 registered = 1;
111 zval_ptr_dtor(&connection->taf_callback);
112 ZVAL_NULL(&connection->taf_callback);
113 } else {
114 if (!Z_ISUNDEF(connection->taf_callback)) {
115 registered = 1;
116 if (!Z_ISNULL(connection->taf_callback)) {
117 zval_ptr_dtor(&connection->taf_callback);
118 ZVAL_NULL(&connection->taf_callback);
119 }
120 }
121
122 /* Set userspace callback function */
123 ZVAL_COPY(&connection->taf_callback, callback);
124 }
125
126 /* OCI callback function already registered */
127 if (registered) {
128 return 0;
129 }
130
131 /* set context */
132 failover.fo_ctx = connection;
133
134 /* set callback function */
135 failover.callback_function = &callback_fn;
136
137 /* do the registration */
138 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (connection->server, (ub4) OCI_HTYPE_SERVER, (void *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, connection->err));
139
140 if (errstatus != OCI_SUCCESS) {
141 zval_ptr_dtor(&connection->taf_callback);
142 ZVAL_UNDEF(&connection->taf_callback);
143 connection->errcode = php_oci_error(connection->err, errstatus);
144 return 1;
145 }
146
147 /* successful conclusion */
148 return 0;
149 }
150 /* }}} */
151
152 #endif /* HAVE_OCI8 */
153