OCI_ThreadKey * OCI_ThreadKeyCreateInternal ( POCI_THREADKEYDEST destfunc ) { boolean res = TRUE; OCI_ThreadKey *key = NULL; /* allocate key structure */ key = (OCI_ThreadKey *) OCI_MemAlloc(OCI_IPC_THREADKEY, sizeof(*key), (size_t) 1, TRUE); if (key != NULL) { /* allocate error handle */ res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env, (dvoid **) (void *) &key->err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) NULL)); /* key initialization */ OCI_CALL3 ( res, key->err, OCIThreadKeyInit(OCILib.env, key->err, &key->handle, destfunc) ) }
OCI_Mutex * OCI_MutexCreateInternal ( void ) { OCI_CALL_DECLARE_CONTEXT(TRUE) OCI_Mutex *mutex = NULL; /* allocate mutex structure */ mutex = (OCI_Mutex *) OCI_MemAlloc(OCI_IPC_MUTEX, sizeof(*mutex), (size_t) 1, TRUE); OCI_STATUS = (NULL != mutex); if (OCI_STATUS) { /* allocate error handle */ OCI_STATUS = OCI_HandleAlloc(OCILib.env, (dvoid **)(void *)&mutex->err, OCI_HTYPE_ERROR); /* allocate mutex handle */ OCI_EXEC(OCIThreadMutexInit(OCILib.env, mutex->err, &mutex->handle)) } if (!OCI_STATUS && mutex) { OCI_MutexFree(mutex); mutex = NULL; } return mutex; }
OCI_Transaction * OCI_API OCI_TransactionCreate ( OCI_Connection *con, unsigned int timeout, unsigned int mode, OCI_XID *pxid ) { OCI_Item *item = NULL; OCI_Transaction *trans = NULL; boolean res = TRUE; OCI_CHECK_INITIALIZED(NULL); OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL); /* create transaction object */ item = OCI_ListAppend(con->trsns, sizeof(*trans)); if (item != NULL) { trans = (OCI_Transaction *) item->data; trans->con = con; trans->mode = mode; trans->timeout = timeout; trans->local = (pxid == NULL); /* allocate transaction handle */ if (res == TRUE) { res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) trans->con->env, (dvoid **) (void *) &trans->htr, (ub4) OCI_HTYPE_TRANS, (size_t) 0, (dvoid **) NULL)); } /* set XID attribute for global transaction */ if (pxid != NULL) { memcpy(&trans->xid, pxid, sizeof(trans->xid)); OCI_CALL2 ( res, con, OCIAttrSet((dvoid *) trans->htr, (ub4) OCI_HTYPE_TRANS, (dvoid *) &trans->xid, (ub4) sizeof(trans->xid), (ub4) OCI_ATTR_XID, trans->con->err) ) }
OCI_Transaction * OCI_API OCI_TransactionCreate ( OCI_Connection *con, unsigned int timeout, unsigned int mode, OCI_XID *pxid ) { OCI_Item *item = NULL; OCI_LIB_CALL_ENTER(OCI_Transaction *, NULL) OCI_CHECK_PTR(OCI_IPC_CONNECTION, con) /* create transaction object */ item = OCI_ListAppend(con->trsns, sizeof(*call_retval)); if (item) { call_retval = (OCI_Transaction *) item->data; call_retval->con = con; call_retval->mode = mode; call_retval->timeout = timeout; call_retval->local = (NULL == pxid); /* allocate transaction handle */ call_status = OCI_SUCCESSFUL(OCI_HandleAlloc((dvoid *) call_retval->con->env, (dvoid **) &call_retval->htr, (ub4) OCI_HTYPE_TRANS, (size_t) 0, (dvoid **) NULL)); /* set XID attribute for global transaction */ if (call_status && pxid) { memcpy(&call_retval->xid, pxid, sizeof(call_retval->xid)); OCI_CALL2 ( call_status, con, OCIAttrSet((dvoid *) call_retval->htr, (ub4) OCI_HTYPE_TRANS, (dvoid *) &call_retval->xid, (ub4) sizeof(call_retval->xid), (ub4) OCI_ATTR_XID, call_retval->con->err) ) } }
OCI_Mutex * OCI_MutexCreateInternal ( void ) { OCI_Mutex *mutex = NULL; boolean res = FALSE; /* allocate mutex structure */ mutex = (OCI_Mutex *) OCI_MemAlloc(OCI_IPC_MUTEX, sizeof(*mutex), (size_t) 1, TRUE); if (mutex) { /* allocate error handle */ res = OCI_SUCCESSFUL(OCI_HandleAlloc(OCILib.env, (dvoid **) (void *) &mutex->err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) NULL)); /* allocate mutex handle */ OCI_CALL3 ( res, mutex->err, OCIThreadMutexInit(OCILib.env, mutex->err, &mutex->handle) ) } if (!res && mutex) { OCI_MutexFree(mutex); mutex = NULL; } return mutex; }
boolean OCI_DefineAlloc ( OCI_Define *def ) { boolean res = TRUE; ub4 indsize = 0; ub4 i; /* this function allocates internal buffers, handles, indicators, arrays, ... for the given output define handle */ OCI_CHECK(NULL == def, FALSE) /* Allocate null indicators array */ if (SQLT_NTY == def->col.sqlcode || SQLT_REF == def->col.sqlcode) { indsize = (ub4) sizeof(void*); } else { indsize = (ub4) sizeof(sb2); } def->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY, (size_t) indsize, (size_t) def->buf.count, TRUE); res = (NULL != def->buf.inds); if (OCI_CDT_OBJECT == def->col.datatype) { def->buf.obj_inds = (void **) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY, sizeof(void *), (size_t) def->buf.count, TRUE); res = (NULL != def->buf.obj_inds); } /* Allocate row data sizes array */ if (res) { def->buf.lens = (void *) OCI_MemAlloc(OCI_IPC_LEN_ARRAY, (size_t) def->buf.sizelen, (size_t) def->buf.count, TRUE); res = (NULL != def->buf.lens); } /* initialize length array with buffer default size. But, Oracle uses different sizes for static fetch and callback fetch....*/ if (res) { ub4 bufsize = 0; for (i=0; i < def->buf.count; i++) { if (def->buf.sizelen == (int) sizeof(ub2)) { *(ub2*)(((ub1 *)def->buf.lens) + (size_t) (def->buf.sizelen*i)) = (ub2) def->col.bufsize; } else if (def->buf.sizelen == (int) sizeof(ub4)) { *(ub4*)(((ub1 *)def->buf.lens) + (size_t) (def->buf.sizelen*i)) = (ub4) def->col.bufsize; } } /* Allocate buffer array */ if (OCI_CDT_LONG == def->col.datatype) { bufsize = (ub4) sizeof(OCI_Long *); } else { bufsize = def->col.bufsize; } def->buf.data = (void **) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, (size_t) bufsize, (size_t) def->buf.count, TRUE); res = (NULL != def->buf.data); } /* Allocate descriptor for cursor, lob and file, interval and timestamp */ if (res && OCI_UNKNOWN != def->col.handletype) { if (OCI_CDT_CURSOR == def->col.datatype) { for (i = 0; (i < def->buf.count) && res; i++) { res = OCI_SUCCESSFUL(OCI_HandleAlloc((dvoid *) def->rs->stmt->con->env, (dvoid **) &(def->buf.data[i]), (ub4) def->col.handletype, (size_t) 0, (dvoid **) NULL)); } } else { res = OCI_SUCCESSFUL(OCI_DescriptorArrayAlloc((dvoid *) def->rs->stmt->con->env, (dvoid **) def->buf.data, (ub4) def->col.handletype, (ub4) def->buf.count, (size_t) 0, (dvoid **) NULL)); if (res && (OCI_CDT_LOB == def->col.datatype)) { ub4 empty = 0; for (i = 0; (i < def->buf.count) && res; i++) { OCI_CALL1 ( res, def->rs->stmt->con, def->rs->stmt, OCIAttrSet((dvoid *) def->buf.data[i], (ub4) def->col.handletype, (void *) &empty, (ub4) sizeof(empty), (ub4) OCI_ATTR_LOBEMPTY, def->rs->stmt->con->err) ) } } } }
OCI_EXPORT boolean OCI_API OCI_DequeueSubscribe ( OCI_Dequeue *dequeue, unsigned int port, unsigned int timeout, POCI_NOTIFY_AQ callback ) { boolean res = TRUE; ub4 oci_namespace = OCI_SUBSCR_NAMESPACE_AQ; #if OCI_VERSION_COMPILE >= OCI_10_2 ub4 oci_port = (ub4) port; ub4 oci_timeout = (ub4) timeout; ub4 oci_protocol = OCI_SUBSCR_PROTO_OCI; ub4 oci_msgpres = OCI_SUBSCR_PRES_DEFAULT; #endif OCI_Connection *con = NULL; OCI_CHECK_INITIALIZED(FALSE); OCI_CHECK_DATABASE_NOTIFY_ENABLED(FALSE); OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE); con = dequeue->typinf->con; /* clear any previous subscription */ OCI_DequeueUnsubscribe(dequeue); /* allocate subcription handle */ res = (OCI_SUCCESS == OCI_HandleAlloc(con->env, (dvoid **) (void *) &dequeue->subhp, OCI_HTYPE_SUBSCRIPTION, (size_t) 0, (dvoid **) NULL)); #if OCI_VERSION_COMPILE >= OCI_10_2 /* set port number */ if (oci_port > 0) { OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) &oci_port, (ub4) sizeof (oci_port), (ub4) OCI_ATTR_SUBSCR_PORTNO, con->err) ) } /* set timeout */ if (oci_timeout > 0) { OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) &oci_timeout, (ub4) sizeof (oci_timeout), (ub4) OCI_ATTR_SUBSCR_TIMEOUT, con->err) ) } /* set protocol */ OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) &oci_protocol, (ub4) sizeof(oci_protocol), (ub4) OCI_ATTR_SUBSCR_RECPTPROTO, con->err) ) /* set presentation */ OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) &oci_msgpres, (ub4) sizeof(oci_msgpres), (ub4) OCI_ATTR_SUBSCR_RECPTPRES, con->err) ) #else OCI_NOT_USED(port); OCI_NOT_USED(timeout); #endif /* set name */ if (dequeue->name != NULL) { /* for AQ subscription, the name should be "[shema.]queue[:consumer]" */ mtext buffer[(OCI_SIZE_OBJ_NAME*2) + 2] = MT(""); mtext *str = NULL; size_t size = sizeof(buffer)/sizeof(mtext); void *ostr = NULL; int osize = -1; mtsncat(buffer, dequeue->name, size); if (dequeue->consumer != NULL) { size -= mtslen(dequeue->name); mtsncat(buffer, MT(":"), size); size -= (size_t) 1; mtsncat(buffer, dequeue->consumer, size); } /* queue name must be uppercase */ for (str = buffer; *str != 0; str++) { *str = (mtext) mttoupper(*str); } ostr = OCI_GetInputMetaString(buffer, &osize); OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_SUBSCR_NAME, con->err) ) OCI_ReleaseMetaString(ostr); } /* set namespace */ OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) &oci_namespace, (ub4) sizeof(oci_namespace), (ub4) OCI_ATTR_SUBSCR_NAMESPACE, con->err) ) /* set context pointer to dequeue structure */ OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) dequeue, (ub4) 0, (ub4) OCI_ATTR_SUBSCR_CTX, con->err) ) /* internal callback handler */ OCI_CALL3 ( res, con->err, OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION, (dvoid *) OCI_ProcNotifyMessages, (ub4) 0, (ub4) OCI_ATTR_SUBSCR_CALLBACK, con->err) ) /* all attributes set, let's register the subscription ! */ OCI_CALL3 ( res, con->err, OCISubscriptionRegister(con->cxt, &dequeue->subhp, (ub2) 1, con->err,(ub4) OCI_DEFAULT) ) /* set callback on success */ if (res) { dequeue->callback = callback; } else { /* clear subscription on failure */ OCI_DequeueUnsubscribe(dequeue); } OCI_RESULT(res); return res; }
OCI_DirPath * OCI_API OCI_DirPathCreate ( OCI_TypeInfo *typinf, const mtext *partition, unsigned int nb_cols, unsigned int nb_rows ) { OCI_DirPath *dp = NULL; void *ostr = NULL; int osize = -1; boolean res = TRUE; OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL); OCI_CHECK_COMPAT(typinf->con, typinf->type != OCI_TIF_TYPE, NULL); OCI_CHECK_BOUND(typinf->con, nb_cols, 1, typinf->nb_cols, NULL); /* allocate direct path structure */ dp = (OCI_DirPath *) OCI_MemAlloc(OCI_IPC_DIRPATH, sizeof(*dp), (size_t) 1, TRUE); if (dp != NULL) { dp->con = typinf->con; dp->status = OCI_DPS_NOT_PREPARED; dp->typinf = typinf; dp->nb_rows = (ub2) nb_rows; dp->nb_cols = (ub2) nb_cols; dp->nb_cur = (ub2) dp->nb_rows; dp->err_col = 0; dp->err_row = 0; dp->nb_prcsd = 0; /* allocates direct context handle */ if (res == TRUE) { res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) dp->con->env, (dvoid **) (void *) &dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX, (size_t) 0, (dvoid **) NULL)); } /* set table name attribute */ if (res == TRUE) { osize = -1; ostr = OCI_GetInputMetaString(dp->typinf->name, &osize); OCI_CALL2 ( res, dp->con, OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_NAME, dp->con->err) ) OCI_ReleaseMetaString(ostr); } /* set schema name attribute */ if ((res == TRUE) && (dp->typinf->schema != NULL) && (dp->typinf->schema[0] != 0)) { osize = -1; ostr = OCI_GetInputMetaString(dp->typinf->schema, &osize); OCI_CALL2 ( res, dp->con, OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_SCHEMA_NAME, dp->con->err) ) OCI_ReleaseMetaString(ostr); } /* set partition name attribute */ if ((res == TRUE) && (partition != NULL) && (partition[0] != 0)) { osize = -1; ostr = OCI_GetInputMetaString(partition, &osize); OCI_CALL2 ( res, dp->con, OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_SUB_NAME, dp->con->err) ) OCI_ReleaseMetaString(ostr); } if (OCILib.version_runtime >= OCI_9_0) { ub4 num_rows = dp->nb_rows; /* set array size attribute */ OCI_CALL2 ( res, dp->con, OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX, (dvoid *) &num_rows, (ub4) sizeof(num_rows), (ub4) OCI_ATTR_NUM_ROWS, dp->con->err) ) }
boolean OCI_DefineAlloc ( OCI_Define *def ) { ub4 i; OCI_CALL_DECLARE_CONTEXT(TRUE) OCI_CHECK(NULL == def, FALSE) OCI_CALL_CONTEXT_SET_FROM_STMT(def->rs->stmt) /* Allocate indicators */ OCI_ALLOCATE_DATA(OCI_IPC_INDICATOR_ARRAY, def->buf.inds, def->buf.count); if (SQLT_NTY == def->col.sqlcode) { OCI_ALLOCATE_DATA(OCI_IPC_INDICATOR_ARRAY, def->buf.obj_inds, def->buf.count); } /* Allocate row data sizes array */ OCI_ALLOCATE_BUFFER(OCI_IPC_LEN_ARRAY, def->buf.lens, def->buf.sizelen, def->buf.count) /* initialize length array with buffer default size. But, Oracle uses different sizes for static fetch and callback fetch....*/ if (OCI_STATUS) { /* Allocate buffer array */ ub4 bufsize = (ub4)(OCI_CDT_LONG == def->col.datatype ? sizeof(OCI_Long *) : def->col.bufsize); OCI_ALLOCATE_BUFFER(OCI_IPC_BUFF_ARRAY, def->buf.data, bufsize, def->buf.count) /* Allocate buffer length array */ for (i = 0; i < def->buf.count; i++) { if (def->buf.sizelen == (int) sizeof(ub2)) { OCI_ARRAY_SET_AT(def->buf.lens, ub2, i, def->col.bufsize) } else if (def->buf.sizelen == (int) sizeof(ub4)) { OCI_ARRAY_SET_AT(def->buf.lens, ub4, i, def->col.bufsize) } } } /* Allocate descriptor for cursor, lob and file, interval and timestamp */ if (OCI_STATUS && OCI_UNKNOWN != def->col.handletype) { if (OCI_CDT_CURSOR == def->col.datatype) { for (i = 0; (i < def->buf.count) && OCI_STATUS; i++) { OCI_STATUS = OCI_HandleAlloc((dvoid *)def->rs->stmt->con->env, (dvoid **) &(def->buf.data[i]), (ub4) def->col.handletype); } } else { OCI_STATUS = OCI_DescriptorArrayAlloc((dvoid *)def->rs->stmt->con->env, (dvoid **)def->buf.data, (ub4)def->col.handletype, (ub4)def->buf.count); if (OCI_STATUS && (OCI_CDT_LOB == def->col.datatype)) { ub4 empty = 0; for (i = 0; (i < def->buf.count) && OCI_STATUS; i++) { OCI_SET_ATTRIB(def->col.handletype, OCI_ATTR_LOBEMPTY, def->buf.data[i], &empty, sizeof(empty)) } } } }
OCI_Pool * OCI_API OCI_PoolCreate ( const mtext *db, const mtext *user, const mtext *pwd, unsigned int type, unsigned int mode, unsigned int min_con, unsigned int max_con, unsigned int incr_con ) { OCI_Pool *pool = NULL; OCI_Item *item = NULL; boolean res = TRUE; OCI_CHECK_MIN(NULL, NULL, max_con, 1, NULL); /* let's be sure OCI_Initialize() has been called */ OCI_CHECK_INITIALIZED(NULL); /* make sure that we do not have a XA session flag */ mode &= ~OCI_SESSION_XA; /* create pool object */ item = OCI_ListAppend(OCILib.pools, sizeof(*pool)); if (item != NULL) { pool = (OCI_Pool *) item->data; /* create internal lists */ pool->cons = OCI_ListCreate(OCI_IPC_CONNECTION); if (OCI_LIB_THREADED) { /* create mutex for OCI_PoolGetConnection() */ pool->mutex = OCI_MutexCreateInternal(); res = (pool->mutex != NULL); } } else { res = FALSE; } /* set attributes */ if (res == TRUE) { pool->mode = mode; pool->min = min_con; pool->max = max_con; pool->incr = incr_con; pool->db = mtsdup(db != NULL ? db : MT("")); pool->user = mtsdup(user != NULL ? user : MT("")); pool->pwd = mtsdup(pwd != NULL ? pwd : MT("")); } #if OCI_VERSION_COMPILE < OCI_9_2 type = OCI_POOL_CONNECTION; #endif #if OCI_VERSION_COMPILE >= OCI_9_0 if (res == TRUE) { if (type == OCI_POOL_CONNECTION) { pool->htype = OCI_HTYPE_CPOOL; } #if OCI_VERSION_COMPILE >= OCI_9_2 else { pool->htype = OCI_HTYPE_SPOOL; } #endif } if (OCILib.version_runtime >= OCI_9_0) { int osize_name = -1; int osize_db = -1; void *ostr_name = NULL; void *ostr_db = NULL; /* allocate error handle */ if (res == TRUE) { res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, (dvoid **) (void *) &pool->err, (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) NULL)); } /* allocate pool handle */ if (res == TRUE) { res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, (dvoid **) (void *) &pool->handle, (ub4) pool->htype, (size_t) 0, (dvoid **) NULL)); } /* allocate authentification handle only if needed */ #if OCI_VERSION_COMPILE >= OCI_11_1 if (res == TRUE) { if ((pool->htype == OCI_HTYPE_SPOOL) && (OCILib.version_runtime >= OCI_11_1)) { int osize = -1; void *ostr = OCI_GetInputMetaString(OCILIB_DRIVER_NAME, &osize); /* allocate authentification handle */ res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, (dvoid **) (void *) &pool->authp, (ub4) OCI_HTYPE_AUTHINFO, (size_t) 0, (dvoid **) NULL)); /* set OCILIB's driver layer name attribute only for session pools here For standalone connections and connection pool this attribute is set in OCI_ConnectionLogon() */ OCI_CALL3 ( res, pool->err, OCIAttrSet((dvoid *) pool->authp, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_DRIVER_NAME, pool->err) ) OCI_ReleaseMetaString(ostr); /* set auth handle on the session pool */ OCI_CALL3 ( res, pool->err, OCIAttrSet((dvoid *) pool->handle, (ub4) OCI_HTYPE_SPOOL, (dvoid *) pool->authp, (ub4) sizeof(pool->authp), (ub4) OCI_ATTR_SPOOL_AUTH, pool->err) ) } }