[svn:dbd-oracle] r14733 - dbd-oracle/branches/TAF

[email protected] Fri, 4 Mar 2011 12:48:28 -0800 (PST)
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
Author: byterock
Date: Fri Mar  4 12:48:26 2011
New Revision: 14733

Modified:
   dbd-oracle/branches/TAF/Oracle.pm
   dbd-oracle/branches/TAF/dbdimp.c
   dbd-oracle/branches/TAF/dbdimp.h
   dbd-oracle/branches/TAF/oci8.c

Log:
Working version

That was easy

Modified: dbd-oracle/branches/TAF/Oracle.pm
==============================================================================
--- dbd-oracle/branches/TAF/Oracle.pm	(original)
+++ dbd-oracle/branches/TAF/Oracle.pm	Fri Mar  4 12:48:26 2011
@@ -379,6 +379,9 @@
                  ora_client_info	=> undef,
                  ora_client_identifier	=> undef,
                  ora_action		=> undef,
+                 ora_taf		=> undef,
+                 ora_taf_attempts	=> undef,
+                 ora_taf_sleep		=> undef,
                
                  };
     }

Modified: dbd-oracle/branches/TAF/dbdimp.c
==============================================================================
--- dbd-oracle/branches/TAF/dbdimp.c	(original)
+++ dbd-oracle/branches/TAF/dbdimp.c	Fri Mar  4 12:48:26 2011
@@ -490,7 +490,19 @@
 
     }
 
+    /* TAF Events */
+	imp_dbh->using_taf = 0;
+
+	if (DBD_ATTRIB_TRUE(attr,"ora_taf",7,svp)){
+		imp_dbh->using_taf = 1;
+		imp_dbh->taf_sleep = 5; /* 5 second default */
+    	DBD_ATTRIB_GET_IV( attr, "ora_taf_attempts",  16, svp, imp_dbh->taf_attempts);
+    	DBD_ATTRIB_GET_IV( attr, "ora_taf_sleep",  13, svp, imp_dbh->taf_sleep);
+
+	}
+
     imp_dbh->server_version = 0;
+
 	/* check to see if DBD_verbose or ora_verbose is set*/
 	if (DBD_ATTRIB_TRUE(attr,"dbd_verbose",11,svp))
 		DBD_ATTRIB_GET_IV(  attr, "dbd_verbose",  11, svp, dbd_verbose);
@@ -1037,6 +1049,29 @@
 	}
 #endif
 
+    /* set up TAF callback if wanted */
+
+
+    if (imp_dbh->using_taf){
+		bool	can_taf;
+        OCIAttrGet_log_stat(imp_dbh->srvhp, OCI_HTYPE_SERVER, &can_taf, NULL,
+				OCI_ATTR_TAF_ENABLED, imp_dbh->errhp, status);
+
+		if (!can_taf){
+				croak("You are attempting to enable TAF on a server that is not TAF Enabled \n");
+		}
+
+		if (DBIS->debug >= 4 || dbd_verbose >= 4 ) {
+        	PerlIO_printf(DBILOGFP,"Setting up TAF with wait time of %d seconds\n",imp_dbh->taf_sleep);
+		}
+		status = reg_taf_callback(imp_dbh);
+		if (status != OCI_SUCCESS) {
+			oci_error(dbh, NULL, status,
+				"Setting TAF Callback Failed! ");
+			return 0;
+		}
+	}
+
 	return 1;
 }
 
@@ -1263,6 +1298,21 @@
 		imp_dbh->pool_incr = SvIV (valuesv);
 	}
 #endif
