/*--------------------------------------------------------------------------- PRIVATE FUNCTIONS ---------------------------------------------------------------------------*/ static int qxiqtce( OCIExtProcContext *ctx, OCIError *errhp, sword status) { text errbuf[512]; sb4 errcode = 0; int errnum = 29400; /* choose some oracle error number */ int rc = 0; switch (status) { case OCI_SUCCESS: rc = 0; break; case OCI_ERROR: (void) OCIErrorGet((dvoid *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); OCIExtProcRaiseExcpWithMsg(ctx, errnum, errbuf, strlen((char *)errbuf)); rc = 1; break; default: (void) sprintf((char *)errbuf, "Warning - some error\n"); OCIExtProcRaiseExcpWithMsg(ctx, errnum, errbuf, strlen((char *)errbuf)); rc = 1; break; } return (rc); }
void extprocsh(OCIExtProcContext *ctx, char *cmd, short cmdInd) { int excNum = 20001; char excMsg[512]; size_t excMsgLen; if (cmdInd == OCI_IND_NULL) return; if (system(cmd) != 0) { sprintf(excMsg, "Error %i during system call: %.*s", errno, 475, strerror(errno)); excMsgLen = (size_t)strlen(excMsg); if (OCIExtProcRaiseExcpWithMsg(ctx, excNum, (text *)excMsg, excMsgLen) != OCIEXTPROC_SUCCESS) return; } }
int checkerr(Handles_t* handles, sword status, const char* info) { text errbuf[512]; /* error message buffer */ text errbuf1[512]; /* error message buffer */ sb4 errcode; /* OCI error code */ switch (status) { case OCI_SUCCESS: case OCI_SUCCESS_WITH_INFO: return 0; case OCI_ERROR: OCIErrorGet((dvoid*)handles->errhp, (ub4)1, (text *)NULL, &errcode, errbuf1, (ub4)sizeof(errbuf1), (ub4)OCI_HTYPE_ERROR); sprintf((char*)errbuf, "%s: OCI ERROR code %d: %s", info, errcode, (char*)errbuf1); break; case OCI_INVALID_HANDLE: sprintf((char*)errbuf, "Error - OCI_INVALID_HANDLE: %s", info); break; case OCI_NEED_DATA: sprintf((char*)errbuf, "Error - OCI_NEED_DATA\n"); break; case OCI_NO_DATA: sprintf((char*)errbuf, "Error - OCI_NO_DATA\n"); break; case OCI_STILL_EXECUTING: sprintf((char*)errbuf, "Error - OCI_STILL_EXECUTE\n"); break; case OCI_CONTINUE: sprintf((char*)errbuf, "Error - OCI_CONTINUE\n"); break; default: sprintf((char*)errbuf, "Warning - error status %d: %s",status, info); break; } OCIExtProcRaiseExcpWithMsg(handles->extProcCtx, 29400, errbuf, strlen((char*)errbuf)); return -1; }
/* ODCIIndexStart function */ OCINumber *qxiqtbsps( OCIExtProcContext *ctx, qxiqtim *sctx, qxiqtin *sctx_ind, ODCIIndexInfo *ix, ODCIIndexInfo_ind *ix_ind, ODCIPredInfo *pr, ODCIPredInfo_ind *pr_ind, ODCIQueryInfo *qy, ODCIQueryInfo_ind *qy_ind, OCINumber *strt, short strt_ind, OCINumber *stop, short stop_ind, char *cmpval, short cmpval_ind, ODCIEnv *env, ODCIEnv_ind *env_ind) { sword status; OCIEnv *envhp = (OCIEnv *) 0; /* env. handle */ OCISvcCtx *svchp = (OCISvcCtx *) 0; /* service handle */ OCIError *errhp = (OCIError *) 0; /* error handle */ OCISession *usrhp = (OCISession *) 0; /* user handle */ qxiqtcx *icx = (qxiqtcx *) 0; /* state to be saved for later calls */ int strtval; /* start bound */ int stopval; /* stop bound */ int errnum = 29400; /* choose some oracle error number */ char errmsg[512]; /* error message buffer */ size_t errmsglen; /* Length of error message */ char relop[3]; /* relational operator used in sql stmt */ char selstmt[2000]; /* sql select statement */ int retval = (int)ODCI_SUCCESS; /* return from this function */ OCINumber *rval = (OCINumber *)0; ub4 key; /* key value set in "sctx" */ ub1 *rkey; /* key to retrieve context */ ub4 rkeylen; /* length of key */ ODCIColInfo *colinfo; /* column info */ ODCIColInfo_ind *colinfo_ind; boolean exists = TRUE; int partiden; /* table partition iden */ /* Get oci handles */ if (qxiqtce(ctx, errhp, OCIExtProcGetEnv(ctx, &envhp, &svchp, &errhp))) return(rval); /* set up return code */ rval = (OCINumber *)OCIExtProcAllocCallMemory(ctx, sizeof(OCINumber)); if (qxiqtce(ctx, errhp, OCINumberFromInt(errhp, (dvoid *)&retval, sizeof(retval), OCI_NUMBER_SIGNED, rval))) return(rval); /* get the user handle */ if (qxiqtce(ctx, errhp, OCIAttrGet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)&usrhp, (ub4 *)0, (ub4)OCI_ATTR_SESSION, errhp))) return(rval); /**********************************************/ /* Allocate memory to hold index scan context */ /**********************************************/ if (sctx_ind ->atomic_qxiqtin == OCI_IND_NULL || sctx_ind ->scind_qxiqtin == OCI_IND_NULL) { if (qxiqtce(ctx, errhp, OCIMemoryAlloc((dvoid *)usrhp, errhp, (dvoid **)&icx, OCI_DURATION_STATEMENT, (ub4)(sizeof(qxiqtcx)), OCI_MEMORY_CLEARED))) return(rval); icx->stmthp = (OCIStmt *)0; icx->defnp = (OCIDefine *)0; icx->bndp = (OCIBind *)0; } else { /*************************/ /* Retrieve scan context */ /*************************/ rkey = OCIRawPtr(envhp, sctx->sctx_qxiqtim); rkeylen = OCIRawSize(envhp, sctx->sctx_qxiqtim); if (qxiqtce(ctx, errhp, OCIContextGetValue((dvoid *)usrhp, errhp, rkey, (ub1)rkeylen, (dvoid **)&(icx)))) return(rval); } /***********************************/ /* Check that the bounds are valid */ /***********************************/ /* convert from oci numbers to native numbers */ if (qxiqtce(ctx, errhp, OCINumberToInt(errhp, strt, sizeof(strtval), OCI_NUMBER_SIGNED, (dvoid *)&strtval))) return(rval); if (qxiqtce(ctx, errhp, OCINumberToInt(errhp, stop, sizeof(stopval), OCI_NUMBER_SIGNED, (dvoid *)&stopval))) return(rval); /* verify that strtval/stopval are both either 0 or 1 */ if (!(((strtval == 0) && (stopval == 0)) || ((strtval == 1) && (stopval == 1)))) { strcpy(errmsg, (char *)"Incorrect predicate for sbtree operator"); errmsglen = (size_t)strlen(errmsg); if (OCIExtProcRaiseExcpWithMsg(ctx, errnum, (text *)errmsg, errmsglen) != OCIEXTPROC_SUCCESS) /* Use cartridge error services here */; return(rval); } /*********************************************/ /* Generate the SQL statement to be executed */ /*********************************************/ if (memcmp((dvoid *)OCIStringPtr(envhp, pr->ObjectName), (dvoid *)"EQ", 2) == 0) if (strtval == 1) strcpy(relop, (char *)"="); else strcpy(relop, (char *)"!="); else if (memcmp((dvoid *)OCIStringPtr(envhp, pr->ObjectName), (dvoid *)"LT", 2) == 0) if (strtval == 1) strcpy(relop, (char *)"<"); else strcpy(relop, (char *)">="); else if (strtval == 1) strcpy(relop, (char *)">"); else strcpy(relop, (char *)"<="); if (ix_ind->IndexPartitionIden == OCI_IND_NULL) (void)sprintf(selstmt, "select f2 from %s.%s_sbtree where f1 %s :val", OCIStringPtr(envhp, ix->IndexSchema), OCIStringPtr(envhp, ix->IndexName), relop); else { if (qxiqtce(ctx, errhp, OCICollGetElem(envhp, errhp, (OCIColl *)ix->IndexCols, (sb4)0, &exists, (void **) &colinfo, (void **) &colinfo_ind))) return(rval); (void)sprintf(selstmt, "select f2 from %s.%s_sbtree partition (DATAOBJ_TO_PARTITION(%s, :partiden)) where f1 %s :val", OCIStringPtr(envhp, ix->IndexSchema), OCIStringPtr(envhp, ix->IndexName), OCIStringPtr(envhp, colinfo->TableName), relop); } /***********************************/ /* Parse, bind, define and execute */ /***********************************/ if (sctx_ind ->atomic_qxiqtin == OCI_IND_NULL || sctx_ind ->scind_qxiqtin == OCI_IND_NULL) { /* allocate stmt handle */ if (qxiqtce(ctx, errhp, OCIHandleAlloc((dvoid *)envhp, (dvoid **)&(icx->stmthp), (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0))) return(rval); } /* prepare the statement */ if (qxiqtce(ctx, errhp, OCIStmtPrepare(icx->stmthp, errhp, (text *)selstmt, (ub4)strlen(selstmt), OCI_NTV_SYNTAX, OCI_DEFAULT))) return(rval); if (ix_ind->IndexPartitionIden != OCI_IND_NULL) { /* Convert partiden to integer from OCINumber */ if (qxiqtce(ctx, errhp, OCINumberToInt(errhp, &(colinfo->TablePartitionIden), sizeof(partiden), OCI_NUMBER_SIGNED, ( void *)&partiden))) return(rval); /* Set up bind for partiden */ if (qxiqtce(ctx, errhp, OCIBindByName(icx->stmthp, &(icx->bndp), errhp, (text *)":partiden", sizeof(":partiden")-1, (dvoid *)&partiden, (sb4)(sizeof(partiden)), (ub2)SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT))) return(rval); } /* Set up bind for compare value */ if (qxiqtce(ctx, errhp, OCIBindByName(icx->stmthp, &(icx->bndp),errhp, (text *)":val", sizeof(":val")-1, (dvoid *)cmpval, (sb4)(strlen(cmpval)+1), (ub2)SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT))) return(rval); /* Set up define */ if (qxiqtce(ctx, errhp, OCIDefineByPos(icx->stmthp, &(icx->defnp), errhp, (ub4)1, (dvoid *)(icx->ridp), (sb4) sizeof(icx->ridp), (ub2)SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT))) return(rval); /* execute */ if (qxiqtce(ctx, errhp, OCIStmtExecute(svchp, icx->stmthp, errhp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT))) return(rval); /************************************/ /* Set index context to be returned */ /************************************/ if (sctx_ind ->atomic_qxiqtin == OCI_IND_NULL || sctx_ind ->scind_qxiqtin == OCI_IND_NULL) { /* generate a key */ if (qxiqtce(ctx, errhp, OCIContextGenerateKey((dvoid *)usrhp, errhp, &key))) return(rval); /* set the memory address of the struct to be saved in the context */ if (qxiqtce(ctx, errhp, OCIContextSetValue((dvoid *)usrhp, errhp, OCI_DURATION_STATEMENT, (ub1 *)&key, (ub1)sizeof(key), (dvoid *)icx))) return(rval); /* set the key as the member of "sctx" */ if (qxiqtce(ctx, errhp, OCIRawAssignBytes(envhp, errhp, (ub1 *)&key, (ub4)sizeof(key), &(sctx->sctx_qxiqtim)))) return(rval); sctx_ind->atomic_qxiqtin = OCI_IND_NOTNULL; sctx_ind->scind_qxiqtin = OCI_IND_NOTNULL; return(rval); } return(rval); }
PLRUBY_EXPORT OCIAnyData * extproc_ruby(OCIExtProcContext *with_context, short *ret_ind, int rettype, const char *obj, short obj_ind, const char *meth, short meth_ind, const char *argtype, int argtype_len, OCIString *v1, short v1_ind, OCIString *v2, short v2_ind, OCIString *v3, short v3_ind, OCIString *v4, short v4_ind, OCIString *v5, short v5_ind, OCIString *v6, short v6_ind, OCIString *v7, short v7_ind, OCIString *v8, short v8_ind, OCIString *v9, short v9_ind, OCIString *v10, short v10_ind, OCINumber *n1, short n1_ind, OCINumber *n2, short n2_ind, OCINumber *n3, short n3_ind, OCINumber *n4, short n4_ind, OCINumber *n5, short n5_ind, OCINumber *n6, short n6_ind, OCINumber *n7, short n7_ind, OCINumber *n8, short n8_ind, OCINumber *n9, short n9_ind, OCINumber *n10, short n10_ind, double d1, short d1_ind, double d2, short d2_ind, double d3, short d3_ind, double d4, short d4_ind, double d5, short d5_ind, double d6, short d6_ind, double d7, short d7_ind, double d8, short d8_ind, double d9, short d9_ind, double d10, short d10_ind) { plruby_context_t ctx; OCIAnyData *sdata = NULL; static int ruby_initialized = 0; OCIExtProcGetEnv(with_context, &ctx.envhp, &ctx.svchp, &ctx.errhp); ctx.obj = obj_ind ? NULL : obj; ctx.meth = meth_ind ? NULL : meth; ctx.rettype = rettype; ctx.argtype = argtype; ctx.args[0] = argtype_len >= 1 ? checkarg(argtype[0], v1, n1, &d1) : EMPTY; ctx.args[1] = argtype_len >= 2 ? checkarg(argtype[1], v2, n2, &d2) : EMPTY; ctx.args[2] = argtype_len >= 3 ? checkarg(argtype[2], v3, n3, &d3) : EMPTY; ctx.args[3] = argtype_len >= 4 ? checkarg(argtype[3], v4, n4, &d4) : EMPTY; ctx.args[4] = argtype_len >= 5 ? checkarg(argtype[4], v5, n5, &d5) : EMPTY; ctx.args[5] = argtype_len >= 6 ? checkarg(argtype[5], v6, n6, &d6) : EMPTY; ctx.args[6] = argtype_len >= 7 ? checkarg(argtype[6], v7, n7, &d7) : EMPTY; ctx.args[7] = argtype_len >= 8 ? checkarg(argtype[7], v8, n8, &d8) : EMPTY; ctx.args[8] = argtype_len >= 9 ? checkarg(argtype[8], v9, n9, &d9) : EMPTY; ctx.args[9] = argtype_len >= 10 ? checkarg(argtype[9], v10, n10, &d10) : EMPTY; if (!ruby_initialized) { ruby_init(); ruby_init_loadpath(); ruby_script("extproc_ruby"); ruby_initialized = 1; } { int state = 0; int plruby_initialized = 0; RUBY_INIT_STACK; if (!plruby_initialized) { rb_protect((VALUE(*)(VALUE))setup_plruby_oracle, (VALUE)&ctx, &state); if (state == 0) { plruby_initialized = 1; } } if (state == 0) { sdata = (OCIAnyData*)rb_protect((VALUE(*)(VALUE))call_ruby, (VALUE)&ctx, &state); } if (state) { int errnum = 20999; /* The last value of user-defined error number */ const char *errmsg = (const char *)rb_protect((VALUE(*)(VALUE))get_error_msg, (VALUE)&errnum, &state); if (state) { errmsg = "Failed to get an error in extproc_ruby"; } OCIExtProcRaiseExcpWithMsg(with_context, errnum, (OraText*)errmsg, 0); } } *ret_ind = (sdata != NULL) ? OCI_IND_NOTNULL : OCI_IND_NULL; return sdata; }