tony2001                                 Tue, 27 Sep 2011 09:12:13 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=317381

Log:
fix bug #55768 (PDO_OCI can't resume Oracle session after it's been killed)

Bug: https://bugs.php.net/55768 (Open) PDO_OCI can't resume session when kill 
Oracle session's
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/pdo_oci/oci_driver.c
    U   php/php-src/branches/PHP_5_4/ext/pdo_oci/oci_driver.c
    U   php/php-src/trunk/ext/pdo_oci/oci_driver.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2011-09-27 08:38:45 UTC (rev 317380)
+++ php/php-src/branches/PHP_5_3/NEWS	2011-09-27 09:12:13 UTC (rev 317381)
@@ -55,9 +55,13 @@
   . Fixed bug #54158 (MYSQLND+PDO MySQL requires #define MYSQL_OPT_LOCAL_INFILE)
   (Andrey)

+- PDO OCI driver:
+  . Fixed bug #55768 (PDO_OCI can't resume Oracle session after it's been killed)
+  (mikhail dot v dot gavrilov at gmail dot com, Chris Jones, Tony)
+
 - Phar:
-  . Fixed bug#52013 (Unable to decompress files in a compressed phar). (Hannes)
-  . Fixed bug#53872 (internal corruption of phar). (Hannes)
+  . Fixed bug #52013 (Unable to decompress files in a compressed phar). (Hannes)
+  . Fixed bug #53872 (internal corruption of phar). (Hannes)

 - Session:
   . Fixed bug #55267 (session_regenerate_id fails after header sent). (Hannes)

Modified: php/php-src/branches/PHP_5_3/ext/pdo_oci/oci_driver.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo_oci/oci_driver.c	2011-09-27 08:38:45 UTC (rev 317380)
+++ php/php-src/branches/PHP_5_3/ext/pdo_oci/oci_driver.c	2011-09-27 09:12:13 UTC (rev 317381)
@@ -141,12 +141,27 @@
 				case 12154:	/* ORA-12154: TNS:could not resolve service name */
 					strcpy(*pdo_err, "42S02");
 					break;
-
-				case 22:	/* ORA-00022: invalid session id */
-				case 1012:	/* ORA-01012: */
-				case 3113:	/* ORA-03133: end of file on communication channel */
-				case 604:
-				case 1041:
+
+				case	22:	/* ORA-00022: invalid session id */
+				case   378:
+				case   602:
+				case   603:
+				case   604:
+				case   609:
+				case  1012:	/* ORA-01012: */
+				case  1033:
+				case  1041:
+				case  1043:
+				case  1089:
+				case  1090:
+				case  1092:
+				case  3113:	/* ORA-03133: end of file on communication channel */
+				case  3114:
+				case  3122:
+				case  3135:
+				case 12153:
+				case 27146:
+				case 28511:
 					/* consider the connection closed */
 					dbh->is_closed = 1;
 					H->attached = 0;
@@ -516,6 +531,43 @@
 }
 /* }}} */

+static int pdo_oci_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
+{
+	pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
+	sb4 error_code = 0;
+	char version[256];
+
+	/* TODO move attached check to PDO level */
+	if (H->attached == 0) {
+		return FAILURE;
+	}
+	/* TODO add persistent_timeout check at PDO level */
+
+
+	/* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
+	 * such as from Pre-10.1 servers, the error is still from the server and we would have
+	 * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
+	 * Pre-10.2 clients
+	 */
+#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))	/* OCIPing available 10.2 onwards */
+	H->last_err = OCIPing (H->svc, H->err, OCI_DEFAULT);
+#else
+	/* use good old OCIServerVersion() */
+	H->last_err = OCIServerVersion (H->svc, H->err, (text *)version, sizeof(version), OCI_HTYPE_SVCCTX);
+#endif
+	if (H->last_err == OCI_SUCCESS) {
+		return SUCCESS;
+	}
+
+	OCIErrorGet (H->err, (ub4)1, NULL, &error_code, NULL, 0, OCI_HTYPE_ERROR);
+
+	if (error_code == 1010) {
+		return SUCCESS;
+	}
+	return FAILURE;
+}
+/* }}} */
+
 static struct pdo_dbh_methods oci_methods = {
 	oci_handle_closer,
 	oci_handle_preparer,
@@ -528,7 +580,7 @@
 	NULL,
 	pdo_oci_fetch_error_func,
 	oci_handle_get_attribute,
-	NULL,	/* check_liveness */
+	pdo_oci_check_liveness,	/* check_liveness */
 	NULL	/* get_driver_methods */
 };

@@ -675,6 +727,7 @@
 }
 /* }}} */

+
 /*
  * Local variables:
  * tab-width: 4

Modified: php/php-src/branches/PHP_5_4/ext/pdo_oci/oci_driver.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/pdo_oci/oci_driver.c	2011-09-27 08:38:45 UTC (rev 317380)
+++ php/php-src/branches/PHP_5_4/ext/pdo_oci/oci_driver.c	2011-09-27 09:12:13 UTC (rev 317381)
@@ -141,12 +141,27 @@
 				case 12154:	/* ORA-12154: TNS:could not resolve service name */
 					strcpy(*pdo_err, "42S02");
 					break;
