oracledb 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Change Log
2
2
 
3
+ ## node-oracledb v2.3.0 (7 Jun 2018)
4
+
5
+ - The stated compatibility is now for Node.js 6, 8, and 10 due to EOL
6
+ of Node.js 4, and the release of Node 10.
7
+
8
+ - Added support for heterogeneous connection pooling and for proxy
9
+ support in connection pools. This allows each connection in the
10
+ pool to use different database credentials.
11
+
12
+ - Added support for Oracle Database Continuous Query Notifications,
13
+ allowing JavaScript methods to be called when database changes are
14
+ committed.
15
+
16
+ - Added support to `fetchAsString` and `fetchInfo` for fetching RAW
17
+ columns as STRING (hex-encoded).
18
+
19
+ - Added Windows support for building binary packages for self-hosting
20
+ on internal networks. PR #891 (Danilo Silva).
21
+
22
+ - Eliminated a memory leak when binding LOBs as `oracledb.BIND_INOUT`.
23
+
24
+ - Added an error message indicating that `batchErrors` and
25
+ `dmlRowCounts` can only be used with INSERT, UPDATE, DELETE and
26
+ MERGE statements.
27
+
28
+ - Fixed a bug that caused `queryStream()` to emit multiple close
29
+ events in Node.js 10.
30
+
31
+ - Fixed a crash when getting the list of names for an undefined object
32
+ with Node.js 6.
33
+
34
+ - Remove deprecated `Buffer()` function in tests in order to eliminate
35
+ a deprecation warning with Node.js 10.
36
+
37
+ - Upgraded NAN dependency from 2.8 to 2.10.
38
+
39
+ - Made some internal changes to fix NAN 2.10 deprecations: Replaced
40
+ `v8::String::Utf8Value` with `Nan::Uft8String`. Replaced
41
+ `MakeCallback()` with `runInAsyncScope()`.
42
+
43
+ - Mention that `queueRequests` is deprecated and will be removed in a
44
+ future version; connection pool queuing will always be enabled in
45
+ that future version.
46
+
3
47
  ## node-oracledb v2.2.0 (3 Apr 2018)
4
48
 
5
49
  - Added
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # node-oracledb version 2.2
1
+ # node-oracledb version 2.3
2
2
 
3
3
  The node-oracledb add-on for Node.js powers high performance Oracle
4
4
  Database applications.
5
5
 
6
- Use node-oracledb to connect Node.js 4, 6, 8 and 9 to Oracle Database.
6
+ Use node-oracledb to connect Node.js 6, 8 and 10 to Oracle Database.
7
7
 
8
8
  Node-oracledb supports basic and advanced features of Oracle Database
9
9
  and Oracle Client. See the
package/binding.gyp CHANGED
@@ -8,6 +8,7 @@
8
8
  "src/njsPool.cpp",
9
9
  "src/njsConnection.cpp",
10
10
  "src/njsResultSet.cpp",
11
+ "src/njsSubscription.cpp",
11
12
  "src/njsMessages.cpp",
12
13
  "src/njsIntLob.cpp",
13
14
  "odpi/src/dpiConn.c",
package/lib/connection.js CHANGED
@@ -32,6 +32,8 @@ var closePromisified;
32
32
  var breakPromisified;
33
33
  var changePasswordPromisified;
34
34
  var pingPromisified;
35
+ var subscribePromisified;
36
+ var unsubscribePromisified;
35
37
 
36
38
  // The queryStream function is similar to execute except that it immediately
37
39
  // returns a QueryStream.
