#ifdef RCSID static char *RCSid = "$Header: cdemofo.c 25-jan-00.15:42:06 mrhodes Exp $ "; #endif /* RCSID */ /* Copyright (c) 1998, 1999,, 2000 Oracle Corporation. All rights reserved. */ /* NAME cdemofo.c - C demo program for OCI callbacks for application failover DESCRIPTION This is an example program to demonstrate the registration and operation of OCI application failover callbacks. PUBLIC FUNCTION(S) main - main entry point PRIVATE FUNCTION(S) checkerr - check errors cleanup - cleanup resources register_callback - register failover callback callback_fn - callback function RETURNS EX_SUCESS on success EX_FAILURE on failure NOTES This is just a demo program for the failover callbacks. A complete failover example would require someway of simulating the failure of the connection and switching to a new instance MODIFIED (MM/DD/YY) mrhodes 01/25/00 - make sleep call nt compatible mjaeger 07/14/99 - bug 808870: OCCS: convert tabs, no long lines slari 10/14/98 - remove OCI_FO_TXNAL slari 10/13/98 - demo program for oci application failover callbacks slari 10/13/98 - Creation */ /* for WINDOWS compatibility of 'sleep' call */ #if defined(WIN32COMMON) || defined(WIN32) || defined(_WIN32) #include #define sleep(x) Sleep(1000*(x)) #endif #include #include #include #include #ifdef __STDC__ #include #else #include #endif #define EX_SUCCESS 0 #define EX_FAILURE -1 static text *username = (text *) "SCOTT"; static text *password = (text *) "TIGER"; static text *dbname = (text *) "inst1"; /* Define SQL statements to be used in program. */ static text *sel1 = (text *) "SELECT empno FROM emp order by empno"; static OCIEnv *envhp = 0; static OCIServer *srvhp = 0; static OCIError *errhp = 0; static OCISvcCtx *svchp = 0; static OCIStmt *stmthp = 0; static OCIDefine *defnp = (OCIDefine *) 0; static OCIBind *bnd1p = (OCIBind *) 0; static sb4 checkerr(/*_ OCIError *errhp, sword status _*/); static void cleanup(/*_ void _*/); static sb4 register_callback(); static sb4 callback_fn(); int main(/*_ int argc, char *argv[] _*/); static sword status; int main(argc, argv) int argc; char *argv[]; { int exitCode = EX_FAILURE; sword i=0, empno=0, count=0, totcount=0; OCISession *authp = (OCISession *) 0; if (checkerr(NULL, OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0))) goto terminate; if (checkerr(NULL, OCIEnvInit((OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0, (dvoid **) 0))) goto terminate; if (checkerr(envhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **)0))) goto terminate; /* server contexts */ if (checkerr(envhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0))) goto terminate; if (checkerr(envhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0))) goto terminate; if (checkerr(errhp, OCIServerAttach(srvhp, errhp, (text *)dbname, strlen((char *)dbname), 0))) goto terminate; /* set attribute server context in the service context */ if (checkerr(errhp, OCIAttrSet((dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp))) goto terminate; if (checkerr(envhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp, (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0))) goto terminate; if (checkerr(errhp, OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) strlen((char *)username), (ub4) OCI_ATTR_USERNAME, errhp))) goto terminate; if (checkerr(errhp, OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) strlen((char *)password), (ub4) OCI_ATTR_PASSWORD, errhp))) goto terminate; if (checkerr(errhp, OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, (ub4) OCI_DEFAULT))) goto terminate; if (checkerr(errhp, OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) authp, (ub4) 0, (ub4) OCI_ATTR_SESSION, errhp))) goto terminate; /* registers the OCI application failover callbacks */ if (register_callback(srvhp, errhp)) goto terminate; if (checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0))) goto terminate; /* process SQL statement */ if (checkerr(errhp, OCIStmtPrepare(stmthp, errhp, sel1, (ub4) strlen((char *) sel1), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT))) goto terminate; if (checkerr(errhp, OCIDefineByPos(stmthp, &defnp, errhp, 1, (dvoid *) &empno, (sword) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT))) goto terminate; status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); for(;;) { if (status != 0) { if (status == OCI_NO_DATA) break; else { checkerr(errhp, status); goto terminate; } } printf("empno: %d\n", empno); /* execute and fetch */ status=OCIStmtFetch(stmthp, errhp, (ub4) 1, (ub4) 0, (ub4) 0); } exitCode = EX_SUCCESS; terminate: if (exitCode == EX_SUCCESS) printf("No errors.\n"); else printf("Failed due to errors.\n"); cleanup(); return exitCode; } /* application failoever callback function */ sb4 callback_fn(svchp, envhp, fo_ctx, fo_type, fo_event ) dvoid * svchp; dvoid * envhp; dvoid *fo_ctx; ub4 fo_type; ub4 fo_event; { 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(3); return OCI_FO_RETRY; break; } default: { printf("Bad Failover Event: %d.\n", fo_event); break; } } return 0; } /* callback function registration */ sb4 register_callback(srvhp, errhp) dvoid *srvhp; /* the server handle */ OCIError *errhp; /* the error handle */ { OCIFocbkStruct failover; /* failover callback structure */ /* allocate memory for context */ if (!(failover.fo_ctx = (dvoid *)malloc(strlen("Application Failove Context")))) { (void) printf("Error - could not allocate failover context\n"); return EX_FAILURE; } /* initialize the context. */ strcpy((char *)failover.fo_ctx, "Application Failover Context"); failover.callback_function = &callback_fn; /* do the registration */ if (checkerr(errhp, OCIAttrSet(srvhp, (ub4) OCI_HTYPE_SERVER, (dvoid *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, errhp))) { printf("Failed to set failover attribute\n"); return EX_FAILURE; } return EX_SUCCESS; } /* error handler */ sb4 checkerr(ehndlp, status) dvoid *ehndlp; sword status; { text errbuf[512]; sb4 errcode = 0; switch (status) { case OCI_SUCCESS: return EX_SUCCESS; case OCI_SUCCESS_WITH_INFO: printf("Error - OCI_SUCCESS_WITH_INFO\n"); return EX_SUCCESS; case OCI_NEED_DATA: printf("Error - OCI_NEED_DATA\n"); return EX_SUCCESS; case OCI_NO_DATA: printf("Error - OCI_NODATA\n"); return EX_SUCCESS; case OCI_ERROR: if (ehndlp) { OCIErrorGet((dvoid *)ehndlp, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); printf("Error - %.*s\n", 512, errbuf); } else printf("Error - OCI_ERROR\n"); return EX_FAILURE; case OCI_INVALID_HANDLE: printf("Error - OCI_INVALID_HANDLE\n"); return EX_FAILURE; case OCI_STILL_EXECUTING: printf("Error - OCI_STILL_EXECUTE\n"); return EX_SUCCESS; case OCI_CONTINUE: printf("Error - OCI_CONTINUE\n"); return EX_SUCCESS; default: printf("Error - Unknown error\n"); return EX_FAILURE; } } /* cleanup resources */ void cleanup() { if (stmthp) checkerr(errhp, OCIHandleFree((dvoid *) stmthp, OCI_HTYPE_STMT)); if (errhp && srvhp) (void) OCIServerDetach( srvhp, errhp, OCI_DEFAULT ); if (srvhp) checkerr(errhp, OCIHandleFree((dvoid *) srvhp, OCI_HTYPE_SERVER)); if (svchp) (void) OCIHandleFree((dvoid *) svchp, OCI_HTYPE_SVCCTX); if (errhp) (void) OCIHandleFree((dvoid *) errhp, OCI_HTYPE_ERROR); if (envhp) (void) OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV); return; } /* end of file cdemofo.c */