boolean OCI_API OCI_DequeueFree ( OCI_Dequeue *dequeue ) { OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE); /* Unsubscribe notification if needed */ if (dequeue->subhp != NULL) { OCI_DequeueUnsubscribe(dequeue); } /* free local message */ if (dequeue->msg != NULL) { OCI_MsgFree(dequeue->msg); } /* free local agent */ if (dequeue->agent != NULL) { OCI_AgentFree(dequeue->agent); } /* free OCI descriptor */ OCI_DescriptorFree((dvoid *) dequeue->opth, OCI_DTYPE_AQDEQ_OPTIONS); /* free strings */ OCI_FREE(dequeue->name); OCI_FREE(dequeue->pattern); OCI_FREE(dequeue->consumer); /* free misc. */ OCI_FREE(dequeue->agent_list); OCI_FREE(dequeue); return TRUE; }
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; }
int main(int argc, char *argv[]) { OCI_Connection *con; OCI_Enqueue *enq; OCI_Dequeue *deq1; OCI_Dequeue *deq2; OCI_Msg *msg; OCI_TypeInfo *inf; OCI_Object *obj; OCI_Agent *agents[2]; OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT | OCI_ENV_THREADED |OCI_ENV_EVENTS); con = OCI_ConnectionCreate("db", "usr", "pwd", OCI_SESSION_DEFAULT); OCI_Immediate(con, "create type my_message as object (title varchar2(50), content varchar2(50)) "); OCI_QueueTableCreate(con, "my_queue_table", "my_message", NULL, NULL, TRUE, FALSE, NULL, 0,0,NULL); OCI_QueueCreate(con, "my_queue", "my_queue_table", OCIT_NORMAL, 0, 0, 0, 0, NULL); OCI_QueueStart(con, "my_queue", TRUE, TRUE); agents[0] = OCI_AgentCreate(con, "C1", NULL); agents[1] = OCI_AgentCreate(con, "C2", NULL); inf = OCI_TypeInfoGet(con, "MY_MESSAGE", OCI_TIF_TYPE); enq = OCI_EnqueueCreate(inf, "my_queue"); deq1 = OCI_DequeueCreate(inf, "my_queue"); deq2 = OCI_DequeueCreate(inf, "my_queue"); OCI_DequeueSetConsumer(deq1, "C1"); OCI_DequeueSetNavigation(deq1, OCI_ADN_FIRST_MSG); OCI_DequeueSetConsumer(deq2, "C2"); OCI_DequeueSetNavigation(deq2, OCI_ADN_FIRST_MSG); OCI_DequeueSubscribe(deq1, 9998, 0, on_message); OCI_DequeueSubscribe(deq2, 9999, 0, on_message); msg = OCI_MsgCreate(inf); obj = OCI_ObjectCreate(con, inf); OCI_ObjectSetString(obj, "TITLE", "NEXT MEETING"); OCI_ObjectSetString(obj, "CONTENT", "12:00 PM IN STARBUCKS"); OCI_MsgSetObject(msg, obj); OCI_MsgSetConsumers(msg, agents, 2); OCI_EnqueuePut(enq, msg); OCI_MsgFree(msg); OCI_ObjectFree(obj); OCI_Commit(con); getchar(); OCI_DequeueUnsubscribe(deq1); OCI_DequeueUnsubscribe(deq2); OCI_AgentFree(agents[0]); OCI_AgentFree(agents[1]); OCI_EnqueueFree(enq); OCI_DequeueFree(deq1); OCI_DequeueFree(deq2); OCI_QueueStop(con, "my_queue", TRUE, TRUE, 0); OCI_QueueDrop(con, "my_queue"); OCI_QueueTableDrop(con, "my_queue_table", TRUE); OCI_Immediate(con, "drop type my_message"); OCI_ConnectionFree(con); OCI_Cleanup(); return EXIT_SUCCESS; }