+	else if (kl==7 && strEQ(key, "ora_taf") ) {
+		imp_dbh->using_taf = 1;
+	}
+	else if (kl==16 && strEQ(key, "ora_taf_attempts") ) {
+		imp_dbh->taf_attempts = SvIV (valuesv);
+	}
+	else if (kl==13 && strEQ(key, "ora_taf_sleep") ) {
+			imp_dbh->taf_sleep = SvIV (valuesv);
+	}
+	else if (kl==10 && strEQ(key, "ora_action") ) {
+		imp_dbh->action = (char *) SvPV (valuesv, vl );
+		imp_dbh->actionl= (ub4) vl;
+		OCIAttrSet_log_stat(imp_dbh->seshp,OCI_HTYPE_SESSION, imp_dbh->action,imp_dbh->actionl,OCI_ATTR_ACTION,imp_dbh->errhp, status);
+
+	}
 	else if (kl==10 && strEQ(key, "ora_action") ) {
 		imp_dbh->action = (char *) SvPV (valuesv, vl );
 		imp_dbh->actionl= (ub4) vl;
@@ -1367,6 +1417,15 @@
 		retsv = newSViv(imp_dbh->pool_incr);
 	}
 #endif
+	else if (kl==7 && strEQ(key, "ora_taf") ) {
+		retsv = newSViv(imp_dbh->using_taf);
+	}
+	else if (kl==16 && strEQ(key, "ora_taf_attempts") ) {
+		retsv = newSViv(imp_dbh->taf_attempts);
+	}
+	else if (kl==13 && strEQ(key, "ora_taf_sleep") ) {
+		retsv = newSViv(imp_dbh->taf_sleep);
+	}
 	else if (kl==10 && strEQ(key, "ora_action")) {
 		retsv =  newSVpv((char *)imp_dbh->action,0);
 	}
