oracledb 2.1.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 +174 -54
- package/LICENSE.md +52 -18
- package/README.md +35 -68
- package/binding.gyp +5 -4
- package/lib/connection.js +164 -14
- package/lib/oracledb.js +160 -11
- package/lib/pool.js +33 -22
- package/lib/querystream.js +3 -2
- package/lib/rel.txt +1 -1
- package/odpi/LICENSE.md +1 -1
- package/odpi/README.md +25 -84
- package/odpi/embed/README.md +1 -1
- package/odpi/include/dpi.h +51 -7
- package/odpi/src/dpiConn.c +78 -9
- package/odpi/src/dpiContext.c +24 -10
- package/odpi/src/dpiEnv.c +5 -1
- package/odpi/src/dpiError.c +4 -0
- package/odpi/src/dpiErrorMessages.h +6 -4
- package/odpi/src/dpiImpl.h +125 -68
- package/odpi/src/dpiMsgProps.c +33 -0
- package/odpi/src/dpiObject.c +17 -10
- package/odpi/src/dpiObjectType.c +1 -1
- package/odpi/src/dpiOci.c +55 -40
- package/odpi/src/dpiOracleType.c +2 -2
- package/odpi/src/dpiPool.c +88 -18
- package/odpi/src/dpiStmt.c +57 -36
- package/odpi/src/dpiSubscr.c +117 -9
- package/odpi/src/dpiUtils.c +20 -9
- package/odpi/src/dpiVar.c +504 -430
- package/package/MAKEPKG.BAT +64 -1
- package/package/README.md +9 -5
- package/package/createpackage.js +2 -2
- package/package/extractpackage.js +2 -1
- package/package/oracledbinstall.js +19 -19
- package/package/package.json +4 -4
- package/package.json +4 -4
- package/src/njsCommon.cpp +94 -10
- package/src/njsCommon.h +73 -21
- package/src/njsConnection.cpp +1425 -458
- package/src/njsConnection.h +68 -19
- package/src/njsIntLob.cpp +5 -1
- package/src/njsIntLob.h +1 -1
- package/src/njsMessages.cpp +9 -2
- package/src/njsMessages.h +9 -2
- package/src/njsOracle.cpp +213 -23
- package/src/njsOracle.h +18 -2
- package/src/njsPool.cpp +32 -14
- package/src/njsPool.h +4 -4
- package/src/njsResultSet.cpp +4 -3
- package/src/njsResultSet.h +1 -1
- package/src/njsSubscription.cpp +388 -0
- package/src/njsSubscription.h +111 -0
package/odpi/src/dpiOracleType.c
CHANGED
|
@@ -301,6 +301,8 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode,
|
|
|
301
301
|
case DPI_SQLT_FLT:
|
|
302
302
|
case DPI_SQLT_NUM:
|
|
303
303
|
case DPI_SQLT_VNU:
|
|
304
|
+
case DPI_SQLT_BFLOAT:
|
|
305
|
+
case DPI_SQLT_BDOUBLE:
|
|
304
306
|
return DPI_ORACLE_TYPE_NUMBER;
|
|
305
307
|
case DPI_SQLT_DAT:
|
|
306
308
|
case DPI_SQLT_ODT:
|
|
@@ -314,10 +316,8 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode,
|
|
|
314
316
|
case DPI_SQLT_INT:
|
|
315
317
|
case DPI_OCI_TYPECODE_SMALLINT:
|
|
316
318
|
return DPI_ORACLE_TYPE_NATIVE_INT;
|
|
317
|
-
case DPI_SQLT_BFLOAT:
|
|
318
319
|
case DPI_SQLT_IBFLOAT:
|
|
319
320
|
return DPI_ORACLE_TYPE_NATIVE_FLOAT;
|
|
320
|
-
case DPI_SQLT_BDOUBLE:
|
|
321
321
|
case DPI_SQLT_IBDOUBLE:
|
|
322
322
|
return DPI_ORACLE_TYPE_NATIVE_DOUBLE;
|
|
323
323
|
case DPI_SQLT_DATE:
|
package/odpi/src/dpiPool.c
CHANGED
|
@@ -119,6 +119,31 @@ static int dpiPool__create(dpiPool *pool, const char *userName,
|
|
|
119
119
|
DPI_OCI_ATTR_SPOOL_GETMODE, "set get mode", error) < 0)
|
|
120
120
|
return DPI_FAILURE;
|
|
121
121
|
|
|
122
|
+
// set the session timeout on the pool
|
|
123
|
+
if (dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, (void*)
|
|
124
|
+
&createParams->timeout, 0, DPI_OCI_ATTR_SPOOL_TIMEOUT,
|
|
125
|
+
"set timeout", error) < 0)
|
|
126
|
+
return DPI_FAILURE;
|
|
127
|
+
|
|
128
|
+
// set the wait timeout on the pool (valid in 12.2 and higher)
|
|
129
|
+
if (pool->env->versionInfo->versionNum > 12 ||
|
|
130
|
+
(pool->env->versionInfo->versionNum == 12 &&
|
|
131
|
+
pool->env->versionInfo->releaseNum >= 2)) {
|
|
132
|
+
if (dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, (void*)
|
|
133
|
+
&createParams->waitTimeout, 0, DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT,
|
|
134
|
+
"set wait timeout", error) < 0)
|
|
135
|
+
return DPI_FAILURE;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// set the maximum lifetime session on the pool (valid in 12.1 and higher)
|
|
139
|
+
if (pool->env->versionInfo->versionNum >= 12) {
|
|
140
|
+
if (dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, (void*)
|
|
141
|
+
&createParams->maxLifetimeSession, 0,
|
|
142
|
+
DPI_OCI_ATTR_SPOOL_MAX_LIFETIME_SESSION,
|
|
143
|
+
"set max lifetime session", error) < 0)
|
|
144
|
+
return DPI_FAILURE;
|
|
145
|
+
}
|
|
146
|
+
|
|
122
147
|
// set reamining attributes directly
|
|
123
148
|
pool->homogeneous = createParams->homogeneous;
|
|
124
149
|
pool->externalAuth = createParams->externalAuth;
|
|
@@ -154,26 +179,37 @@ void dpiPool__free(dpiPool *pool, dpiError *error)
|
|
|
154
179
|
static int dpiPool__getAttributeUint(dpiPool *pool, uint32_t attribute,
|
|
155
180
|
uint32_t *value, const char *fnName)
|
|
156
181
|
{
|
|
182
|
+
int status, supported = 1;
|
|
157
183
|
dpiError error;
|
|
158
|
-
int status;
|
|
159
184
|
|
|
160
185
|
if (dpiPool__checkConnected(pool, fnName, &error) < 0)
|
|
161
186
|
return dpiGen__endPublicFn(pool, DPI_FAILURE, &error);
|
|
162
187
|
DPI_CHECK_PTR_NOT_NULL(pool, value)
|
|
163
188
|
switch (attribute) {
|
|
164
|
-
case DPI_OCI_ATTR_SPOOL_BUSY_COUNT:
|
|
165
189
|
case DPI_OCI_ATTR_SPOOL_MAX_LIFETIME_SESSION:
|
|
190
|
+
if (pool->env->versionInfo->versionNum < 12)
|
|
191
|
+
supported = 0;
|
|
192
|
+
break;
|
|
193
|
+
case DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT:
|
|
194
|
+
if (pool->env->versionInfo->versionNum < 12 ||
|
|
195
|
+
(pool->env->versionInfo->versionNum == 12 &&
|
|
196
|
+
pool->env->versionInfo->releaseNum < 2))
|
|
197
|
+
supported = 0;
|
|
198
|
+
break;
|
|
199
|
+
case DPI_OCI_ATTR_SPOOL_BUSY_COUNT:
|
|
166
200
|
case DPI_OCI_ATTR_SPOOL_OPEN_COUNT:
|
|
167
201
|
case DPI_OCI_ATTR_SPOOL_STMTCACHESIZE:
|
|
168
202
|
case DPI_OCI_ATTR_SPOOL_TIMEOUT:
|
|
169
|
-
status = dpiOci__attrGet(pool->handle, DPI_OCI_HTYPE_SPOOL, value,
|
|
170
|
-
NULL, attribute, "get attribute value", &error);
|
|
171
203
|
break;
|
|
172
204
|
default:
|
|
173
|
-
|
|
174
|
-
DPI_ERR_NOT_SUPPORTED);
|
|
205
|
+
supported = 0;
|
|
175
206
|
break;
|
|
176
207
|
}
|
|
208
|
+
if (supported)
|
|
209
|
+
status = dpiOci__attrGet(pool->handle, DPI_OCI_HTYPE_SPOOL, value,
|
|
210
|
+
NULL, attribute, "get attribute value", &error);
|
|
211
|
+
else status = dpiError__set(&error, "get attribute value",
|
|
212
|
+
DPI_ERR_NOT_SUPPORTED);
|
|
177
213
|
return dpiGen__endPublicFn(pool, status, &error);
|
|
178
214
|
}
|
|
179
215
|
|
|
@@ -185,10 +221,10 @@ static int dpiPool__getAttributeUint(dpiPool *pool, uint32_t attribute,
|
|
|
185
221
|
static int dpiPool__setAttributeUint(dpiPool *pool, uint32_t attribute,
|
|
186
222
|
uint32_t value, const char *fnName)
|
|
187
223
|
{
|
|
224
|
+
int status, supported = 1;
|
|
225
|
+
void *ociValue = &value;
|
|
188
226
|
uint8_t shortValue;
|
|
189
|
-
void *ociValue;
|
|
190
227
|
dpiError error;
|
|
191
|
-
int status;
|
|
192
228
|
|
|
193
229
|
// make sure session pool is connected
|
|
194
230
|
if (dpiPool__checkConnected(pool, fnName, &error) < 0)
|
|
@@ -201,18 +237,29 @@ static int dpiPool__setAttributeUint(dpiPool *pool, uint32_t attribute,
|
|
|
201
237
|
ociValue = &shortValue;
|
|
202
238
|
break;
|
|
203
239
|
case DPI_OCI_ATTR_SPOOL_MAX_LIFETIME_SESSION:
|
|
240
|
+
if (pool->env->versionInfo->versionNum < 12)
|
|
241
|
+
supported = 0;
|
|
242
|
+
break;
|
|
243
|
+
case DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT:
|
|
244
|
+
if (pool->env->versionInfo->versionNum < 12 ||
|
|
245
|
+
(pool->env->versionInfo->versionNum == 12 &&
|
|
246
|
+
pool->env->versionInfo->releaseNum < 2))
|
|
247
|
+
supported = 0;
|
|
248
|
+
break;
|
|
204
249
|
case DPI_OCI_ATTR_SPOOL_STMTCACHESIZE:
|
|
205
250
|
case DPI_OCI_ATTR_SPOOL_TIMEOUT:
|
|
206
|
-
ociValue = &value;
|
|
207
251
|
break;
|
|
208
252
|
default:
|
|
209
|
-
|
|
210
|
-
|
|
253
|
+
supported = 0;
|
|
254
|
+
break;
|
|
211
255
|
}
|
|
212
256
|
|
|
213
257
|
// set value in the OCI
|
|
214
|
-
|
|
215
|
-
|
|
258
|
+
if (supported)
|
|
259
|
+
status = dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, ociValue,
|
|
260
|
+
0, attribute, "set attribute value", &error);
|
|
261
|
+
else status = dpiError__set(&error, "set attribute value",
|
|
262
|
+
DPI_ERR_NOT_SUPPORTED);
|
|
216
263
|
return dpiGen__endPublicFn(pool, status, &error);
|
|
217
264
|
}
|
|
218
265
|
|
|
@@ -226,7 +273,6 @@ int dpiPool_acquireConnection(dpiPool *pool, const char *userName,
|
|
|
226
273
|
dpiConnCreateParams *params, dpiConn **conn)
|
|
227
274
|
{
|
|
228
275
|
dpiConnCreateParams localParams;
|
|
229
|
-
size_t structSize;
|
|
230
276
|
dpiError error;
|
|
231
277
|
int status;
|
|
232
278
|
|
|
@@ -239,10 +285,9 @@ int dpiPool_acquireConnection(dpiPool *pool, const char *userName,
|
|
|
239
285
|
|
|
240
286
|
// use default parameters if none provided
|
|
241
287
|
if (!params || pool->env->context->dpiMinorVersion == 0) {
|
|
242
|
-
dpiContext__initConnCreateParams(
|
|
243
|
-
&structSize);
|
|
288
|
+
dpiContext__initConnCreateParams(&localParams);
|
|
244
289
|
if (params)
|
|
245
|
-
memcpy(&localParams, params,
|
|
290
|
+
memcpy(&localParams, params, sizeof(dpiConnCreateParams__v20));
|
|
246
291
|
params = &localParams;
|
|
247
292
|
}
|
|
248
293
|
|
|
@@ -309,8 +354,11 @@ int dpiPool_create(const dpiContext *context, const char *userName,
|
|
|
309
354
|
dpiContext__initCommonCreateParams(&localCommonParams);
|
|
310
355
|
commonParams = &localCommonParams;
|
|
311
356
|
}
|
|
312
|
-
if (!createParams) {
|
|
357
|
+
if (!createParams || context->dpiMinorVersion < 4) {
|
|
313
358
|
dpiContext__initPoolCreateParams(&localCreateParams);
|
|
359
|
+
if (createParams)
|
|
360
|
+
memcpy(&localCreateParams, createParams,
|
|
361
|
+
sizeof(dpiPoolCreateParams__v23));
|
|
314
362
|
createParams = &localCreateParams;
|
|
315
363
|
}
|
|
316
364
|
|
|
@@ -433,6 +481,17 @@ int dpiPool_getTimeout(dpiPool *pool, uint32_t *value)
|
|
|
433
481
|
}
|
|
434
482
|
|
|
435
483
|
|
|
484
|
+
//-----------------------------------------------------------------------------
|
|
485
|
+
// dpiPool_getWaitTimeout() [PUBLIC]
|
|
486
|
+
// Return the pool's wait timeout value.
|
|
487
|
+
//-----------------------------------------------------------------------------
|
|
488
|
+
int dpiPool_getWaitTimeout(dpiPool *pool, uint32_t *value)
|
|
489
|
+
{
|
|
490
|
+
return dpiPool__getAttributeUint(pool, DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT,
|
|
491
|
+
value, __func__);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
|
|
436
495
|
//-----------------------------------------------------------------------------
|
|
437
496
|
// dpiPool_release() [PUBLIC]
|
|
438
497
|
// Release a reference to the pool.
|
|
@@ -486,3 +545,14 @@ int dpiPool_setTimeout(dpiPool *pool, uint32_t value)
|
|
|
486
545
|
__func__);
|
|
487
546
|
}
|
|
488
547
|
|
|
548
|
+
|
|
549
|
+
//-----------------------------------------------------------------------------
|
|
550
|
+
// dpiPool_setWaitTimeout() [PUBLIC]
|
|
551
|
+
// Set the pool's wait timeout value.
|
|
552
|
+
//-----------------------------------------------------------------------------
|
|
553
|
+
int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value)
|
|
554
|
+
{
|
|
555
|
+
return dpiPool__setAttributeUint(pool, DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT,
|
|
556
|
+
value, __func__);
|
|
557
|
+
}
|
|
558
|
+
|
package/odpi/src/dpiStmt.c
CHANGED
|
@@ -22,7 +22,7 @@ static int dpiStmt__getQueryInfo(dpiStmt *stmt, uint32_t pos,
|
|
|
22
22
|
static int dpiStmt__getQueryInfoFromParam(dpiStmt *stmt, void *param,
|
|
23
23
|
dpiQueryInfo *info, dpiError *error);
|
|
24
24
|
static int dpiStmt__postFetch(dpiStmt *stmt, dpiError *error);
|
|
25
|
-
static int
|
|
25
|
+
static int dpiStmt__beforeFetch(dpiStmt *stmt, dpiError *error);
|
|
26
26
|
static int dpiStmt__reExecute(dpiStmt *stmt, uint32_t numIters,
|
|
27
27
|
uint32_t mode, dpiError *error);
|
|
28
28
|
|
|
@@ -184,18 +184,13 @@ static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, int addReference,
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
// bind object, if applicable
|
|
187
|
-
if (var->objectIndicator &&
|
|
187
|
+
if (var->buffer.objectIndicator &&
|
|
188
|
+
dpiOci__bindObject(var, bindHandle, error) < 0)
|
|
188
189
|
return DPI_FAILURE;
|
|
189
190
|
|
|
190
|
-
// setup dynamic bind, if applicable
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (dynamicBind) {
|
|
194
|
-
if (stmt->isReturning)
|
|
195
|
-
var->actualArraySize = 0;
|
|
196
|
-
if (dpiOci__bindDynamic(var, bindHandle, error) < 0)
|
|
197
|
-
return DPI_FAILURE;
|
|
198
|
-
}
|
|
191
|
+
// setup dynamic bind, if applicable
|
|
192
|
+
if (dynamicBind && dpiOci__bindDynamic(var, bindHandle, error) < 0)
|
|
193
|
+
return DPI_FAILURE;
|
|
199
194
|
|
|
200
195
|
return DPI_SUCCESS;
|
|
201
196
|
}
|
|
@@ -510,7 +505,7 @@ static int dpiStmt__define(dpiStmt *stmt, uint32_t pos, dpiVar *var,
|
|
|
510
505
|
}
|
|
511
506
|
|
|
512
507
|
// define objects, if applicable
|
|
513
|
-
if (var->objectIndicator && dpiOci__defineObject(var, defineHandle,
|
|
508
|
+
if (var->buffer.objectIndicator && dpiOci__defineObject(var, defineHandle,
|
|
514
509
|
error) < 0)
|
|
515
510
|
return DPI_FAILURE;
|
|
516
511
|
|
|
@@ -543,21 +538,28 @@ static int dpiStmt__execute(dpiStmt *stmt, uint32_t numIters,
|
|
|
543
538
|
// buffer structures
|
|
544
539
|
for (i = 0; i < stmt->numBindVars; i++) {
|
|
545
540
|
var = stmt->bindVars[i].var;
|
|
546
|
-
|
|
547
|
-
|
|
541
|
+
if (var->isArray && numIters > 1)
|
|
542
|
+
return dpiError__set(error, "bind array var",
|
|
543
|
+
DPI_ERR_ARRAY_VAR_NOT_SUPPORTED);
|
|
544
|
+
for (j = 0; j < var->buffer.maxArraySize; j++) {
|
|
545
|
+
data = &var->buffer.externalData[j];
|
|
548
546
|
if (var->type->oracleTypeNum == DPI_ORACLE_TYPE_STMT &&
|
|
549
547
|
data->value.asStmt == stmt)
|
|
550
548
|
return dpiError__set(error, "bind to self",
|
|
551
549
|
DPI_ERR_NOT_SUPPORTED);
|
|
552
|
-
if (dpiVar__setValue(var, j, data, error) < 0)
|
|
550
|
+
if (dpiVar__setValue(var, &var->buffer, j, data, error) < 0)
|
|
553
551
|
return DPI_FAILURE;
|
|
552
|
+
if (var->dynBindBuffers)
|
|
553
|
+
var->dynBindBuffers[j].actualArraySize = 0;
|
|
554
554
|
}
|
|
555
555
|
if (stmt->isReturning || var->isDynamic)
|
|
556
556
|
var->error = error;
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
-
// for queries, set the prefetch
|
|
560
|
-
//
|
|
559
|
+
// for queries, set the OCI prefetch to a fixed value; this prevents an
|
|
560
|
+
// additional round trip for single row fetches while avoiding the overhead
|
|
561
|
+
// of copying from the OCI prefetch buffer to our own buffers for larger
|
|
562
|
+
// fetches
|
|
561
563
|
if (stmt->statementType == DPI_STMT_TYPE_SELECT) {
|
|
562
564
|
prefetchSize = DPI_PREFETCH_ROWS_DEFAULT;
|
|
563
565
|
if (dpiOci__attrSet(stmt->handle, DPI_OCI_HTYPE_STMT, &prefetchSize,
|
|
@@ -595,9 +597,8 @@ static int dpiStmt__execute(dpiStmt *stmt, uint32_t numIters,
|
|
|
595
597
|
stmt->statementType == DPI_STMT_TYPE_CALL) {
|
|
596
598
|
for (i = 0; i < stmt->numBindVars; i++) {
|
|
597
599
|
var = stmt->bindVars[i].var;
|
|
598
|
-
for (j = 0; j < var->maxArraySize; j++) {
|
|
599
|
-
if (dpiVar__getValue(var,
|
|
600
|
-
error) < 0)
|
|
600
|
+
for (j = 0; j < var->buffer.maxArraySize; j++) {
|
|
601
|
+
if (dpiVar__getValue(var, &var->buffer, j, 0, error) < 0)
|
|
601
602
|
return DPI_FAILURE;
|
|
602
603
|
}
|
|
603
604
|
var->error = NULL;
|
|
@@ -606,6 +607,7 @@ static int dpiStmt__execute(dpiStmt *stmt, uint32_t numIters,
|
|
|
606
607
|
|
|
607
608
|
// create query variables (if applicable)
|
|
608
609
|
if (stmt->statementType == DPI_STMT_TYPE_SELECT &&
|
|
610
|
+
!(mode & DPI_MODE_EXEC_PARSE_ONLY) &&
|
|
609
611
|
dpiStmt__createQueryVars(stmt, error) < 0)
|
|
610
612
|
return DPI_FAILURE;
|
|
611
613
|
|
|
@@ -620,7 +622,7 @@ static int dpiStmt__execute(dpiStmt *stmt, uint32_t numIters,
|
|
|
620
622
|
static int dpiStmt__fetch(dpiStmt *stmt, dpiError *error)
|
|
621
623
|
{
|
|
622
624
|
// perform any pre-fetch activities required
|
|
623
|
-
if (
|
|
625
|
+
if (dpiStmt__beforeFetch(stmt, error) < 0)
|
|
624
626
|
return DPI_FAILURE;
|
|
625
627
|
|
|
626
628
|
// perform fetch
|
|
@@ -840,7 +842,7 @@ static int dpiStmt__postFetch(dpiStmt *stmt, dpiError *error)
|
|
|
840
842
|
for (i = 0; i < stmt->numQueryVars; i++) {
|
|
841
843
|
var = stmt->queryVars[i];
|
|
842
844
|
for (j = 0; j < stmt->bufferRowCount; j++) {
|
|
843
|
-
if (dpiVar__getValue(var,
|
|
845
|
+
if (dpiVar__getValue(var, &var->buffer, j, 1, error) < 0)
|
|
844
846
|
return DPI_FAILURE;
|
|
845
847
|
if (var->type->requiresPreFetch)
|
|
846
848
|
var->requiresPreFetch = 1;
|
|
@@ -853,13 +855,13 @@ static int dpiStmt__postFetch(dpiStmt *stmt, dpiError *error)
|
|
|
853
855
|
|
|
854
856
|
|
|
855
857
|
//-----------------------------------------------------------------------------
|
|
856
|
-
//
|
|
858
|
+
// dpiStmt__beforeFetch() [INTERNAL]
|
|
857
859
|
// Performs work that needs to be done prior to fetch for each variable. In
|
|
858
860
|
// addition, variables are created if they do not already exist. A check is
|
|
859
861
|
// also made to ensure that the variable has enough space to support a fetch
|
|
860
862
|
// of the requested size.
|
|
861
863
|
//-----------------------------------------------------------------------------
|
|
862
|
-
static int
|
|
864
|
+
static int dpiStmt__beforeFetch(dpiStmt *stmt, dpiError *error)
|
|
863
865
|
{
|
|
864
866
|
dpiQueryInfo *queryInfo;
|
|
865
867
|
dpiData *data;
|
|
@@ -883,10 +885,11 @@ static int dpiStmt__preFetch(dpiStmt *stmt, dpiError *error)
|
|
|
883
885
|
dpiGen__setRefCount(var, error, -1);
|
|
884
886
|
}
|
|
885
887
|
var->error = error;
|
|
886
|
-
if (stmt->fetchArraySize > var->maxArraySize)
|
|
888
|
+
if (stmt->fetchArraySize > var->buffer.maxArraySize)
|
|
887
889
|
return dpiError__set(error, "check array size",
|
|
888
|
-
DPI_ERR_ARRAY_SIZE_TOO_SMALL, var->maxArraySize);
|
|
889
|
-
if (var->requiresPreFetch && dpiVar__extendedPreFetch(var,
|
|
890
|
+
DPI_ERR_ARRAY_SIZE_TOO_SMALL, var->buffer.maxArraySize);
|
|
891
|
+
if (var->requiresPreFetch && dpiVar__extendedPreFetch(var,
|
|
892
|
+
&var->buffer, error) < 0)
|
|
890
893
|
return DPI_FAILURE;
|
|
891
894
|
}
|
|
892
895
|
|
|
@@ -949,7 +952,7 @@ static int dpiStmt__reExecute(dpiStmt *stmt, uint32_t numIters,
|
|
|
949
952
|
// so that it does not return with the invalid metadata; again, if this
|
|
950
953
|
// cannot be done, let the original error propagate
|
|
951
954
|
origHandle = stmt->handle;
|
|
952
|
-
status =
|
|
955
|
+
status = dpiOci__stmtPrepare2(stmt, sql, sqlLength, NULL, 0, &localError);
|
|
953
956
|
newHandle = stmt->handle;
|
|
954
957
|
stmt->handle = origHandle;
|
|
955
958
|
stmt->deleteFromCache = 1;
|
|
@@ -1197,13 +1200,25 @@ int dpiStmt_executeMany(dpiStmt *stmt, dpiExecMode mode, uint32_t numIters)
|
|
|
1197
1200
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
1198
1201
|
}
|
|
1199
1202
|
|
|
1203
|
+
// batch errors and array DML row counts are only supported with DML
|
|
1204
|
+
// statements (insert, update, delete and merge)
|
|
1205
|
+
if ((mode & DPI_MODE_EXEC_BATCH_ERRORS ||
|
|
1206
|
+
mode & DPI_MODE_EXEC_ARRAY_DML_ROWCOUNTS) &&
|
|
1207
|
+
stmt->statementType != DPI_STMT_TYPE_INSERT &&
|
|
1208
|
+
stmt->statementType != DPI_STMT_TYPE_UPDATE &&
|
|
1209
|
+
stmt->statementType != DPI_STMT_TYPE_DELETE &&
|
|
1210
|
+
stmt->statementType != DPI_STMT_TYPE_MERGE) {
|
|
1211
|
+
dpiError__set(&error, "check mode", DPI_ERR_EXEC_MODE_ONLY_FOR_DML);
|
|
1212
|
+
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1200
1215
|
// ensure that all bind variables have a big enough maxArraySize to
|
|
1201
1216
|
// support this operation
|
|
1202
1217
|
for (i = 0; i < stmt->numBindVars; i++) {
|
|
1203
|
-
if (stmt->bindVars[i].var->maxArraySize < numIters) {
|
|
1218
|
+
if (stmt->bindVars[i].var->buffer.maxArraySize < numIters) {
|
|
1204
1219
|
dpiError__set(&error, "check array size",
|
|
1205
1220
|
DPI_ERR_ARRAY_SIZE_TOO_SMALL,
|
|
1206
|
-
stmt->bindVars[i].var->maxArraySize);
|
|
1221
|
+
stmt->bindVars[i].var->buffer.maxArraySize);
|
|
1207
1222
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
1208
1223
|
}
|
|
1209
1224
|
}
|
|
@@ -1564,15 +1579,16 @@ int dpiStmt_getQueryValue(dpiStmt *stmt, uint32_t pos,
|
|
|
1564
1579
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
1565
1580
|
}
|
|
1566
1581
|
*nativeTypeNum = var->nativeTypeNum;
|
|
1567
|
-
*data = &var->externalData[stmt->bufferRowIndex - 1];
|
|
1582
|
+
*data = &var->buffer.externalData[stmt->bufferRowIndex - 1];
|
|
1568
1583
|
return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error);
|
|
1569
1584
|
}
|
|
1570
1585
|
|
|
1571
1586
|
|
|
1572
1587
|
//-----------------------------------------------------------------------------
|
|
1573
1588
|
// dpiStmt_getRowCount() [PUBLIC]
|
|
1574
|
-
// Return the number of rows affected by the last
|
|
1575
|
-
// update
|
|
1589
|
+
// Return the number of rows affected by the last DML executed (for insert,
|
|
1590
|
+
// update, delete and merge) or the number of rows fetched (for queries). In
|
|
1591
|
+
// all other cases, 0 is returned.
|
|
1576
1592
|
//-----------------------------------------------------------------------------
|
|
1577
1593
|
int dpiStmt_getRowCount(dpiStmt *stmt, uint64_t *count)
|
|
1578
1594
|
{
|
|
@@ -1584,7 +1600,12 @@ int dpiStmt_getRowCount(dpiStmt *stmt, uint64_t *count)
|
|
|
1584
1600
|
DPI_CHECK_PTR_NOT_NULL(stmt, count)
|
|
1585
1601
|
if (stmt->statementType == DPI_STMT_TYPE_SELECT)
|
|
1586
1602
|
*count = stmt->rowCount;
|
|
1587
|
-
else if (stmt->
|
|
1603
|
+
else if (stmt->statementType != DPI_STMT_TYPE_INSERT &&
|
|
1604
|
+
stmt->statementType != DPI_STMT_TYPE_UPDATE &&
|
|
1605
|
+
stmt->statementType != DPI_STMT_TYPE_DELETE &&
|
|
1606
|
+
stmt->statementType != DPI_STMT_TYPE_MERGE) {
|
|
1607
|
+
*count = 0;
|
|
1608
|
+
} else if (stmt->env->versionInfo->versionNum < 12) {
|
|
1588
1609
|
if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, &rowCount32, 0,
|
|
1589
1610
|
DPI_OCI_ATTR_ROW_COUNT, "get row count", &error) < 0)
|
|
1590
1611
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
@@ -1703,7 +1724,7 @@ int dpiStmt_scroll(dpiStmt *stmt, dpiFetchMode mode, int32_t offset,
|
|
|
1703
1724
|
}
|
|
1704
1725
|
|
|
1705
1726
|
// perform any pre-fetch activities required
|
|
1706
|
-
if (
|
|
1727
|
+
if (dpiStmt__beforeFetch(stmt, &error) < 0)
|
|
1707
1728
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
|
1708
1729
|
|
|
1709
1730
|
// perform fetch; when fetching the last row, only fetch a single row
|
|
@@ -1767,7 +1788,7 @@ int dpiStmt_setFetchArraySize(dpiStmt *stmt, uint32_t arraySize)
|
|
|
1767
1788
|
arraySize = DPI_DEFAULT_FETCH_ARRAY_SIZE;
|
|
1768
1789
|
for (i = 0; i < stmt->numQueryVars; i++) {
|
|
1769
1790
|
var = stmt->queryVars[i];
|
|
1770
|
-
if (var && var->maxArraySize < arraySize) {
|
|
1791
|
+
if (var && var->buffer.maxArraySize < arraySize) {
|
|
1771
1792
|
dpiError__set(&error, "check array size",
|
|
1772
1793
|
DPI_ERR_ARRAY_SIZE_TOO_BIG, arraySize);
|
|
1773
1794
|
return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error);
|
package/odpi/src/dpiSubscr.c
CHANGED
|
@@ -50,6 +50,7 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle,
|
|
|
50
50
|
dpiError__getInfo(&error, &errorInfo);
|
|
51
51
|
message.errorInfo = &errorInfo;
|
|
52
52
|
}
|
|
53
|
+
message.registered = subscr->registered;
|
|
53
54
|
|
|
54
55
|
// invoke user callback
|
|
55
56
|
(*subscr->callback)(subscr->callbackContext, &message);
|
|
@@ -60,6 +61,23 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle,
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
|
|
64
|
+
//-----------------------------------------------------------------------------
|
|
65
|
+
// dpiSubscr__checkOpen() [INTERNAL]
|
|
66
|
+
// Determine if the subscription is open and available for use.
|
|
67
|
+
//-----------------------------------------------------------------------------
|
|
68
|
+
static int dpiSubscr__checkOpen(dpiSubscr *subscr, const char *fnName,
|
|
69
|
+
dpiError *error)
|
|
70
|
+
{
|
|
71
|
+
if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, fnName, 1, error) < 0)
|
|
72
|
+
return DPI_FAILURE;
|
|
73
|
+
if (!subscr->handle)
|
|
74
|
+
return dpiError__set(error, "check closed", DPI_ERR_SUBSCR_CLOSED);
|
|
75
|
+
if (!subscr->conn->handle || subscr->conn->closing)
|
|
76
|
+
return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED);
|
|
77
|
+
return DPI_SUCCESS;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
63
81
|
//-----------------------------------------------------------------------------
|
|
64
82
|
// dpiSubscr__create() [INTERNAL]
|
|
65
83
|
// Create a new subscription structure and return it. In case of error NULL
|
|
@@ -69,6 +87,7 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn,
|
|
|
69
87
|
dpiSubscrCreateParams *params, uint64_t *subscrId, dpiError *error)
|
|
70
88
|
{
|
|
71
89
|
uint32_t qosFlags;
|
|
90
|
+
int32_t int32Val;
|
|
72
91
|
int rowids;
|
|
73
92
|
|
|
74
93
|
// retain a reference to the connection
|
|
@@ -76,6 +95,7 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn,
|
|
|
76
95
|
subscr->conn = conn;
|
|
77
96
|
subscr->callback = params->callback;
|
|
78
97
|
subscr->callbackContext = params->callbackContext;
|
|
98
|
+
subscr->subscrNamespace = params->subscrNamespace;
|
|
79
99
|
subscr->qos = params->qos;
|
|
80
100
|
|
|
81
101
|
// create the subscription handle
|
|
@@ -101,6 +121,13 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn,
|
|
|
101
121
|
DPI_OCI_ATTR_SUBSCR_TIMEOUT, "set timeout", error) < 0)
|
|
102
122
|
return DPI_FAILURE;
|
|
103
123
|
|
|
124
|
+
// set the IP address used on the client to listen for events
|
|
125
|
+
if (params->ipAddress && params->ipAddressLength > 0 &&
|
|
126
|
+
dpiOci__attrSet(subscr->env->handle, DPI_OCI_HTYPE_ENV,
|
|
127
|
+
(void*) params->ipAddress, params->ipAddressLength,
|
|
128
|
+
DPI_OCI_ATTR_SUBSCR_IPADDR, "set IP address", error) < 0)
|
|
129
|
+
return DPI_FAILURE;
|
|
130
|
+
|
|
104
131
|
// set the port number used on the client to listen for events
|
|
105
132
|
if (params->portNumber > 0 && dpiOci__attrSet(subscr->env->handle,
|
|
106
133
|
DPI_OCI_HTYPE_ENV, (void*) ¶ms->portNumber, 0,
|
|
@@ -163,9 +190,44 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn,
|
|
|
163
190
|
DPI_OCI_ATTR_CHNF_OPERATIONS, "set operations", error) < 0)
|
|
164
191
|
return DPI_FAILURE;
|
|
165
192
|
|
|
193
|
+
// set grouping information, if applicable
|
|
194
|
+
if (params->groupingClass) {
|
|
195
|
+
|
|
196
|
+
// set grouping class
|
|
197
|
+
if (dpiOci__attrSet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION,
|
|
198
|
+
(void*) ¶ms->groupingClass, 0,
|
|
199
|
+
DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_CLASS, "set grouping class",
|
|
200
|
+
error) < 0)
|
|
201
|
+
return DPI_FAILURE;
|
|
202
|
+
|
|
203
|
+
// set grouping value
|
|
204
|
+
if (dpiOci__attrSet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION,
|
|
205
|
+
(void*) ¶ms->groupingValue, 0,
|
|
206
|
+
DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_VALUE, "set grouping value",
|
|
207
|
+
error) < 0)
|
|
208
|
+
return DPI_FAILURE;
|
|
209
|
+
|
|
210
|
+
// set grouping type
|
|
211
|
+
if (dpiOci__attrSet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION,
|
|
212
|
+
(void*) ¶ms->groupingType, 0,
|
|
213
|
+
DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_TYPE, "set grouping type",
|
|
214
|
+
error) < 0)
|
|
215
|
+
return DPI_FAILURE;
|
|
216
|
+
|
|
217
|
+
// set grouping repeat count
|
|
218
|
+
int32Val = DPI_SUBSCR_GROUPING_FOREVER;
|
|
219
|
+
if (dpiOci__attrSet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION,
|
|
220
|
+
(void*) &int32Val, 0,
|
|
221
|
+
DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_REPEAT_COUNT,
|
|
222
|
+
"set grouping repeat count", error) < 0)
|
|
223
|
+
return DPI_FAILURE;
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
166
227
|
// register the subscription
|
|
167
228
|
if (dpiOci__subscriptionRegister(conn, &subscr->handle, error) < 0)
|
|
168
229
|
return DPI_FAILURE;
|
|
230
|
+
subscr->registered = 1;
|
|
169
231
|
|
|
170
232
|
// get the registration id, if applicable
|
|
171
233
|
if (subscrId && dpiOci__attrGet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION,
|
|
@@ -184,7 +246,9 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn,
|
|
|
184
246
|
void dpiSubscr__free(dpiSubscr *subscr, dpiError *error)
|
|
185
247
|
{
|
|
186
248
|
if (subscr->handle) {
|
|
187
|
-
|
|
249
|
+
if (subscr->registered)
|
|
250
|
+
dpiOci__subscriptionUnRegister(subscr->conn, subscr, error);
|
|
251
|
+
dpiOci__handleFree(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION);
|
|
188
252
|
subscr->handle = NULL;
|
|
189
253
|
}
|
|
190
254
|
if (subscr->conn) {
|
|
@@ -230,6 +294,41 @@ static void dpiSubscr__freeMessage(dpiSubscrMessage *message)
|
|
|
230
294
|
}
|
|
231
295
|
|
|
232
296
|
|
|
297
|
+
//-----------------------------------------------------------------------------
|
|
298
|
+
// dpiSubscr__populateAQMessage() [INTERNAL]
|
|
299
|
+
// Populate message with details.
|
|
300
|
+
//-----------------------------------------------------------------------------
|
|
301
|
+
static int dpiSubscr__populateAQMessage(dpiSubscr *subscr,
|
|
302
|
+
dpiSubscrMessage *message, void *descriptor, dpiError *error)
|
|
303
|
+
{
|
|
304
|
+
uint32_t flags = 0;
|
|
305
|
+
|
|
306
|
+
// determine if message is a deregistration message
|
|
307
|
+
if (dpiOci__attrGet(descriptor, DPI_OCI_DTYPE_AQNFY_DESCRIPTOR, &flags,
|
|
308
|
+
NULL, DPI_OCI_ATTR_NFY_FLAGS, "get flags", error) < 0)
|
|
309
|
+
return DPI_FAILURE;
|
|
310
|
+
message->eventType = (flags == 1) ? DPI_EVENT_DEREG : DPI_EVENT_AQ;
|
|
311
|
+
if (message->eventType == DPI_EVENT_DEREG) {
|
|
312
|
+
subscr->registered = 0;
|
|
313
|
+
return DPI_SUCCESS;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// determine the name of the queue which spawned the event
|
|
317
|
+
if (dpiOci__attrGet(descriptor, DPI_OCI_DTYPE_AQNFY_DESCRIPTOR,
|
|
318
|
+
(void*) &message->queueName, &message->queueNameLength,
|
|
319
|
+
DPI_OCI_ATTR_QUEUE_NAME, "get queue name", error) < 0)
|
|
320
|
+
return DPI_FAILURE;
|
|
321
|
+
|
|
322
|
+
// determine the consumer name for the queue that spawned the event
|
|
323
|
+
if (dpiOci__attrGet(descriptor, DPI_OCI_DTYPE_AQNFY_DESCRIPTOR,
|
|
324
|
+
(void*) &message->consumerName, &message->consumerNameLength,
|
|
325
|
+
DPI_OCI_ATTR_CONSUMER_NAME, "get consumer name", error) < 0)
|
|
326
|
+
return DPI_FAILURE;
|
|
327
|
+
|
|
328
|
+
return DPI_SUCCESS;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
233
332
|
//-----------------------------------------------------------------------------
|
|
234
333
|
// dpiSubscr__populateObjectChangeMessage() [INTERNAL]
|
|
235
334
|
// Populate object change message with details.
|
|
@@ -284,6 +383,17 @@ static int dpiSubscr__populateMessage(dpiSubscr *subscr,
|
|
|
284
383
|
{
|
|
285
384
|
void *rawValue;
|
|
286
385
|
|
|
386
|
+
// if quality of service flag indicates that deregistration should take
|
|
387
|
+
// place when the first notification is received, mark the subscription
|
|
388
|
+
// as no longer registered
|
|
389
|
+
if (subscr->qos & DPI_SUBSCR_QOS_DEREG_NFY)
|
|
390
|
+
subscr->registered = 0;
|
|
391
|
+
|
|
392
|
+
// handle AQ messages, if applicable
|
|
393
|
+
if (subscr->subscrNamespace == DPI_SUBSCR_NAMESPACE_AQ)
|
|
394
|
+
return dpiSubscr__populateAQMessage(subscr, message, descriptor,
|
|
395
|
+
error);
|
|
396
|
+
|
|
287
397
|
// determine the type of event that was spawned
|
|
288
398
|
if (dpiOci__attrGet(descriptor, DPI_OCI_DTYPE_CHDES, &message->eventType,
|
|
289
399
|
NULL, DPI_OCI_ATTR_CHDES_NFYTYPE, "get event type", error) < 0)
|
|
@@ -311,7 +421,7 @@ static int dpiSubscr__populateMessage(dpiSubscr *subscr,
|
|
|
311
421
|
return dpiSubscr__populateQueryChangeMessage(subscr, message,
|
|
312
422
|
descriptor, error);
|
|
313
423
|
case DPI_EVENT_DEREG:
|
|
314
|
-
subscr->
|
|
424
|
+
subscr->registered = 0;
|
|
315
425
|
break;
|
|
316
426
|
default:
|
|
317
427
|
return dpiError__set(error, "event type", DPI_ERR_NOT_SUPPORTED);
|
|
@@ -543,13 +653,12 @@ int dpiSubscr_close(dpiSubscr *subscr)
|
|
|
543
653
|
{
|
|
544
654
|
dpiError error;
|
|
545
655
|
|
|
546
|
-
if (
|
|
547
|
-
&error) < 0)
|
|
656
|
+
if (dpiSubscr__checkOpen(subscr, __func__, &error) < 0)
|
|
548
657
|
return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error);
|
|
549
|
-
if (subscr->
|
|
550
|
-
if (dpiOci__subscriptionUnRegister(subscr, &error) < 0)
|
|
658
|
+
if (subscr->registered) {
|
|
659
|
+
if (dpiOci__subscriptionUnRegister(subscr->conn, subscr, &error) < 0)
|
|
551
660
|
return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error);
|
|
552
|
-
subscr->
|
|
661
|
+
subscr->registered = 0;
|
|
553
662
|
}
|
|
554
663
|
|
|
555
664
|
return dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error);
|
|
@@ -566,8 +675,7 @@ int dpiSubscr_prepareStmt(dpiSubscr *subscr, const char *sql,
|
|
|
566
675
|
dpiStmt *tempStmt;
|
|
567
676
|
dpiError error;
|
|
568
677
|
|
|
569
|
-
if (
|
|
570
|
-
&error) < 0)
|
|
678
|
+
if (dpiSubscr__checkOpen(subscr, __func__, &error) < 0)
|
|
571
679
|
return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error);
|
|
572
680
|
DPI_CHECK_PTR_NOT_NULL(subscr, sql)
|
|
573
681
|
DPI_CHECK_PTR_NOT_NULL(subscr, stmt)
|