boolean OCI_SubscriptionClose ( OCI_Subscription *sub ) { boolean res = TRUE; OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, FALSE); #if OCI_VERSION_COMPILE >= OCI_10_2 /* deregister the subscription if connection still alive */ if (sub->subhp != NULL) { OCI_Connection * con = NULL; if (sub->con == NULL) { con = OCI_ConnectionCreate(sub->saved_db, sub->saved_user, sub->saved_pwd, OCI_SESSION_DEFAULT); sub->con = con; } if (sub->con != NULL) { OCI_CALL3 ( res, sub->err, OCISubscriptionUnRegister(sub->con->cxt, sub->subhp, sub->err,(ub4) OCI_DEFAULT) ) } if (con != NULL) { OCI_ConnectionFree(con); } }
OCI_EXPORT boolean OCI_API OCI_DequeueUnsubscribe ( OCI_Dequeue *dequeue ) { boolean res = TRUE; OCI_CHECK_DATABASE_NOTIFY_ENABLED(FALSE); OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE); dequeue->callback = NULL; if (dequeue->subhp != NULL) { /* unregister the subscription */ OCI_CALL3 ( res, dequeue->typinf->con->err, OCISubscriptionUnRegister(dequeue->typinf->con->cxt, dequeue->subhp, dequeue->typinf->con->err,(ub4) OCI_DEFAULT) ) /* free OCI handle */ OCI_HandleFree((dvoid *) dequeue->subhp, OCI_HTYPE_SUBSCRIPTION); dequeue->subhp = NULL; } OCI_RESULT(res); return res; }
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_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) ) } }