OCILIB (C Driver for Oracle) 3.12.1
|
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 }