-
-				case 22:	/* ORA-00022: invalid session id */
-				case 1012:	/* ORA-01012: */
-				case 3113:	/* ORA-03133: end of file on communication channel */
-				case 604:
-				case 1041:
+
+				case	22:	/* ORA-00022: invalid session id */
+				case   378:
+				case   602:
+				case   603:
+				case   604:
+				case   609:
+				case  1012:	/* ORA-01012: */
+				case  1033:
+				case  1041:
+				case  1043:
+				case  1089:
+				case  1090:
+				case  1092:
+				case  3113:	/* ORA-03133: end of file on communication channel */
+				case  3114:
+				case  3122:
+				case  3135:
+				case 12153:
+				case 27146:
+				case 28511:
 					/* consider the connection closed */
 					dbh->is_closed = 1;
 					H->attached = 0;
@@ -516,6 +531,43 @@
 }
 /* }}} */

+static int pdo_oci_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
+{
+	pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
+	sb4 error_code = 0;
+	char version[256];
+
+	/* TODO move attached check to PDO level */
+	if (H->attached == 0) {
+		return FAILURE;
+	}
+	/* TODO add persistent_timeout check at PDO level */
+
+
+	/* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
+	 * such as from Pre-10.1 servers, the error is still from the server and we would have
+	 * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
+	 * Pre-10.2 clients
+	 */
+#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))	/* OCIPing available 10.2 onwards */
+	H->last_err = OCIPing (H->svc, H->err, OCI_DEFAULT);
+#else
+	/* use good old OCIServerVersion() */
+	H->last_err = OCIServerVersion (H->svc, H->err, (text *)version, sizeof(version), OCI_HTYPE_SVCCTX);
+#endif
+	if (H->last_err == OCI_SUCCESS) {
+		return SUCCESS;
+	}
+
+	OCIErrorGet (H->err, (ub4)1, NULL, &error_code, NULL, 0, OCI_HTYPE_ERROR);
+
+	if (error_code == 1010) {
+		return SUCCESS;
+	}
+	return FAILURE;
+}
+/* }}} */
+
 static struct pdo_dbh_methods oci_methods = {
 	oci_handle_closer,
 	oci_handle_preparer,
@@ -528,7 +580,7 @@
 	NULL,
 	pdo_oci_fetch_error_func,
 	oci_handle_get_attribute,
-	NULL,	/* check_liveness */
+	pdo_oci_check_liveness,	/* check_liveness */
 	NULL	/* get_driver_methods */
 };

@@ -675,6 +727,7 @@
 }
 /* }}} */

+
 /*
  * Local variables:
  * tab-width: 4

Modified: php/php-src/trunk/ext/pdo_oci/oci_driver.c
===================================================================
--- php/php-src/trunk/ext/pdo_oci/oci_driver.c	2011-09-27 08:38:45 UTC (rev 317380)
+++ php/php-src/trunk/ext/pdo_oci/oci_driver.c	2011-09-27 09:12:13 UTC (rev 317381)
@@ -141,12 +141,27 @@
 				case 12154:	/* ORA-12154: TNS:could not resolve service name */
 					strcpy(*pdo_err, "42S02");
 					break;
-
-				case 22:	/* ORA-00022: invalid session id */
-				case 1012:	/* ORA-01012: */
-				case 3113:	/* ORA-03133: end of file on communication channel */
-				case 604:
-				case 1041:
+
+				case	22:	/* ORA-00022: invalid session id */
+				case   378:
+				case   602:
+				case   603:
+				case   604:
+				case   609:
+				case  1012:	/* ORA-01012: */
+				case  1033:
+				case  1041:
+				case  1043:
+				case  1089:
+				case  1090:
+				case  1092:
+				case  3113:	/* ORA-03133: end of file on communication channel */
+				case  3114:
+				case  3122:
+				case  3135:
+				case 12153:
+				case 27146:
+				case 28511:
 					/* consider the connection closed */
 					dbh->is_closed = 1;
 					H->attached = 0;
@@ -516,6 +531,43 @@
 }
 /* }}} */

+static int pdo_oci_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
+{
+	pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
+	sb4 error_code = 0;
+	char version[256];
+
+	/* TODO move attached check to PDO level */
+	if (H->attached == 0) {
+		return FAILURE;
+	}
+	/* TODO add persistent_timeout check at PDO level */
+
+
+	/* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
+	 * such as from Pre-10.1 servers, the error is still from the server and we would have
+	 * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
+	 * Pre-10.2 clients
+	 */
+#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))	/* OCIPing available 10.2 onwards */
+	H->last_err = OCIPing (H->svc, H->err, OCI_DEFAULT);
+#else
+	/* use good old OCIServerVersion() */
+	H->last_err = OCIServerVersion (H->svc, H->err, (text *)version, sizeof(version), OCI_HTYPE_SVCCTX);
+#endif
+	if (H->last_err == OCI_SUCCESS) {
+		return SUCCESS;
+	}
+
+	OCIErrorGet (H->err, (ub4)1, NULL, &error_code, NULL, 0, OCI_HTYPE_ERROR);
+
+	if (error_code == 1010) {
+		return SUCCESS;
+	}
+	return FAILURE;
+}
+/* }}} */
+
 static struct pdo_dbh_methods oci_methods = {
 	oci_handle_closer,
 	oci_handle_preparer,
@@ -528,7 +580,7 @@
 	NULL,
 	pdo_oci_fetch_error_func,
 	oci_handle_get_attribute,
-	NULL,	/* check_liveness */
+	pdo_oci_check_liveness,	/* check_liveness */
 	NULL	/* get_driver_methods */
 };

@@ -675,6 +727,7 @@
 }
 /* }}} */

+
 /*
  * Local variables:
  * tab-width: 4
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to