OCILIB (C Driver for Oracle) 3.12.1
dequeue.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2013 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: dequeue.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                            PUBLIC FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_DequeueCreate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Dequeue * OCI_API OCI_DequeueCreate
00046 (
00047     OCI_TypeInfo *typinf,
00048     const mtext  *name
00049 )
00050 {
00051     OCI_Dequeue *dequeue = NULL;
00052     boolean res          = TRUE;
00053 
00054     OCI_CHECK_INITIALIZED(NULL);
00055 
00056     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00057     OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
00058 
00059     /* allocate dequeue structure */
00060 
00061     dequeue = (OCI_Dequeue *) OCI_MemAlloc(OCI_IPC_DEQUEUE, sizeof(*dequeue), (size_t) 1, TRUE);
00062 
00063     if (dequeue != NULL)
00064     {
00065         dequeue->typinf = typinf;
00066         dequeue->name   = mtsdup(name);
00067 
00068         /* allocate dequeue options descriptor */
00069 
00070         res = (OCI_SUCCESS == OCI_DescriptorAlloc((dvoid * ) dequeue->typinf->con->env,
00071                                                   (dvoid **) &dequeue->opth,
00072                                                   OCI_DTYPE_AQDEQ_OPTIONS,
00073                                                   (size_t) 0, (dvoid **) NULL));
00074 
00075         /* create local message for OCI_DequeueGet() */
00076 
00077         if (res == TRUE)
00078         {
00079             dequeue->msg = OCI_MsgCreate(dequeue->typinf);
00080         }
00081 
00082         res = (dequeue->msg != NULL);
00083     }
00084     else
00085     {
00086         res = FALSE;
00087     }
00088 
00089     /* check for failure */
00090 
00091     if (res == FALSE)
00092     {
00093         OCI_DequeueFree(dequeue);
00094         dequeue = NULL;
00095     }
00096 
00097     return dequeue;
00098 }
00099 
00100 /* --------------------------------------------------------------------------------------------- *
00101  * OCI_DequeueFree
00102  * --------------------------------------------------------------------------------------------- */
00103 
00104 boolean OCI_API OCI_DequeueFree
00105 (
00106     OCI_Dequeue *dequeue
00107 )
00108 {
00109     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00110 
00111     /* Unsubscribe notification if needed */
00112 
00113     if (dequeue->subhp != NULL)
00114     {
00115         OCI_DequeueUnsubscribe(dequeue);
00116     }
00117 
00118     /* free local message  */
00119 
00120     if (dequeue->msg != NULL)
00121     {
00122         OCI_MsgFree(dequeue->msg);
00123     }
00124 
00125     /* free local agent  */
00126 
00127     if (dequeue->agent != NULL)
00128     {
00129         OCI_AgentFree(dequeue->agent);
00130     }
00131 
00132     /* free OCI descriptor */
00133 
00134     OCI_DescriptorFree((dvoid *) dequeue->opth, OCI_DTYPE_AQDEQ_OPTIONS);
00135 
00136     /* free strings  */
00137 
00138     OCI_FREE(dequeue->name);
00139     OCI_FREE(dequeue->pattern);
00140     OCI_FREE(dequeue->consumer);
00141 
00142     /* free misc. */
00143 
00144     OCI_FREE(dequeue->agent_list);
00145 
00146     OCI_FREE(dequeue);
00147 
00148     return TRUE;
00149 }
00150 
00151 /* --------------------------------------------------------------------------------------------- *
00152  * OCI_DequeueListen
00153  * --------------------------------------------------------------------------------------------- */
00154 
00155 OCI_Agent * OCI_API OCI_DequeueListen
00156 (
00157     OCI_Dequeue *dequeue,
00158     int          timeout
00159 )
00160 {
00161     boolean res        = TRUE;
00162     OCI_Agent *agent   = NULL;
00163     OCIAQAgent *handle = NULL;
00164 
00165     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, NULL);
00166 
00167     /* listen only if OCI_DequeueSetAgentList has been called */
00168 
00169     if (dequeue->agent_list != NULL)
00170     {
00171         sword ret;
00172         sb4 code = OCI_SUCCESS;
00173 
00174         ret =  OCIAQListen(dequeue->typinf->con->cxt, dequeue->typinf->con->err,
00175                            dequeue->agent_list, (ub4) dequeue->agent_count,
00176                            (sb4) timeout, &handle, OCI_DEFAULT);
00177 
00178         /* check returned error code */
00179 
00180         if (ret == OCI_ERROR)
00181         {
00182             OCIErrorGet((dvoid *) dequeue->typinf->con->err, (ub4) 1,
00183                         (OraText *) NULL, &code, (OraText *) NULL, (ub4) 0,
00184                         (ub4) OCI_HTYPE_ERROR);
00185 
00186             /* raise error only if the call has not been timed out */
00187 
00188             if (code != OCI_ERR_AQ_LISTEN_TIMEOUT)
00189             {
00190                 OCI_ExceptionOCI(dequeue->typinf->con->err, dequeue->typinf->con, NULL, FALSE);
00191 
00192                 res = FALSE;
00193             }
00194         }
00195 
00196         /* init local agent object */
00197 
00198         if ((res == TRUE) && (ret == OCI_SUCCESS) && (handle != NULL))
00199         {
00200             agent = OCI_AgentInit(dequeue->typinf->con, &dequeue->agent, handle, NULL, NULL);
00201         }
00202     }
00203 
00204     OCI_RESULT(res);
00205 
00206     return agent;
00207 }
00208 
00209 /* --------------------------------------------------------------------------------------------- *
00210  * OCI_DequeueGet
00211  * --------------------------------------------------------------------------------------------- */
00212 
00213 OCI_Msg * OCI_API OCI_DequeueGet
00214 (
00215     OCI_Dequeue *dequeue
00216 )
00217 {
00218     boolean   res      = TRUE;
00219     sword     ret      = OCI_SUCCESS;
00220     OCI_Msg  *msg      = NULL;
00221     void     *p_ind    = NULL;
00222 
00223     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, NULL);
00224 
00225     /* reset message */
00226 
00227     res = OCI_MsgReset(dequeue->msg);
00228 
00229     if (res == TRUE)
00230     {
00231         void     *ostr     = NULL;
00232         int       osize    = -1;
00233 
00234         ostr  = OCI_GetInputMetaString(dequeue->name, &osize);
00235 
00236         if (dequeue->typinf->tcode == OCI_UNKNOWN)
00237         {
00238             p_ind = &dequeue->msg->ind;
00239         }
00240 
00241         /* dequeue message */
00242 
00243         ret = OCIAQDeq(dequeue->typinf->con->cxt, dequeue->typinf->con->err,
00244                        ostr, dequeue->opth, dequeue->msg->proph, dequeue->typinf->tdo,
00245                        &dequeue->msg->payload, (void **) &p_ind, &dequeue->msg->id, OCI_DEFAULT);
00246 
00247         OCI_ReleaseMetaString(ostr);
00248 
00249         /* check returned error code */
00250 
00251         if (ret == OCI_ERROR)
00252         {
00253             sb4 code = 0;
00254 
00255             OCIErrorGet((dvoid *) dequeue->typinf->con->err, (ub4) 1,
00256                         (OraText *) NULL, &code, (OraText *) NULL, (ub4) 0,
00257                         (ub4) OCI_HTYPE_ERROR);
00258 
00259             /* raise error only if the call has not been timed out */
00260 
00261             if (code != OCI_ERR_AQ_DEQUEUE_TIMEOUT)
00262             {
00263                 OCI_ExceptionOCI(dequeue->typinf->con->err, dequeue->typinf->con, NULL, FALSE);
00264 
00265                 res = FALSE;
00266             }
00267         }
00268     }
00269 
00270     /* reset message */
00271 
00272     if ((res == TRUE) && (ret == OCI_SUCCESS))
00273     {
00274         /* get payload */
00275 
00276         if (dequeue->typinf->tcode != OCI_UNKNOWN)
00277         {
00278             if ((p_ind != NULL) && ((*(OCIInd *) p_ind) != OCI_IND_NULL))
00279             {
00280                 dequeue->msg->ind = *(OCIInd *) p_ind;
00281 
00282                 dequeue->msg->obj = OCI_ObjectInit(dequeue->typinf->con,
00283                                                    (OCI_Object **) &dequeue->msg->obj,
00284                                                    dequeue->msg->payload, dequeue->typinf,
00285                                                    NULL, -1, TRUE);
00286 
00287                 res = dequeue->msg->obj != NULL;
00288             }
00289         }
00290     }
00291 
00292     /* on success return internla message handle */
00293 
00294     if ((res == TRUE) && (ret == OCI_SUCCESS))
00295     {
00296         msg = dequeue->msg;
00297     }
00298 
00299     OCI_RESULT(res);
00300 
00301     return msg;
00302 }
00303 
00304 /* --------------------------------------------------------------------------------------------- *
00305  * OCI_DequeueGetConsumerName
00306  * --------------------------------------------------------------------------------------------- */
00307 
00308 const mtext * OCI_API OCI_DequeueGetConsumer
00309 (
00310     OCI_Dequeue *dequeue
00311 )
00312 {
00313     boolean res = TRUE;
00314 
00315     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, NULL);
00316 
00317     if (dequeue->consumer == NULL)
00318     {
00319         res = OCI_StringGetFromAttrHandle(dequeue->typinf->con,
00320                                           dequeue->opth,
00321                                           OCI_DTYPE_AQDEQ_OPTIONS,
00322                                           OCI_ATTR_CONSUMER_NAME,
00323                                           &dequeue->consumer);
00324     }
00325 
00326     OCI_RESULT(res);
00327 
00328     return dequeue->consumer;
00329 }
00330 
00331 /* --------------------------------------------------------------------------------------------- *
00332  * OCI_DequeueSetConsumerName
00333  * --------------------------------------------------------------------------------------------- */
00334 
00335 boolean OCI_API OCI_DequeueSetConsumer
00336 (
00337     OCI_Dequeue *dequeue,
00338     const mtext *consumer
00339 )
00340 {
00341     boolean res = TRUE;
00342 
00343     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00344 
00345     res =  OCI_StringSetToAttrHandle(dequeue->typinf->con,
00346                                      dequeue->opth,
00347                                      OCI_DTYPE_AQDEQ_OPTIONS,
00348                                      OCI_ATTR_CONSUMER_NAME,
00349                                      &dequeue->consumer,
00350                                      consumer);
00351 
00352     OCI_RESULT(res);
00353 
00354     return res;
00355 }
00356 
00357 /* --------------------------------------------------------------------------------------------- *
00358  * OCI_DequeueGetCorrelation
00359  * --------------------------------------------------------------------------------------------- */
00360 
00361 const mtext * OCI_API OCI_DequeueGetCorrelation
00362 (
00363     OCI_Dequeue *dequeue
00364 )
00365 {
00366     boolean res = TRUE;
00367 
00368     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, NULL);
00369 
00370     if (dequeue->pattern == NULL)
00371     {
00372         res = OCI_StringGetFromAttrHandle(dequeue->typinf->con,
00373                                           dequeue->opth,
00374                                           OCI_DTYPE_AQDEQ_OPTIONS,
00375                                           OCI_ATTR_CORRELATION,
00376                                           &dequeue->pattern);
00377     }
00378 
00379     OCI_RESULT(res);
00380 
00381     return dequeue->pattern;
00382 }
00383 
00384 /* --------------------------------------------------------------------------------------------- *
00385  * OCI_DequeueSetCorrelation
00386  * --------------------------------------------------------------------------------------------- */
00387 
00388 boolean OCI_API OCI_DequeueSetCorrelation
00389 (
00390     OCI_Dequeue *dequeue,
00391     const mtext *pattern
00392 )
00393 {
00394     boolean res = TRUE;
00395 
00396     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00397 
00398     res =  OCI_StringSetToAttrHandle(dequeue->typinf->con,
00399                                      dequeue->opth,
00400                                      OCI_DTYPE_AQDEQ_OPTIONS,
00401                                      OCI_ATTR_CORRELATION,
00402                                      &dequeue->pattern,
00403                                      pattern);
00404 
00405     OCI_RESULT(res);
00406 
00407     return res;
00408 }
00409 
00410 /* --------------------------------------------------------------------------------------------- *
00411  * OCI_DequeueGetRelativeMsgID
00412  * --------------------------------------------------------------------------------------------- */
00413 
00414 boolean OCI_API OCI_DequeueGetRelativeMsgID
00415 (
00416     OCI_Dequeue  *dequeue,
00417     void         *id,
00418     unsigned int *len
00419 )
00420 {
00421     boolean res   = TRUE;
00422     OCIRaw *value = NULL;
00423 
00424     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00425     OCI_CHECK_PTR(OCI_IPC_VOID,    id,      FALSE);
00426     OCI_CHECK_PTR(OCI_IPC_VOID,    len,     FALSE);
00427 
00428     OCI_CALL2
00429     (
00430         res, dequeue->typinf->con,
00431 
00432         OCIAttrGet((dvoid *) dequeue->opth,
00433                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00434                    (dvoid *) &value,
00435                    (ub4   *) NULL,
00436                    (ub4    ) OCI_ATTR_DEQ_MSGID,
00437                    dequeue->typinf->con->err)
00438     )
00439 
00440     if (value != NULL)
00441     {
00442         ub4 raw_len = OCIRawSize(dequeue->typinf->con->env, value);
00443 
00444         if (*len > raw_len)
00445             *len = raw_len;
00446 
00447         memcpy(id, OCIRawPtr(dequeue->typinf->con->env, value), (size_t) (*len));
00448     }
00449     else
00450     {
00451         *len = 0;
00452     }
00453 
00454     OCI_RESULT(res);
00455 
00456     return res;
00457 }
00458 
00459 /* --------------------------------------------------------------------------------------------- *
00460  * OCI_DequeueSetRelativeMsgID
00461  * --------------------------------------------------------------------------------------------- */
00462 
00463 boolean OCI_API OCI_DequeueSetRelativeMsgID
00464 (
00465     OCI_Dequeue  *dequeue,
00466     const void   *id,
00467     unsigned int  len
00468 )
00469 {
00470     boolean res   = TRUE;
00471     OCIRaw *value = NULL;
00472 
00473     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00474 
00475     OCI_CALL2
00476     (
00477         res, dequeue->typinf->con,
00478 
00479         OCIRawAssignBytes(dequeue->typinf->con->env, dequeue->typinf->con->err,
00480                           (ub1*) id, (ub4) len, (OCIRaw **) &value)
00481     )
00482 
00483     OCI_CALL2
00484     (
00485         res, dequeue->typinf->con,
00486 
00487         OCIAttrSet((dvoid *) dequeue->opth,
00488                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00489                    (dvoid *) &value,
00490                    (ub4    ) 0,
00491                    (ub4    ) OCI_ATTR_DEQ_MSGID,
00492                    dequeue->typinf->con->err)
00493     )
00494 
00495     OCI_RESULT(res);
00496 
00497     return res;
00498 }
00499 
00500 /* --------------------------------------------------------------------------------------------- *
00501  * OCI_DequeueGetVisibility
00502  * --------------------------------------------------------------------------------------------- */
00503 
00504 unsigned int OCI_API OCI_DequeueGetVisibility
00505 (
00506     OCI_Dequeue *dequeue
00507 )
00508 {
00509     boolean res = TRUE;
00510     ub4 ret     = 0;
00511 
00512     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, 0);
00513 
00514     OCI_CALL2
00515     (
00516         res, dequeue->typinf->con,
00517 
00518         OCIAttrGet((dvoid *) dequeue->opth,
00519                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00520                    (dvoid *) &ret,
00521                    (ub4   *) NULL,
00522                    (ub4    ) OCI_ATTR_VISIBILITY,
00523                    dequeue->typinf->con->err)
00524     )
00525 
00526     OCI_RESULT(res);
00527 
00528     return (int) ret;
00529 }
00530 
00531 /* --------------------------------------------------------------------------------------------- *
00532  * OCI_DequeueSetVisibility
00533  * --------------------------------------------------------------------------------------------- */
00534 
00535 boolean OCI_API OCI_DequeueSetVisibility
00536 (
00537     OCI_Dequeue *dequeue,
00538     unsigned int visibility
00539 )
00540 {
00541     boolean res = TRUE;
00542     ub4 value   = (ub4) visibility;
00543 
00544     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00545 
00546     OCI_CALL2
00547     (
00548         res, dequeue->typinf->con,
00549 
00550         OCIAttrSet((dvoid *) dequeue->opth,
00551                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00552                    (dvoid *) &value,
00553                    (ub4    ) 0,
00554                    (ub4    ) OCI_ATTR_VISIBILITY,
00555                    dequeue->typinf->con->err)
00556     )
00557 
00558     OCI_RESULT(res);
00559 
00560     return res;
00561 }
00562 
00563 /* --------------------------------------------------------------------------------------------- *
00564  * OCI_DequeueGetMode
00565  * --------------------------------------------------------------------------------------------- */
00566 
00567 unsigned int OCI_API OCI_DequeueGetMode
00568 (
00569     OCI_Dequeue *dequeue
00570 )
00571 {
00572     boolean res = TRUE;
00573     ub4 ret     = 0;
00574 
00575     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, 0);
00576 
00577     OCI_CALL2
00578     (
00579         res, dequeue->typinf->con,
00580 
00581         OCIAttrGet((dvoid *) dequeue->opth,
00582                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00583                    (dvoid *) &ret,
00584                    (ub4   *) NULL,
00585                    (ub4    ) OCI_ATTR_DEQ_MODE,
00586                    dequeue->typinf->con->err)
00587     )
00588 
00589     OCI_RESULT(res);
00590 
00591     return (int) ret;
00592 }
00593 
00594 /* --------------------------------------------------------------------------------------------- *
00595  * OCI_DequeueSetMode
00596  * --------------------------------------------------------------------------------------------- */
00597 
00598 boolean OCI_API OCI_DequeueSetMode
00599 (
00600     OCI_Dequeue *dequeue,
00601     unsigned int mode
00602 )
00603 {
00604     boolean res = TRUE;
00605     ub4 value   = (ub4) mode;
00606 
00607     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00608 
00609     OCI_CALL2
00610     (
00611         res, dequeue->typinf->con,
00612 
00613         OCIAttrSet((dvoid *) dequeue->opth,
00614                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00615                    (dvoid *) &value,
00616                    (ub4    ) 0,
00617                    (ub4    ) OCI_ATTR_DEQ_MODE,
00618                    dequeue->typinf->con->err)
00619     )
00620 
00621     OCI_RESULT(res);
00622 
00623     return res;
00624 }
00625 
00626 /* --------------------------------------------------------------------------------------------- *
00627  * OCI_DequeueGetNavigation
00628  * --------------------------------------------------------------------------------------------- */
00629 
00630 unsigned int OCI_API OCI_DequeueGetNavigation
00631 (
00632     OCI_Dequeue *dequeue
00633 )
00634 {
00635     boolean res = TRUE;
00636     ub4 ret     = 0;
00637 
00638     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, 0);
00639 
00640     OCI_CALL2
00641     (
00642         res, dequeue->typinf->con,
00643 
00644         OCIAttrGet((dvoid *) dequeue->opth,
00645                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00646                    (dvoid *) &ret,
00647                    (ub4   *) NULL,
00648                    (ub4    ) OCI_ATTR_NAVIGATION,
00649                    dequeue->typinf->con->err)
00650     )
00651 
00652     OCI_RESULT(res);
00653 
00654     return (int) ret;
00655 }
00656 
00657 /* --------------------------------------------------------------------------------------------- *
00658  * OCI_DequeueSetNavigation
00659  * --------------------------------------------------------------------------------------------- */
00660 
00661 boolean OCI_API OCI_DequeueSetNavigation
00662 (
00663     OCI_Dequeue *dequeue,
00664     unsigned int position
00665 )
00666 {
00667     boolean res = TRUE;
00668     ub4 value   = (ub4) position;
00669 
00670     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00671 
00672     OCI_CALL2
00673     (
00674         res, dequeue->typinf->con,
00675 
00676         OCIAttrSet((dvoid *) dequeue->opth,
00677                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00678                    (dvoid *) &value,
00679                    (ub4    ) 0,
00680                    (ub4    ) OCI_ATTR_NAVIGATION,
00681                    dequeue->typinf->con->err)
00682     )
00683 
00684     OCI_RESULT(res);
00685 
00686     return res;
00687 }
00688 
00689 /* --------------------------------------------------------------------------------------------- *
00690  * OCI_DequeueGetWaitTime
00691  * --------------------------------------------------------------------------------------------- */
00692 
00693 int OCI_API OCI_DequeueGetWaitTime
00694 (
00695     OCI_Dequeue *dequeue
00696 )
00697 {
00698     boolean res = TRUE;
00699     sb4 ret     = 0;
00700 
00701     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, 0);
00702 
00703     OCI_CALL2
00704     (
00705         res, dequeue->typinf->con,
00706 
00707         OCIAttrGet((dvoid *) dequeue->opth,
00708                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00709                    (dvoid *) &ret,
00710                    (ub4   *) NULL,
00711                    (ub4    )  OCI_ATTR_WAIT,
00712                    dequeue->typinf->con->err)
00713     )
00714 
00715     OCI_RESULT(res);
00716 
00717     return (int) ret;
00718 }
00719 
00720 /* --------------------------------------------------------------------------------------------- *
00721  * OCI_DequeueSetWaitTime
00722  * --------------------------------------------------------------------------------------------- */
00723 
00724 boolean OCI_API OCI_DequeueSetWaitTime
00725 (
00726     OCI_Dequeue *dequeue,
00727     int          timeout
00728 )
00729 {
00730     boolean res = TRUE;
00731     sb4 value   = (ub4) timeout;
00732 
00733     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00734 
00735     OCI_CALL2
00736     (
00737         res, dequeue->typinf->con,
00738 
00739         OCIAttrSet((dvoid *) dequeue->opth,
00740                    (ub4    ) OCI_DTYPE_AQDEQ_OPTIONS,
00741                    (dvoid *) &value,
00742                    (ub4    ) 0,
00743                    (ub4    )  OCI_ATTR_WAIT,
00744                    dequeue->typinf->con->err)
00745     )
00746 
00747     OCI_RESULT(res);
00748 
00749     return res;
00750 }
00751 
00752 /* --------------------------------------------------------------------------------------------- *
00753  * OCI_DequeueSetAgentList
00754  * --------------------------------------------------------------------------------------------- */
00755 
00756 boolean OCI_API OCI_DequeueSetAgentList
00757 (
00758     OCI_Dequeue *dequeue,
00759     OCI_Agent  **consumers,
00760     unsigned int count
00761 )
00762 {
00763     boolean res = TRUE;
00764 
00765     OCI_CHECK_PTR(OCI_IPC_ENQUEUE, dequeue, FALSE);
00766 
00767     OCI_FREE(dequeue->agent_list);
00768 
00769     if ((consumers != NULL) && (count > 0))
00770     {
00771         dequeue->agent_list = (OCIAQAgent **) OCI_MemAlloc(OCI_IPC_ARRAY,  sizeof(OCIAQAgent *),
00772                                                            count, FALSE);
00773 
00774         if (dequeue->agent_list != NULL)
00775         {
00776             unsigned int i;
00777 
00778             for(i = 0; i < count; i++)
00779             {
00780                 dequeue->agent_list[i] = consumers[i]->handle;
00781             }
00782 
00783             dequeue->agent_count = (ub4) count;
00784         }
00785         else
00786         {
00787             res = FALSE;
00788         }
00789     }
00790 
00791     OCI_RESULT(res);
00792 
00793     return res;
00794 }
00795 
00796 /* --------------------------------------------------------------------------------------------- *
00797  * OCI_DequeueSubscribe
00798  * --------------------------------------------------------------------------------------------- */
00799 
00800 OCI_EXPORT boolean OCI_API  OCI_DequeueSubscribe
00801 (
00802     OCI_Dequeue    *dequeue, 
00803     unsigned int    port, 
00804     unsigned int    timeout,
00805     POCI_NOTIFY_AQ  callback
00806 )
00807 {
00808     boolean res             = TRUE;
00809     ub4     oci_namespace   = OCI_SUBSCR_NAMESPACE_AQ;
00810 
00811 #if OCI_VERSION_COMPILE >= OCI_10_2
00812 
00813     ub4     oci_port        = (ub4) port;
00814     ub4     oci_timeout     = (ub4) timeout;
00815     ub4     oci_protocol    = OCI_SUBSCR_PROTO_OCI;
00816     ub4     oci_msgpres     = OCI_SUBSCR_PRES_DEFAULT;
00817 
00818 #endif
00819 
00820     OCI_Connection *con = NULL;
00821      
00822     OCI_CHECK_INITIALIZED(FALSE);
00823     OCI_CHECK_DATABASE_NOTIFY_ENABLED(FALSE);
00824 
00825     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
00826 
00827     con = dequeue->typinf->con;
00828 
00829     /* clear any previous subscription */
00830 
00831     OCI_DequeueUnsubscribe(dequeue);
00832 
00833     /* allocate subcription handle */
00834 
00835     res = (OCI_SUCCESS == OCI_HandleAlloc(con->env,
00836                                           (dvoid **) (void *) &dequeue->subhp,
00837                                           OCI_HTYPE_SUBSCRIPTION, (size_t) 0,
00838                                           (dvoid **) NULL));
00839 
00840 #if OCI_VERSION_COMPILE >= OCI_10_2
00841 
00842     /* set port number */
00843 
00844     if (oci_port > 0)
00845     {
00846         OCI_CALL3
00847         (
00848             res, con->err,
00849 
00850             OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00851                         (dvoid *) &oci_port, (ub4) sizeof (oci_port),
00852                         (ub4) OCI_ATTR_SUBSCR_PORTNO, con->err)
00853         )
00854     }
00855 
00856     /* set timeout */
00857 
00858     if (oci_timeout > 0)
00859     {
00860         OCI_CALL3
00861         (
00862             res, con->err,
00863 
00864             OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00865                         (dvoid *) &oci_timeout, (ub4) sizeof (oci_timeout),
00866                         (ub4) OCI_ATTR_SUBSCR_TIMEOUT, con->err)
00867         )
00868     }
00869 
00870     /* set protocol  */
00871 
00872     OCI_CALL3
00873     (
00874         res, con->err,
00875 
00876         OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00877                     (dvoid *) &oci_protocol, (ub4) sizeof(oci_protocol),
00878                     (ub4) OCI_ATTR_SUBSCR_RECPTPROTO, con->err)
00879     )
00880 
00881     /* set presentation  */
00882 
00883     OCI_CALL3
00884     (
00885         res, con->err,
00886 
00887         OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00888                     (dvoid *) &oci_msgpres, (ub4) sizeof(oci_msgpres),
00889                     (ub4) OCI_ATTR_SUBSCR_RECPTPRES, con->err)
00890     )
00891 
00892 #else
00893 
00894     OCI_NOT_USED(port);
00895     OCI_NOT_USED(timeout);
00896 
00897 #endif
00898     
00899     /* set name  */
00900 
00901     if (dequeue->name != NULL)
00902     {
00903         /* for AQ subscription, the name should be "[shema.]queue[:consumer]" */
00904 
00905         mtext buffer[(OCI_SIZE_OBJ_NAME*2) + 2] = MT("");
00906 
00907         mtext *str  = NULL;
00908         size_t size = sizeof(buffer)/sizeof(mtext);
00909 
00910         void *ostr  = NULL;
00911         int osize   = -1;
00912             
00913         mtsncat(buffer, dequeue->name, size);
00914 
00915         if (dequeue->consumer != NULL)
00916         {
00917             size -= mtslen(dequeue->name);
00918             mtsncat(buffer, MT(":"), size);
00919             size -= (size_t) 1;
00920 
00921             mtsncat(buffer, dequeue->consumer, size);
00922         }           
00923 
00924         /* queue name must be uppercase */
00925 
00926         for (str =  buffer; *str != 0; str++)
00927         {
00928             *str = (mtext) mttoupper(*str);
00929         }
00930 
00931         ostr = OCI_GetInputMetaString(buffer, &osize);
00932 
00933         OCI_CALL3
00934         (
00935             res, con->err,
00936 
00937             OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00938                         (dvoid *) ostr, (ub4) osize,
00939                         (ub4) OCI_ATTR_SUBSCR_NAME, con->err)
00940         )
00941 
00942         OCI_ReleaseMetaString(ostr);
00943     }
00944 
00945     /* set namespace  */
00946 
00947     OCI_CALL3
00948     (
00949         res, con->err,
00950 
00951         OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00952                     (dvoid *) &oci_namespace, (ub4) sizeof(oci_namespace),
00953                     (ub4) OCI_ATTR_SUBSCR_NAMESPACE, con->err)
00954     )
00955 
00956     /* set context pointer to dequeue structure */
00957 
00958     OCI_CALL3
00959     (
00960         res, con->err,
00961 
00962         OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00963                     (dvoid *) dequeue, (ub4) 0,
00964                     (ub4) OCI_ATTR_SUBSCR_CTX, con->err)
00965     )
00966     
00967     /* internal callback handler */
00968 
00969     OCI_CALL3
00970     (
00971         res, con->err,
00972 
00973         OCIAttrSet((dvoid *) dequeue->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00974                     (dvoid *) OCI_ProcNotifyMessages, (ub4) 0,
00975                     (ub4) OCI_ATTR_SUBSCR_CALLBACK, con->err)
00976     )
00977 
00978     /* set callback */
00979 
00980     dequeue->callback = callback;
00981 
00982     /* all attributes set, let's register the subscription ! */
00983 
00984     OCI_CALL3
00985     (
00986         res, con->err,
00987 
00988         OCISubscriptionRegister(con->cxt, &dequeue->subhp, (ub2) 1, con->err,(ub4) OCI_DEFAULT)
00989     )
00990 
00991     if (res == FALSE)
00992     {
00993         /* clear subscription on failure */
00994 
00995         OCI_DequeueUnsubscribe(dequeue);
00996     }
00997 
00998     OCI_RESULT(res);
00999 
01000     return res;
01001 }
01002 
01003 /* --------------------------------------------------------------------------------------------- *
01004  * OCI_DequeueUnsubscribe
01005  * --------------------------------------------------------------------------------------------- */
01006 
01007 OCI_EXPORT boolean OCI_API OCI_DequeueUnsubscribe
01008 (
01009     OCI_Dequeue *dequeue
01010 )
01011 {
01012     boolean res = TRUE;
01013  
01014     OCI_CHECK_DATABASE_NOTIFY_ENABLED(FALSE);
01015 
01016     OCI_CHECK_PTR(OCI_IPC_DEQUEUE, dequeue, FALSE);
01017 
01018     dequeue->callback = NULL;
01019     
01020     if (dequeue->subhp != NULL)
01021     {
01022         /* unregister the subscription */
01023 
01024         OCI_CALL3
01025         (
01026             res, dequeue->typinf->con->err,
01027 
01028             OCISubscriptionUnRegister(dequeue->typinf->con->cxt, dequeue->subhp,
01029                                       dequeue->typinf->con->err,(ub4) OCI_DEFAULT)
01030         )
01031 
01032         /* free OCI handle */
01033 
01034         OCI_HandleFree((dvoid *) dequeue->subhp, OCI_HTYPE_SUBSCRIPTION);
01035 
01036         dequeue->subhp = NULL;
01037     }
01038 
01039     OCI_RESULT(res);
01040 
01041     return res;
01042 }