@@ -321,6 +323,34 @@ function ping(pingCb) {
321
323
 
322
324
  pingPromisified = nodbUtil.promisify(ping);
323
325
 
326
+ // create a subscription which can be used to get notifications of database
327
+ // changes
328
+ function subscribe(name, options, subscribeCb) {
329
+ var self = this;
330
+
331
+ nodbUtil.assert(arguments.length == 3, 'NJS-009');
332
+ nodbUtil.assert(typeof name === 'string', 'NJS-006', 1);
333
+ nodbUtil.assert(nodbUtil.isObject(options), 'NJS-006', 2);
334
+ nodbUtil.assert(typeof subscribeCb === 'function', 'NJS-006', 3);
335
+ self._subscribe.call(self, name, options, subscribeCb);
336
+ }
337
+
338
+ subscribePromisified = nodbUtil.promisify(subscribe);
339
+
340
+ // destroy a subscription which was earlier created using subscribe()
341
+ function unsubscribe(name, cb) {
342
+ var self = this;
343
+
344
+ nodbUtil.assert(arguments.length == 2, 'NJS-009');
345
+ nodbUtil.assert(typeof name === 'string', 'NJS-006', 1);
346
+ nodbUtil.assert(typeof cb === 'function', 'NJS-006', 2);
347
+
348
+ self._unsubscribe.call(self, name, cb);
349
+ }
350
+
351
+ unsubscribePromisified = nodbUtil.promisify(unsubscribe);
352
+
353
+
324
354
  // The extend method is used to extend the Connection instance from the C layer with
325
355
  // custom properties and method overrides. References to the original methods are
326
356
  // maintained so they can be invoked by the overriding method at the right time.
@@ -427,6 +457,22 @@ function extend(conn, oracledb, pool) {
427
457
  value: pingPromisified,
428
458
  enumerable: true,
429
459
  writable: true
460
+ },
461
+ _subscribe: {
462
+ value: conn.subscribe
463
+ },
464
+ subscribe: {
465
+ value: subscribePromisified,
466
+ enumerable: true,
467
+ writable: true
468
+ },
469
+ _unsubscribe: {
470
+ value: conn.unsubscribe
471
+ },
472
+ unsubscribe: {
473
+ value: unsubscribePromisified,
474
+ enumerable: true,
475
+ writable: true
430
476
  }
431
477
  }
432
478
  );
package/lib/oracledb.js CHANGED
@@ -324,6 +324,34 @@ function extend(oracledb) {
324
324
  value: 0,
325
325
  enumerable: true
326
326
  },
