oci8_failover.c 4.8 KB

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