@@ -1433,23 +1492,23 @@
 SV *
 createxmlfromstring(SV *sth, imp_sth_t *imp_sth, SV *source){
 
-dTHX;
-dTHR;
-OCIXMLType *xml = NULL;
-STRLEN len;
-ub4 buflen;
-sword status;
-ub1 src_type;
-dvoid* src_ptr = NULL;
-D_imp_dbh_from_sth;
-SV* sv_dest;
-dvoid *bufp;
-ub1 csform;
-ub2 csid;
-csid = 0;
-csform = SQLCS_IMPLICIT;
-len = SvLEN(source);
-bufp = SvPV(source, len);
+	dTHX;
+	dTHR;
+	OCIXMLType *xml = NULL;
+	STRLEN len;
+	ub4 buflen;
+	sword status;
+	ub1 src_type;
+	dvoid* src_ptr = NULL;
+	D_imp_dbh_from_sth;
+	SV* sv_dest;
+	dvoid *bufp;
+	ub1 csform;
+	ub2 csid;
+	csid 	= 0;
+	csform 	= SQLCS_IMPLICIT;
+	len 	= SvLEN(source);
+	bufp 	= SvPV(source, len);
 
 	if (DBIS->debug >=3 || dbd_verbose >= 3 )
         PerlIO_printf(DBILOGFP, " creating xml from string that is %lu long\n",(unsigned long)len);

Modified: dbd-oracle/branches/TAF/dbdimp.h
==============================================================================
--- dbd-oracle/branches/TAF/dbdimp.h	(original)
+++ dbd-oracle/branches/TAF/dbdimp.h	Fri Mar  4 12:48:26 2011
@@ -53,6 +53,9 @@
 	char		*driver_name;/*driver name user defined*/
 	ub4			driver_namel;
 #endif
+    bool		using_taf; /*TAF stuff*/
+    int			taf_attempts;
+    int			taf_sleep;
     char		*client_info;  /*user defined*/
     ub4			client_infol;
 	char		*module_name; /*module user defined */
@@ -385,6 +388,7 @@
 void rs_array_init(imp_sth_t *imp_sth);
 
 ub4 ora_db_version _((SV *dbh, imp_dbh_t *imp_dbh));
+sb4 reg_taf_callback _((imp_dbh_t *imp_dbh));
 
 /* These defines avoid name clashes for multiple statically linked DBD's	*/
 

Modified: dbd-oracle/branches/TAF/oci8.c
==============================================================================
--- dbd-oracle/branches/TAF/oci8.c	(original)
+++ dbd-oracle/branches/TAF/oci8.c	Fri Mar  4 12:48:26 2011
@@ -1269,7 +1269,8 @@
 	to get it all.  I also take set fb_ary->cb_abuf back to empty just
 	to keep things clean
  -------------------------------------------------------------- */
-sb4 presist_lob_fetch_cbk(dvoid *octxp, OCIDefine *dfnhp, ub4 iter, dvoid **bufpp,
+sb4
+presist_lob_fetch_cbk(dvoid *octxp, OCIDefine *dfnhp, ub4 iter, dvoid **bufpp,
 					  ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp)
 {
 	dTHX;
@@ -1283,7 +1284,7 @@
 
 
 	if (dbd_verbose >= 5 ) {
-			PerlIO_printf(DBILOGFP, " In presist_lob_fetch_cbk\n");
+		PerlIO_printf(DBILOGFP, " In presist_lob_fetch_cbk\n");
 	}
 
 	if ( *piecep ==OCI_NEXT_PIECE ){/*more than one piece*/
@@ -1304,6 +1305,102 @@
 
 }
 
+/* TAF or Trasarent Application Failoever callback
+   Works like this.  The fuction below is registered on the server,
+   when the server is set up to use it, when an exe is called (not sure about other server round trips)
+   and the server fails tt should get into this cbk error below.
+   It will wait X seconds and then try to reconnect (up to n times if that is the users choice)
+   That is how I see it working */
+
+sb4
+taf_cbk(dvoid *svchp, dvoid *envhp, dvoid *fo_ctx,ub4 fo_type, ub4 fo_event )
+{
+	dTHX;
+	imp_dbh_t *dbh =(imp_dbh_t*)fo_ctx;
+
+  switch (fo_event)
+  {
+   case OCI_FO_BEGIN:
+   {
+     printf(" Failing Over ... Please stand by \n");
+     printf(" Failover type was found to be %s \n",
+                     ((fo_type==OCI_FO_NONE) ? "NONE"
+                     :(fo_type==OCI_FO_SESSION) ? "SESSION"
+                     :(fo_type==OCI_FO_SELECT) ? "SELECT"
+                     : "UNKNOWN!"));
+     printf(" Failover Context is :%s\n",
+            (fo_ctx?(char *)fo_ctx:"NULL POINTER!"));
+     break;
+   }
+
+   case OCI_FO_ABORT:
+   {
+     printf(" Failover aborted. Failover will not take place.\n");
+     break;
+   }
+
+   case OCI_FO_END:
+   {
+     printf(" Failover ended ...resuming services\n");
+     break;
+   }
+
+   case OCI_FO_REAUTH:
+   {
+     printf(" Failed over user. Resuming services\n");
+
+                    /* Application can check the OCI_ATTR_SESSION attribute of
+                       the service handle to find out the user being
+                       re-authenticated.
+
+                       After this, the application can replay any ALTER SESSION
+                       commands associated with this session.  These must have
+                      been saved by the application in the fo_ctx
+                     */
+     break;
+   }
+
+
+   case OCI_FO_ERROR:
+   {
+     printf(" Failover error gotten. Sleeping...\n");
+     sleep(dbh->taf_sleep);
+     return OCI_FO_RETRY;
+     break;
+   }
+
+   default:
+   {
+     printf("Bad Failover Event: %d.\n",  fo_event);
+     break;
+   }
+  }
+  return 0;
+}
+
+
+sb4
+reg_taf_callback(imp_dbh_t *imp_dbh)
+{
+	dTHX;
+	OCIFocbkStruct 	tafailover;
+	sword 			status;
+
+  	if (dbd_verbose >= 5 ) {
+  		PerlIO_printf(DBILOGFP, " In reg_taf_callback\n");
+	}
+/* set the context up as a pointer to the handle*/
+    tafailover.fo_ctx = imp_dbh;
+
+  	tafailover.callback_function = &taf_cbk;
+
+    OCIAttrSet_log_stat(imp_dbh->srvhp, (ub4) OCI_HTYPE_SERVER,
+								(dvoid *) &tafailover, (ub4) 0,
+                                 (ub4) OCI_ATTR_FOCBK, imp_dbh->errhp, status);
+
+	return status;
+}
+
 #ifdef UTF8_SUPPORT
 /* How many bytes are n utf8 chars in buffer */
 static ub4