1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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@php.net> |
24 | Wez Furlong <wez@omniti.com> |
25 +----------------------------------------------------------------------+
26 */
27
28
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "php.h"
35 #include "ext/standard/info.h"
36 #include "php_ini.h"
37
38 #if HAVE_OCI8
39
40 #include "php_oci8.h"
41 #include "php_oci8_int.h"
42
43 /* {{{ callback_fn()
44 OCI TAF callback function, calling userspace function */
callback_fn(void * svchp,void * envhp,void * fo_ctx,ub4 fo_type,ub4 fo_event)45 sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_event)
46 {
47 /* Create zval */
48 zval retval, params[3];
49 php_oci_connection *connection = (php_oci_connection*)fo_ctx;
50
51 /* Default return value */
52 sb4 returnValue = 0;
53
54 /* Check if userspace callback function was unregistered */
55 if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) {
56 return 0;
57 }
58
59 /* Initialize zval */
60 ZVAL_RES(¶ms[0], connection->id);
61 ZVAL_LONG(¶ms[1], fo_event);
62 ZVAL_LONG(¶ms[2], fo_type);
63
64 /* Call user function (if possible) */
65 if (call_user_function(NULL, NULL, &connection->taf_callback, &retval, 3, params) == FAILURE) {
66 php_error_docref(NULL, E_WARNING, "Unable to call Oracle TAF callback function");
67 }
68
69 /* Set return value */
70 if (Z_TYPE(retval) == IS_LONG) {
71 returnValue = (sb4) Z_LVAL(retval);
72 }
73
74 /* Setting params[0] to null so resource isn't destroyed on zval_dtor */
75 ZVAL_NULL(¶ms[0]);
76
77 /* Cleanup */
78 zval_ptr_dtor(&retval);
79 zval_ptr_dtor(¶ms[0]);
80 zval_ptr_dtor(¶ms[1]);
81 zval_ptr_dtor(¶ms[2]);
82
83 return returnValue;
84 }
85 /* }}} */
86
87 /* {{{ php_oci_unregister_taf_callback()
88 Unregister the userspace callback function for Oracle TAF,
89 while keeping the OCI callback alive */
php_oci_unregister_taf_callback(php_oci_connection * connection)90 int php_oci_unregister_taf_callback(php_oci_connection *connection)
91 {
92 return php_oci_register_taf_callback(connection, NULL);
93 }
94 /* }}} */
95
96 /* {{{ php_oci_register_taf_callback()
97 Register a callback function for Oracle TAF */
php_oci_register_taf_callback(php_oci_connection * connection,zval * callback)98 int php_oci_register_taf_callback(php_oci_connection *connection, zval *callback)
99 {
100 sword errstatus;
101 int registered = 0;
102
103 /* temporary failover callback structure */
104 OCIFocbkStruct failover;
105
106 if (!callback) {
107 /* Unregister callback */
108 if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) {
109 return 0; // Nothing to unregister
110 }
111
112 registered = 1;
113 zval_ptr_dtor(&connection->taf_callback);
114 ZVAL_NULL(&connection->taf_callback);
115 } else {
116 if (!Z_ISUNDEF(connection->taf_callback)) {
117 registered = 1;
118 if (!Z_ISNULL(connection->taf_callback)) {
119 zval_ptr_dtor(&connection->taf_callback);
120 ZVAL_NULL(&connection->taf_callback);
121 }
122 }
123
124 /* Set userspace callback function */
125 ZVAL_COPY(&connection->taf_callback, callback);
126 }
127
128 /* OCI callback function already registered */
129 if (registered) {
130 return 0;
131 }
132
133 /* set context */
134 failover.fo_ctx = connection;
135
136 /* set callback function */
137 failover.callback_function = &callback_fn;
138
139 /* do the registration */
140 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (connection->server, (ub4) OCI_HTYPE_SERVER, (void *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, connection->err));
141
142 if (errstatus != OCI_SUCCESS) {
143 zval_ptr_dtor(&connection->taf_callback);
144 ZVAL_UNDEF(&connection->taf_callback);
145 connection->errcode = php_oci_error(connection->err, errstatus);
146 return 1;
147 }
148
149 /* successful conclusion */
150 return 0;
151 }
152 /* }}} */
153
154 #endif /* HAVE_OCI8 */
155