327
+ CQN_OPCODE_ALL_OPS: {
328
+ value: 0,
329
+ enumerable: true
330
+ },
331
+ CQN_OPCODE_ALL_ROWS: {
332
+ value: 1,
333
+ enumerable: true
334
+ },
335
+ CQN_OPCODE_ALTER: {
336
+ value: 16,
337
+ enumerable: true
338
+ },
339
+ CQN_OPCODE_DELETE: {
340
+ value: 8,
341
+ enumerable: true
342
+ },
343
+ CQN_OPCODE_DROP: {
344
+ value: 32,
345
+ enumerable: true
346
+ },
347
+ CQN_OPCODE_INSERT: {
348
+ value: 2,
349
+ enumerable: true
350
+ },
351
+ CQN_OPCODE_UPDATE: {
352
+ value: 4,
353
+ enumerable: true
354
+ },
327
355
  DB_TYPE_VARCHAR: {
328
356
  value: 1,
329
357
  enumerable: true
@@ -460,6 +488,62 @@ function extend(oracledb) {
460
488
  value: 2001,
461
489
  enumerable: true
462
490
  },
491
+ SUBSCR_EVENT_TYPE_DEREG: {
492
+ value: 5,
493
+ enumerable: true
494
+ },
495
+ SUBSCR_EVENT_TYPE_OBJ_CHANGE: {
496
+ value: 6,
497
+ enumerable: true
498
+ },
499
+ SUBSCR_EVENT_TYPE_QUERY_CHANGE: {
500
+ value: 7,
501
+ enumerable: true
502
+ },
503
+ SUBSCR_EVENT_TYPE_AQ: {
504
+ value: 100,
505
+ enumerable: true
506
+ },
507
+ SUBSCR_GROUPING_CLASS_TIME: {
508
+ value: 1,
509
+ enumerable: true
510
+ },
511
+ SUBSCR_GROUPING_TYPE_SUMMARY: {
512
+ value: 1,
513
+ enumerable: true
514
+ },
515
+ SUBSCR_GROUPING_TYPE_LAST: {
516
+ value: 2,
517
+ enumerable: true
518
+ },
519
+ SUBSCR_NAMESPACE_AQ: {
520
+ value: 1,
521
+ enumerable: true
522
+ },
523
+ SUBSCR_NAMESPACE_DBCHANGE: {
524
+ value: 2,
525
+ enumerable: true
526
+ },
527
+ SUBSCR_QOS_BEST_EFFORT: {
528
+ value: 16,
529
+ enumerable: true
530
+ },
531
+ SUBSCR_QOS_DEREG_NFY: {
532
+ value: 2,
533
+ enumerable: true
534
+ },
535
+ SUBSCR_QOS_QUERY: {
536
+ value: 8,
537
+ enumerable: true
538
+ },
539
+ SUBSCR_QOS_RELIABLE: {
540
+ value: 1,
541
+ enumerable: true
542
+ },
543
+ SUBSCR_QOS_ROWIDS: {
544
+ value: 4,
545
+ enumerable: true
546
+ },
463
547
  NUMBER: {
464
548
  value: 2002,
465
549
  enumerable: true
package/lib/pool.js CHANGED
@@ -27,14 +27,14 @@ var closePromisified;
27
27
  // completeConnectionRequest does the actual work of getting a connection from a
28
28
  // pool when queuing is enabled. It's abstracted out so it can be called from
29
29
  // getConnection and checkRequestQueue constently.
30
- function completeConnectionRequest(getConnectionCb) {
30
+ function completeConnectionRequest(config, getConnectionCb) {
31
31
  var self = this;
32
32
 
33
33
  // Incrementing _connectionsOut prior to making the async call to get a connection
34
34
  // to prevent other connection requests from exceeding the poolMax.
35
35
  self._connectionsOut += 1;
36
36
 
37
- self._getConnection(function(err, connInst) {
37
+ self._getConnection(config, function(err, connInst) {
38
38
  if (err) {
39
39
  // Decrementing _connectionsOut if we didn't actually get a connection
40
40
  // and then rechecking the queue.
@@ -98,7 +98,8 @@ function checkRequestQueue() {
98
98
  payload.timerIdx = null;
99
99
  }
100
100
 
101
- completeConnectionRequest.call(self, payload.getConnectionCb);
101
+ completeConnectionRequest.call(self, payload.config,
102
+ payload.getConnectionCb);
102
103
  }
103
104
 
104
105
  // onRequestTimeout is used to prevent requests for connections from sitting in the
@@ -129,14 +130,23 @@ function onRequestTimeout(timerIdx) {
129
130
  // directly to the C layer if queueing is disabled. If queueing is enabled and the
130
131
  // connections out is under the poolMax then the request will be completed immediately.
131
132
  // Otherwise the request will be queued and completed when a connection is avaialble.
132
- function getConnection(getConnectionCb) {
133
+ function getConnection(a1, a2) {
133
134
  var self = this;
134
135
  var payload;
135
136
  var timeoutHandle;
136
137
  var timerIdx;
138
+ var getConnectionCb = arguments[arguments.length - 1];
139
+ var options = {};
137
140
 
138
- nodbUtil.assert(arguments.length === 1, 'NJS-009');
139
- nodbUtil.assert(typeof getConnectionCb === 'function', 'NJS-006', 1);
141
+ nodbUtil.assert(arguments.length >= 1 && arguments.length <= 2, 'NJS-009');
142
+ nodbUtil.assert(typeof getConnectionCb === 'function', 'NJS-006',
143
+ arguments.length);
144
+
145
+ // Optional JSON parameter
146
+ if (arguments.length > 1 ) {
147
+ options = arguments[0];
148
+ nodbUtil.assert(nodbUtil.isObject(options), 'NJS-006', 1 );
149
+ }
140
150
 
141
151
  // Added this check because if the pool isn't valid and we reference self.poolMax
142
152
  // (which is a C layer getter) an error will be thrown.
@@ -154,7 +164,7 @@ function getConnection(getConnectionCb) {
154
164
  }
155
165
 
156
166
  if (self.queueRequests === false) { // queueing is disabled for pool
157
- self._getConnection(function(err, connInst) {
167
+ self._getConnection(options, function(err, connInst) {
158
168
  if (err) {
159
169
  if (self._enableStats) {
160
170
  self._totalFailedRequests += 1;
@@ -170,7 +180,7 @@ function getConnection(getConnectionCb) {
170
180
  getConnectionCb(null, connInst);
171
181
  });
172
182
  } else if (self._connectionsOut < self.poolMax) { // queueing enabled, but not needed
173
- completeConnectionRequest.call(self, getConnectionCb);
183
+ completeConnectionRequest.call(self, options, getConnectionCb);
174
184
  } else { // need to queue the request
175
185
  if (self._usingQueueTimeout) {
176
186
  self._connRequestTimersIdx += 1;
@@ -187,7 +197,8 @@ function getConnection(getConnectionCb) {
187
197
  payload = {
188
198
  timerIdx: timerIdx,
189
199
  timeoutHandle: timeoutHandle,
190
- getConnectionCb: getConnectionCb
200
+ getConnectionCb: getConnectionCb,
201
+ config : options
191
202
  };
192
203
 
193
204
  if (self._usingQueueTimeout) {
@@ -48,7 +48,8 @@ function QueryStream(resultSet, oracledb) {
48
48
  );
49
49
 
50
50
  Readable.call(self, {
51
- objectMode: true
51
+ objectMode: true,
52
+ emitClose: false // Prevents duplicate close events
52
53
  });
53
54
 
54
55
  // Check if QueryStream was created via ResultSet.toQueryStream() then the
package/lib/rel.txt CHANGED
@@ -1 +1 @@
1
- 57c1f83a4343c4db029b9df327b50deae3c9cf2c Thu 29 Mar 2018 08:05:42 UTC
1
+ 88e5d8dd1201e3d0244e8264cf1d0652b2be378e Tue 5 Jun 2018 07:13:28 UTC
package/odpi/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ODPI-C version 2.3
1
+ # ODPI-C version 2.4
2
2
 
3
3
  Oracle Database Programming Interface for C (ODPI-C) is an open source library
4
4
  of C code that simplifies access to Oracle Database for applications written in
@@ -39,7 +39,7 @@ See [CONTRIBUTING](https://github.com/oracle/odpi/blob/master/CONTRIBUTING.md).
39
39
 
40
40
  Oracle Drivers:
41
41
  * [cx_Oracle](https://oracle.github.io/python-cx_Oracle) Python interface.
42
- * [node-oracledb](https://github.com/oracle/node-oracledb/tree/dev-2.0) Node.js module.
42
+ * [node-oracledb](https://oracle.github.io/node-oracledb) Node.js module.
43
43
 
44
44
  Third-party Drivers:
45
45
  * [go-goracle](https://gopkg.in/goracle.v2) Go Driver.
@@ -44,7 +44,7 @@
44
44
 
45
45
  // define ODPI-C version information
46
46
  #define DPI_MAJOR_VERSION 2
47
- #define DPI_MINOR_VERSION 3
47
+ #define DPI_MINOR_VERSION 4
48
48
  #define DPI_PATCH_LEVEL 0
49
49
  #define DPI_VERSION_SUFFIX
50
50
 
@@ -159,7 +159,8 @@ typedef enum {
159
159
  DPI_EVENT_DROP_DB = 4, // OCI_EVENT_DROP_DB
160
160
  DPI_EVENT_DEREG = 5, // OCI_EVENT_DEREG
161
161
  DPI_EVENT_OBJCHANGE = 6, // OCI_EVENT_OBJCHANGE
162
- DPI_EVENT_QUERYCHANGE = 7 // OCI_EVENT_QUERYCHANGE
162
+ DPI_EVENT_QUERYCHANGE = 7, // OCI_EVENT_QUERYCHANGE
163
+ DPI_EVENT_AQ = 100
163
164
  } dpiEventType;
164
165
 
165
166
  // statement execution modes
@@ -268,7 +269,8 @@ typedef enum {
268
269
  typedef enum {
269
270
  DPI_MODE_POOL_GET_WAIT = 0, // OCI_SPOOL_ATTRVAL_WAIT
270
271
  DPI_MODE_POOL_GET_NOWAIT = 1, // OCI_SPOOL_ATTRVAL_NOWAIT
271
- DPI_MODE_POOL_GET_FORCEGET = 2 // OCI_SPOOL_ATTRVAL_FORCEGET
272
+ DPI_MODE_POOL_GET_FORCEGET = 2, // OCI_SPOOL_ATTRVAL_FORCEGET
273
+ DPI_MODE_POOL_GET_TIMEDWAIT = 3 // OCI_SPOOL_ATTRVAL_TIMEDWAIT
272
274
  } dpiPoolGetMode;
273
275
 
274
276
  // purity values when acquiring a connection from a pool
@@ -314,9 +316,17 @@ typedef enum {
314
316
  DPI_STMT_TYPE_COMMIT = 21
315
317
  } dpiStatementType;
316
318
 
319
+ // subscription grouping classes
320
+ #define DPI_SUBSCR_GROUPING_CLASS_TIME 1
321
+
322
+ // subscription grouping types
323
+ #define DPI_SUBSCR_GROUPING_TYPE_SUMMARY 1
324
+ #define DPI_SUBSCR_GROUPING_TYPE_LAST 2
325
+
317
326
  // subscription namespaces
318
327
  typedef enum {
319
- DPI_SUBSCR_NAMESPACE_DBCHANGE = 2 // OCI_SUBSCR_NAMESPACE_DBCHANGE
328
+ DPI_SUBSCR_NAMESPACE_AQ = 1, // OCI_SUBSCR_NAMESPACE_AQ
329
+ DPI_SUBSCR_NAMESPACE_DBCHANGE = 2 // OCI_SUBSCR_NAMESPACE_DBCHANGE
320
330
  } dpiSubscrNamespace;
321
331
 
322
332
  // subscription protocols
@@ -562,6 +572,9 @@ struct dpiPoolCreateParams {
562
572
  dpiPoolGetMode getMode;
563
573
  const char *outPoolName;
564
574
  uint32_t outPoolNameLength;
575
+ uint32_t timeout;
576
+ uint32_t waitTimeout;
577
+ uint32_t maxLifetimeSession;
565
578
  };
566
579
 
567
580
  // structure used for transferring query metadata from ODPI-C
@@ -606,6 +619,11 @@ struct dpiSubscrCreateParams {
606
619
  void *callbackContext;
607
620
  const char *recipientName;
608
621
  uint32_t recipientNameLength;
622
+ const char *ipAddress;
623
+ uint32_t ipAddressLength;
624
+ uint8_t groupingClass;
625
+ uint32_t groupingValue;
626
+ uint8_t groupingType;
609
627
  };
610
628
 
611
629
  // structure used for transferring messages in subscription callbacks
@@ -620,6 +638,11 @@ struct dpiSubscrMessage {
620
638
  dpiErrorInfo *errorInfo;
621
639
  const void *txId;
622
640
  uint32_t txIdLength;
641
+ int registered;
642
+ const char *queueName;
643
+ uint32_t queueNameLength;
644
+ const char *consumerName;
645
+ uint32_t consumerNameLength;
623
646
  };
624
647
 
625
648
  // structure used for transferring query information in messages in
@@ -853,6 +876,13 @@ int dpiConn_shutdownDatabase(dpiConn *conn, dpiShutdownMode mode);
853
876
  // startup the database
854
877
  int dpiConn_startupDatabase(dpiConn *conn, dpiStartupMode mode);
855
878
 
879
+ // subscribe to events in the database
880
+ int dpiConn_subscribe(dpiConn *conn, dpiSubscrCreateParams *params,
881
+ dpiSubscr **subscr);
882
+
883
+ // unsubscribe from events in the database
884
+ int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr);
885
+
856
886
 
857
887
  //-----------------------------------------------------------------------------
858
888
  // Data Methods (dpiData)
@@ -1316,6 +1346,9 @@ int dpiPool_getStmtCacheSize(dpiPool *pool, uint32_t *cacheSize);
1316
1346
  // get the pool's timeout value
1317
1347
  int dpiPool_getTimeout(dpiPool *pool, uint32_t *value);
1318
1348
 
1349
+ // get the pool's wait timeout value
1350
+ int dpiPool_getWaitTimeout(dpiPool *pool, uint32_t *value);
1351
+
1319
1352
  // release a reference to the pool
1320
1353
  int dpiPool_release(dpiPool *pool);
1321
1354
 
@@ -1331,6 +1364,9 @@ int dpiPool_setStmtCacheSize(dpiPool *pool, uint32_t cacheSize);
1331
1364
  // set the pool's timeout value
1332
1365
  int dpiPool_setTimeout(dpiPool *pool, uint32_t value);
1333
1366
 
1367
+ // set the pool's wait timeout value
1368
+ int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value);
1369
+
1334
1370
 
1335
1371
  //-----------------------------------------------------------------------------
1336
1372
  // Statement Methods (dpiStmt)
@@ -416,7 +416,11 @@ static int dpiConn__get(dpiConn *conn, const char *userName,
416
416
  externalAuth = pool->externalAuth;
417
417
  if (userName && pool->homogeneous)
418
418
  return dpiError__set(error, "check proxy", DPI_ERR_INVALID_PROXY);
419
- if (userName)
419
+
420
+ // if the userName is provided but no password is provided and external
421
+ // authentication is not being used, proxy authentication is taking
422
+ // place
423
+ if (userName && !password && !externalAuth)
420
424
  mode |= DPI_OCI_SESSGET_CREDPROXY;
421
425
  if (createParams->matchAnyTag)
422
426
  mode |= DPI_OCI_SESSGET_SPOOL_MATCHANY;
@@ -1168,7 +1172,6 @@ int dpiConn_create(const dpiContext *context, const char *userName,
1168
1172
  dpiCommonCreateParams localCommonParams;
1169
1173
  dpiConnCreateParams localCreateParams;
1170
1174
  dpiConn *tempConn;
1171
- size_t structSize;
1172
1175
  dpiError error;
1173
1176
  int status;
1174
1177
 
@@ -1187,10 +1190,10 @@ int dpiConn_create(const dpiContext *context, const char *userName,
1187
1190
  commonParams = &localCommonParams;
1188
1191
  }
1189
1192
  if (!createParams || context->dpiMinorVersion == 0) {
1190
- dpiContext__initConnCreateParams(context, &localCreateParams,
1191
- &structSize);
1193
+ dpiContext__initConnCreateParams(&localCreateParams);
1192
1194
  if (createParams)
1193
- memcpy(&localCreateParams, createParams, structSize);
1195
+ memcpy(&localCreateParams, createParams,
1196
+ sizeof(dpiConnCreateParams__v20));
1194
1197
  createParams = &localCreateParams;
1195
1198
  }
1196
1199
 
@@ -1942,3 +1945,59 @@ int dpiConn_startupDatabase(dpiConn *conn, dpiStartupMode mode)
1942
1945
  return dpiGen__endPublicFn(conn, status, &error);
1943
1946
  }
1944
1947
 
1948
+ //-----------------------------------------------------------------------------
1949
+ // dpiConn_subscribe() [PUBLIC]
1950
+ // Subscribe to events in the database. A subscription is created and
1951
+ // returned. This replaces dpiConn_newSubscription().
1952
+ //-----------------------------------------------------------------------------
1953
+ int dpiConn_subscribe(dpiConn *conn, dpiSubscrCreateParams *params,
1954
+ dpiSubscr **subscr)
1955
+ {
1956
+ dpiSubscr *tempSubscr;
1957
+ dpiError error;
1958
+
1959
+ if (dpiConn__checkConnected(conn, __func__, &error) < 0)
1960
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1961
+ DPI_CHECK_PTR_NOT_NULL(conn, params)
1962
+ DPI_CHECK_PTR_NOT_NULL(conn, subscr)
1963
+ if (!conn->env->events) {
1964
+ dpiError__set(&error, "subscribe", DPI_ERR_EVENTS_MODE_REQUIRED);
1965
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1966
+ }
1967
+ if (dpiGen__allocate(DPI_HTYPE_SUBSCR, conn->env, (void**) &tempSubscr,
1968
+ &error) < 0)
1969
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1970
+ if (dpiSubscr__create(tempSubscr, conn, params, NULL, &error) < 0) {
1971
+ dpiSubscr__free(tempSubscr, &error);
1972
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1973
+ }
1974
+
1975
+ *subscr = tempSubscr;
1976
+ return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error);
1977
+ }
1978
+
1979
+
1980
+ //-----------------------------------------------------------------------------
1981
+ // dpiConn_unsubscribe() [PUBLIC]
1982
+ // Unsubscribe from events in the database. Once this call completes
1983
+ // successfully no further notifications will be sent.
1984
+ //-----------------------------------------------------------------------------
1985
+ int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr)
1986
+ {
1987
+ dpiError error;
1988
+
1989
+ if (dpiConn__checkConnected(conn, __func__, &error) < 0)
1990
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1991
+ if (dpiGen__checkHandle(subscr, DPI_HTYPE_SUBSCR, "check subscription",
1992
+ &error) < 0)
1993
+ return dpiGen__endPublicFn(conn, DPI_FAILURE, &error);
1994
+ if (subscr->registered) {
1995
+ if (dpiOci__subscriptionUnRegister(conn, subscr, &error) < 0)
1996
+ return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error);
1997
+ subscr->registered = 0;
1998
+ }
1999
+
2000
+ dpiGen__setRefCount(subscr, &error, -1);
2001
+ return dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error);
2002
+ }
2003
+
@@ -77,13 +77,9 @@ void dpiContext__initCommonCreateParams(dpiCommonCreateParams *params)
77
77
  // the structure size as a convenience for calling functions which may have to
78
78
  // differentiate between different ODPI-C application versions.
79
79
  //-----------------------------------------------------------------------------
80
- void dpiContext__initConnCreateParams(const dpiContext *context,
81
- dpiConnCreateParams *params, size_t *structSize)
80
+ void dpiContext__initConnCreateParams(dpiConnCreateParams *params)
82
81
  {
83
- *structSize = sizeof(dpiConnCreateParams);
84
- if (context->dpiMinorVersion == 0)
85
- *structSize = sizeof(dpiConnCreateParams__v20);
86
- memset(params, 0, *structSize);
82
+ memset(params, 0, sizeof(dpiConnCreateParams));
87
83
  }
88
84
 
89
85
 
@@ -112,6 +108,7 @@ void dpiContext__initSubscrCreateParams(dpiSubscrCreateParams *params)
112
108
  {
113
109
  memset(params, 0, sizeof(dpiSubscrCreateParams));
114
110
  params->subscrNamespace = DPI_SUBSCR_NAMESPACE_DBCHANGE;
111
+ params->groupingType = DPI_SUBSCR_GROUPING_TYPE_SUMMARY;
115
112
  }
116
113
 
117
114
 
@@ -223,14 +220,19 @@ int dpiContext_initCommonCreateParams(const dpiContext *context,
223
220
  int dpiContext_initConnCreateParams(const dpiContext *context,
224
221
  dpiConnCreateParams *params)
225
222
  {
226
- size_t structSize;
223
+ dpiConnCreateParams localParams;
227
224
  dpiError error;
228
225
 
229
226
  if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0,
230
227
  &error) < 0)
231
228
  return dpiGen__endPublicFn(context, DPI_FAILURE, &error);
232
229
  DPI_CHECK_PTR_NOT_NULL(context, params)
233
- dpiContext__initConnCreateParams(context, params, &structSize);
230
+ if (context->dpiMinorVersion > 0)
231
+ dpiContext__initConnCreateParams(params);
232
+ else {
233
+ dpiContext__initConnCreateParams(&localParams);
234
+ memcpy(params, &localParams, sizeof(dpiConnCreateParams__v20));
235
+ }
234
236
  return dpiGen__endPublicFn(context, DPI_SUCCESS, &error);
235
237
  }
236
238
 
@@ -242,13 +244,19 @@ int dpiContext_initConnCreateParams(const dpiContext *context,
242
244
  int dpiContext_initPoolCreateParams(const dpiContext *context,
243
245
  dpiPoolCreateParams *params)
244
246
  {
247
+ dpiPoolCreateParams localParams;
245
248
  dpiError error;
246
249
 
247
250
  if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0,
248
251
  &error) < 0)
249
252
  return dpiGen__endPublicFn(context, DPI_FAILURE, &error);
250
253
  DPI_CHECK_PTR_NOT_NULL(context, params)
251
- dpiContext__initPoolCreateParams(params);
254
+ if (context->dpiMinorVersion > 3)
255
+ dpiContext__initPoolCreateParams(params);
256
+ else {
257
+ dpiContext__initPoolCreateParams(&localParams);
258
+ memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v23));
259
+ }
252
260
  return dpiGen__endPublicFn(context, DPI_SUCCESS, &error);
253
261
  }
254
262
 
@@ -260,13 +268,19 @@ int dpiContext_initPoolCreateParams(const dpiContext *context,
260
268
  int dpiContext_initSubscrCreateParams(const dpiContext *context,
261
269
  dpiSubscrCreateParams *params)
262
270
  {
271
+ dpiSubscrCreateParams localParams;
263
272
  dpiError error;
264
273
 
265
274
  if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0,
266
275
  &error) < 0)
267
276
  return dpiGen__endPublicFn(context, DPI_FAILURE, &error);
268
277
  DPI_CHECK_PTR_NOT_NULL(context, params)
269
- dpiContext__initSubscrCreateParams(params);
278
+ if (context->dpiMinorVersion > 3)
279
+ dpiContext__initSubscrCreateParams(params);
280
+ else {
281
+ dpiContext__initSubscrCreateParams(&localParams);
282
+ memcpy(params, &localParams, sizeof(dpiSubscrCreateParams__v23));
283
+ }
270
284
  return dpiGen__endPublicFn(context, DPI_SUCCESS, &error);
271
285
  }
272
286
 
package/odpi/src/dpiEnv.c CHANGED
@@ -153,9 +153,13 @@ int dpiEnv__init(dpiEnv *env, const dpiContext *context,
153
153
  return DPI_FAILURE;
154
154
 
155
155
  // set whether or not we are threaded
156
- if (params->createMode & DPI_OCI_THREADED)
156
+ if (params->createMode & DPI_MODE_CREATE_THREADED)
157
157
  env->threaded = 1;
158
158
 
159
+ // set whether or not events mode has been set
160
+ if (params->createMode & DPI_MODE_CREATE_EVENTS)
161
+ env->events = 1;
162
+
159
163
  return DPI_SUCCESS;
160
164
  }
161
165
 
@@ -76,5 +76,8 @@ static const char* const dpiErrorMessages[DPI_ERR_MAX - DPI_ERR_NO_ERR] = {
76
76
  "DPI-1060: subscription was already closed", // DPI_ERR_SUBSCR_CLOSED
77
77
  "DPI-1061: edition is not supported when a new password is specified", // DPI_ERR_NO_EDITION_WITH_NEW_PASSWORD
78
78
  "DPI-1062: unexpected OCI return value %d in function %s", // DPI_ERR_UNEXPECTED_OCI_RETURN_VALUE
79
+ "DPI-1063: modes DPI_MODE_EXEC_BATCH_ERRORS and DPI_MODE_EXEC_ARRAY_DML_ROWCOUNTS can only be used with insert, update, delete and merge statements", // DPI_ERR_EXEC_MODE_ONLY_FOR_DML
80
+ "DPI-1064: array variables are not supported with dpiStmt_executeMany()", // DPI_ERR_ARRAY_VAR_NOT_SUPPORTED
81
+ "DPI-1065: events mode is required to subscribe to events in the database", // DPI_ERR_EVENTS_MODE_REQUIRED
79
82
  };
80
83