00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "ocilib_internal.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 boolean OCI_SubscriptionClose
00046 (
00047 OCI_Subscription *sub
00048 )
00049 {
00050 boolean res = TRUE;
00051
00052 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, FALSE);
00053
00054 #if OCI_VERSION_COMPILE >= OCI_10_2
00055
00056
00057
00058 if (sub->subhp != NULL)
00059 {
00060 OCI_Connection * con = NULL;
00061
00062 if (sub->con == NULL)
00063 {
00064 con = OCI_ConnectionCreate(sub->saved_db, sub->saved_user,
00065 sub->saved_pwd, OCI_SESSION_DEFAULT);
00066
00067 sub->con = con;
00068 }
00069
00070 if (sub->con != NULL)
00071 {
00072 OCI_CALL3
00073 (
00074 res, sub->err,
00075
00076 OCISubscriptionUnRegister(sub->con->cxt, sub->subhp,
00077 sub->err,(ub4) OCI_DEFAULT)
00078 )
00079 }
00080
00081 if (con != NULL)
00082 {
00083 OCI_ConnectionFree(con);
00084 }
00085 }
00086
00087
00088
00089 OCI_HandleFree((dvoid *) sub->subhp, OCI_HTYPE_SUBSCRIPTION);
00090
00091
00092
00093 if (sub->err != NULL)
00094 {
00095 OCI_HandleFree(sub->err, OCI_HTYPE_ERROR);
00096 }
00097
00098 #endif
00099
00100
00101
00102 OCI_FREE(sub->event.dbname);
00103 OCI_FREE(sub->event.objname);
00104 OCI_FREE(sub->event.rowid);
00105
00106
00107
00108 OCI_FREE(sub->saved_db);
00109 OCI_FREE(sub->saved_user);
00110 OCI_FREE(sub->saved_pwd);
00111 OCI_FREE(sub->name);
00112
00113 return res;
00114 }
00115
00116
00117
00118
00119
00120 boolean OCI_SubscriptionDetachConnection
00121 (
00122 OCI_Connection *con
00123 )
00124 {
00125 OCI_List *list = OCILib.subs;
00126 OCI_Item *item = NULL;
00127
00128 OCI_CHECK(list == NULL, FALSE);
00129
00130 if (list->mutex != NULL)
00131 OCI_MutexAcquire(list->mutex);
00132
00133 item = list->head;
00134
00135
00136
00137 while (item != NULL)
00138 {
00139 OCI_Subscription * sub = (OCI_Subscription *) item->data;
00140
00141 if ((sub != NULL) && (sub->con == con))
00142 {
00143 sub->con = NULL;
00144
00145 sub->saved_db = mtsdup(con->db);
00146 sub->saved_user = mtsdup(con->user);
00147 sub->saved_pwd = mtsdup(con->pwd);
00148 }
00149
00150 item = item->next;
00151 }
00152
00153 if (list->mutex != NULL)
00154 OCI_MutexRelease(list->mutex);
00155
00156 return TRUE;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 OCI_Subscription * OCI_API OCI_SubscriptionRegister
00168 (
00169 OCI_Connection *con,
00170 const mtext *name,
00171 unsigned int type,
00172 POCI_NOTIFY handler,
00173 unsigned int port,
00174 unsigned int timeout
00175 )
00176 {
00177 OCI_Subscription *sub = NULL;
00178 OCI_Item *item = NULL;
00179 boolean res = TRUE;
00180
00181 OCI_CHECK_INITIALIZED(NULL);
00182 OCI_CHECK_DATABASE_NOTIFY_ENABLED(NULL);
00183
00184 OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00185 OCI_CHECK_PTR(OCI_IPC_PROC, handler, NULL);
00186 OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
00187
00188 #if OCI_VERSION_COMPILE >= OCI_10_2
00189
00190
00191
00192 item = OCI_ListAppend(OCILib.subs, sizeof(*sub));
00193
00194 if (item != NULL)
00195 {
00196 sub = (OCI_Subscription *) item->data;
00197
00198
00199
00200 res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env,
00201 (dvoid **) (void *) &sub->err,
00202 OCI_HTYPE_ERROR, (size_t) 0,
00203 (dvoid **) NULL));
00204
00205
00206
00207 res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env,
00208 (dvoid **) (void *) &sub->subhp,
00209 OCI_HTYPE_SUBSCRIPTION, (size_t) 0,
00210 (dvoid **) NULL));
00211
00212 if (res == TRUE)
00213 {
00214 ub4 attr = 0;
00215 int osize = -1;
00216 void *ostr = NULL;
00217
00218 sub->con = con;
00219 sub->port = (ub4) port;
00220 sub->timeout = (ub4) timeout;
00221 sub->handler = handler;
00222 sub->type = type;
00223 sub->name = mtsdup(name);
00224 sub->event.sub = sub;
00225
00226
00227
00228 if (sub->port > 0)
00229 {
00230 OCI_CALL3
00231 (
00232 res, sub->err,
00233
00234 OCIAttrSet((dvoid *) OCILib.env, (ub4) OCI_HTYPE_ENV,
00235 (dvoid *) &sub->port, (ub4) sizeof (sub->port),
00236 (ub4) OCI_ATTR_SUBSCR_PORTNO, sub->err)
00237 )
00238 }
00239 else
00240 {
00241 OCI_CALL3
00242 (
00243 res, sub->err,
00244
00245 OCIAttrGet((dvoid *) OCILib.env, (ub4) OCI_HTYPE_ENV,
00246 (dvoid *) &sub->port, (ub4) 0,
00247 (ub4) OCI_ATTR_SUBSCR_PORTNO, sub->err)
00248 )
00249 }
00250
00251
00252
00253 if(sub->timeout > 0)
00254 {
00255 OCI_CALL3
00256 (
00257 res, sub->err,
00258
00259 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00260 (dvoid *) &sub->timeout, (ub4) sizeof (sub->timeout),
00261 (ub4) OCI_ATTR_SUBSCR_TIMEOUT, sub->err)
00262 )
00263 }
00264
00265
00266
00267 ostr = OCI_GetInputMetaString(sub->name, &osize);
00268
00269 OCI_CALL3
00270 (
00271 res, sub->err,
00272
00273 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00274 (dvoid *) ostr, (ub4) osize,
00275 (ub4) OCI_ATTR_SUBSCR_NAME, sub->err)
00276 )
00277
00278 OCI_ReleaseMetaString(ostr);
00279
00280
00281
00282 attr = OCI_SUBSCR_NAMESPACE_DBCHANGE;
00283
00284 OCI_CALL3
00285 (
00286 res, sub->err,
00287
00288 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00289 (dvoid *) &attr, (ub4) sizeof(attr),
00290 (ub4) OCI_ATTR_SUBSCR_NAMESPACE, sub->err)
00291 )
00292
00293
00294
00295
00296
00297 #ifdef _MSC_VER
00298 #pragma warning(disable: 4054)
00299 #endif
00300
00301
00302
00303 OCI_CALL3
00304 (
00305 res, sub->err,
00306
00307 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00308 (dvoid *) OCI_ProcNotify, (ub4) 0,
00309 (ub4) OCI_ATTR_SUBSCR_CALLBACK, sub->err)
00310 )
00311
00312 #ifdef _MSC_VER
00313 #pragma warning(default: 4054)
00314 #endif
00315
00316
00317
00318 if (sub->type & OCI_CNT_ROWS)
00319 {
00320 attr = TRUE;
00321
00322 OCI_CALL3
00323 (
00324 res, sub->err,
00325
00326 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00327 (dvoid *) &attr, (ub4) sizeof(attr),
00328 (ub4) OCI_ATTR_CHNF_ROWIDS, sub->err)
00329 )
00330 }
00331
00332
00333
00334 OCI_CALL3
00335 (
00336 res, sub->err,
00337
00338 OCIAttrSet((dvoid *) sub->subhp, (ub4) OCI_HTYPE_SUBSCRIPTION,
00339 (dvoid *) sub, (ub4) 0,
00340 (ub4) OCI_ATTR_SUBSCR_CTX, sub->err)
00341 )
00342
00343
00344
00345 OCI_CALL3
00346 (
00347 res, sub->err,
00348
00349 OCISubscriptionRegister(sub->con->cxt, &sub->subhp, (ub2) 1,
00350 sub->err,(ub4) OCI_DEFAULT)
00351
00352 )
00353 }
00354 }
00355 else
00356 res = FALSE;
00357
00358 if (res == FALSE)
00359 {
00360 OCI_SubscriptionClose(sub);
00361 OCI_ListRemove(OCILib.subs, sub);
00362 OCI_FREE(sub);
00363 }
00364
00365 #else
00366
00367 res = FALSE;
00368
00369 OCI_NOT_USED(name);
00370 OCI_NOT_USED(type);
00371 OCI_NOT_USED(handler);
00372 OCI_NOT_USED(port);
00373 OCI_NOT_USED(timeout);
00374 OCI_NOT_USED(con);
00375 OCI_NOT_USED(item);
00376
00377 #endif
00378
00379 OCI_RESULT(res);
00380
00381 return sub;
00382 }
00383
00384
00385
00386
00387
00388 boolean OCI_API OCI_SubscriptionUnregister
00389 (
00390 OCI_Subscription *sub
00391 )
00392 {
00393 boolean res = TRUE;
00394
00395 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, FALSE);
00396
00397 res = OCI_SubscriptionClose(sub);
00398
00399 OCI_ListRemove(OCILib.subs, sub);
00400
00401 OCI_FREE(sub);
00402
00403 OCI_RESULT(res);
00404
00405 return res;
00406 }
00407
00408
00409
00410
00411
00412 boolean OCI_API OCI_SubscriptionAddStatement
00413 (
00414 OCI_Subscription *sub,
00415 OCI_Statement *stmt
00416 )
00417 {
00418 boolean res = TRUE;
00419
00420 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, FALSE);
00421 OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
00422
00423 OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_CLOSED, FALSE);
00424 OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_EXECUTED, FALSE);
00425
00426 #if OCI_VERSION_COMPILE >= OCI_10_2
00427
00428
00429
00430 if (sub->type & OCI_CNT_OBJECTS)
00431 {
00432 OCI_CALL3
00433 (
00434 res, sub->err,
00435
00436 OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
00437 (dvoid *) sub->subhp, (ub4) 0,
00438 (ub4) OCI_ATTR_CHNF_REGHANDLE, sub->err)
00439 )
00440
00441 res = res && OCI_Execute(stmt) && (OCI_GetResultset(stmt) != NULL);
00442 }
00443
00444 #endif
00445
00446 OCI_RESULT(res);
00447
00448 return res;
00449 }
00450
00451
00452
00453
00454
00455 const mtext * OCI_API OCI_SubscriptionGetName
00456 (
00457 OCI_Subscription *sub
00458 )
00459 {
00460 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, NULL);
00461
00462 OCI_RESULT(TRUE);
00463
00464 return sub->name;
00465 }
00466
00467
00468
00469
00470
00471 unsigned int OCI_API OCI_SubscriptionGetPort
00472 (
00473 OCI_Subscription *sub
00474 )
00475 {
00476 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, 0);
00477
00478 OCI_RESULT(TRUE);
00479
00480 return sub->port;
00481 }
00482
00483
00484
00485
00486
00487 unsigned int OCI_API OCI_SubscriptionGetTimeout
00488 (
00489 OCI_Subscription *sub
00490 )
00491 {
00492 OCI_CHECK_PTR(OCI_IPC_NOTIFY, sub, 0);
00493
00494 OCI_RESULT(TRUE);
00495
00496 return sub->timeout;
00497 }
00498