oracledb 3.0.0 → 3.1.2

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +135 -8
  2. package/README.md +6 -4
  3. package/build/Release/oracledb-abi48-darwin-x64.node +0 -0
  4. package/build/Release/oracledb-abi48-darwin-x64.node-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-abi48-linux-x64.node +0 -0
  6. package/build/Release/oracledb-abi48-linux-x64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-abi48-win32-x64.node +0 -0
  8. package/build/Release/oracledb-abi48-win32-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-abi57-darwin-x64.node +0 -0
  10. package/build/Release/oracledb-abi57-darwin-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-abi57-linux-x64.node +0 -0
  12. package/build/Release/oracledb-abi57-linux-x64.node-buildinfo.txt +1 -0
  13. package/build/Release/oracledb-abi57-win32-x64.node +0 -0
  14. package/build/Release/oracledb-abi57-win32-x64.node-buildinfo.txt +1 -0
  15. package/build/Release/oracledb-abi64-darwin-x64.node +0 -0
  16. package/build/Release/oracledb-abi64-darwin-x64.node-buildinfo.txt +1 -0
  17. package/build/Release/oracledb-abi64-linux-x64.node +0 -0
  18. package/build/Release/oracledb-abi64-linux-x64.node-buildinfo.txt +1 -0
  19. package/build/Release/oracledb-abi64-win32-x64.node +0 -0
  20. package/build/Release/oracledb-abi64-win32-x64.node-buildinfo.txt +1 -0
  21. package/build/Release/oracledb-abi67-darwin-x64.node +0 -0
  22. package/build/Release/oracledb-abi67-darwin-x64.node-buildinfo.txt +1 -0
  23. package/build/Release/oracledb-abi67-linux-x64.node +0 -0
  24. package/build/Release/oracledb-abi67-linux-x64.node-buildinfo.txt +1 -0
  25. package/build/Release/oracledb-abi67-win32-x64.node +0 -0
  26. package/build/Release/oracledb-abi67-win32-x64.node-buildinfo.txt +1 -0
  27. package/lib/connection.js +18 -4
  28. package/lib/oracledb.js +44 -92
  29. package/lib/pool.js +36 -2
  30. package/lib/sodaCollection.js +1 -1
  31. package/lib/sodaDatabase.js +1 -1
  32. package/lib/util.js +82 -5
  33. package/package/README.md +32 -101
  34. package/package/install.js +139 -0
  35. package/package/prunebinaries.js +51 -0
  36. package/package.json +4 -11
  37. package/binding.gyp +0 -162
  38. package/lib/rel.txt +0 -1
  39. package/odpi/.npmignore +0 -4
  40. package/odpi/LICENSE.md +0 -218
  41. package/odpi/README.md +0 -61
  42. package/odpi/embed/README.md +0 -4
  43. package/odpi/embed/dpi.c +0 -50
  44. package/odpi/include/dpi.h +0 -1748
  45. package/odpi/src/dpiConn.c +0 -2089
  46. package/odpi/src/dpiContext.c +0 -296
  47. package/odpi/src/dpiData.c +0 -797
  48. package/odpi/src/dpiDebug.c +0 -184
  49. package/odpi/src/dpiDeqOptions.c +0 -370
  50. package/odpi/src/dpiEnqOptions.c +0 -174
  51. package/odpi/src/dpiEnv.c +0 -189
  52. package/odpi/src/dpiError.c +0 -204
  53. package/odpi/src/dpiErrorMessages.h +0 -86
  54. package/odpi/src/dpiGen.c +0 -303
  55. package/odpi/src/dpiGlobal.c +0 -292
  56. package/odpi/src/dpiHandleList.c +0 -117
  57. package/odpi/src/dpiHandlePool.c +0 -118
  58. package/odpi/src/dpiImpl.h +0 -1707
  59. package/odpi/src/dpiLob.c +0 -506
  60. package/odpi/src/dpiMsgProps.c +0 -386
  61. package/odpi/src/dpiObject.c +0 -897
  62. package/odpi/src/dpiObjectAttr.c +0 -115
  63. package/odpi/src/dpiObjectType.c +0 -326
  64. package/odpi/src/dpiOci.c +0 -3527
  65. package/odpi/src/dpiOracleType.c +0 -492
  66. package/odpi/src/dpiPool.c +0 -549
  67. package/odpi/src/dpiRowid.c +0 -136
  68. package/odpi/src/dpiSodaColl.c +0 -685
  69. package/odpi/src/dpiSodaCollCursor.c +0 -143
  70. package/odpi/src/dpiSodaDb.c +0 -432
  71. package/odpi/src/dpiSodaDoc.c +0 -230
  72. package/odpi/src/dpiSodaDocCursor.c +0 -143
  73. package/odpi/src/dpiStmt.c +0 -1797
  74. package/odpi/src/dpiSubscr.c +0 -674
  75. package/odpi/src/dpiUtils.c +0 -410
  76. package/odpi/src/dpiVar.c +0 -1794
  77. package/package/MAKEPKG.BAT +0 -156
  78. package/package/Makefile +0 -85
  79. package/package/createpackage.js +0 -186
  80. package/package/extractpackage.js +0 -76
  81. package/package/getversion.js +0 -37
  82. package/package/oracledbinstall.js +0 -497
  83. package/package/package.json +0 -54
  84. package/package/util.js +0 -286
  85. package/src/njsCommon.cpp +0 -1055
  86. package/src/njsCommon.h +0 -484
  87. package/src/njsConnection.cpp +0 -2926
  88. package/src/njsConnection.h +0 -227
  89. package/src/njsIntLob.cpp +0 -618
  90. package/src/njsIntLob.h +0 -179
  91. package/src/njsMessages.cpp +0 -122
  92. package/src/njsMessages.h +0 -118
  93. package/src/njsOracle.cpp +0 -1274
  94. package/src/njsOracle.h +0 -237
  95. package/src/njsPool.cpp +0 -482
  96. package/src/njsPool.h +0 -132
  97. package/src/njsResultSet.cpp +0 -478
  98. package/src/njsResultSet.h +0 -120
  99. package/src/njsSodaCollection.cpp +0 -507
  100. package/src/njsSodaCollection.h +0 -128
  101. package/src/njsSodaDatabase.cpp +0 -335
  102. package/src/njsSodaDatabase.h +0 -108
  103. package/src/njsSodaDocCursor.cpp +0 -203
  104. package/src/njsSodaDocCursor.h +0 -94
  105. package/src/njsSodaDocument.cpp +0 -412
  106. package/src/njsSodaDocument.h +0 -105
  107. package/src/njsSodaOperation.cpp +0 -557
  108. package/src/njsSodaOperation.h +0 -123
  109. package/src/njsSubscription.cpp +0 -388
  110. package/src/njsSubscription.h +0 -111
  111. package/src/njsUtils.cpp +0 -158
  112. package/src/njsUtils.h +0 -68
package/odpi/src/dpiVar.c DELETED
@@ -1,1794 +0,0 @@
1
- //-----------------------------------------------------------------------------
2
- // Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3
- // This program is free software: you can modify it and/or redistribute it
4
- // under the terms of:
5
- //
6
- // (i) the Universal Permissive License v 1.0 or at your option, any
7
- // later version (http://oss.oracle.com/licenses/upl); and/or
8
- //
9
- // (ii) the Apache License v 2.0. (http://www.apache.org/licenses/LICENSE-2.0)
10
- //-----------------------------------------------------------------------------
11
-
12
- //-----------------------------------------------------------------------------
13
- // dpiVar.c
14
- // Implementation of variables.
15
- //-----------------------------------------------------------------------------
16
-
17
- #include "dpiImpl.h"
18
-
19
- // forward declarations of internal functions only used in this file
20
- static int dpiVar__initBuffer(dpiVar *var, dpiVarBuffer *buffer,
21
- dpiError *error);
22
- static int dpiVar__setBytesFromDynamicBytes(dpiBytes *bytes,
23
- dpiDynamicBytes *dynBytes, dpiError *error);
24
- static int dpiVar__setBytesFromLob(dpiBytes *bytes, dpiDynamicBytes *dynBytes,
25
- dpiLob *lob, dpiError *error);
26
- static int dpiVar__setFromBytes(dpiVar *var, uint32_t pos, const char *value,
27
- uint32_t valueLength, dpiError *error);
28
- static int dpiVar__setFromLob(dpiVar *var, uint32_t pos, dpiLob *lob,
29
- dpiError *error);
30
- static int dpiVar__setFromObject(dpiVar *var, uint32_t pos, dpiObject *obj,
31
- dpiError *error);
32
- static int dpiVar__setFromRowid(dpiVar *var, uint32_t pos, dpiRowid *rowid,
33
- dpiError *error);
34
- static int dpiVar__setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt,
35
- dpiError *error);
36
- static int dpiVar__validateTypes(const dpiOracleType *oracleType,
37
- dpiNativeTypeNum nativeTypeNum, dpiError *error);
38
-
39
-
40
- //-----------------------------------------------------------------------------
41
- // dpiVar__allocate() [INTERNAL]
42
- // Create a new variable object and return it. In case of error NULL is
43
- // returned.
44
- //-----------------------------------------------------------------------------
45
- int dpiVar__allocate(dpiConn *conn, dpiOracleTypeNum oracleTypeNum,
46
- dpiNativeTypeNum nativeTypeNum, uint32_t maxArraySize, uint32_t size,
47
- int sizeIsBytes, int isArray, dpiObjectType *objType, dpiVar **var,
48
- dpiData **data, dpiError *error)
49
- {
50
- const dpiOracleType *type;
51
- uint32_t sizeInBytes;
52
- dpiVar *tempVar;
53
-
54
- // validate arguments
55
- *var = NULL;
56
- type = dpiOracleType__getFromNum(oracleTypeNum, error);
57
- if (!type)
58
- return DPI_FAILURE;
59
- if (maxArraySize == 0)
60
- return dpiError__set(error, "check max array size",
61
- DPI_ERR_ARRAY_SIZE_ZERO);
62
- if (isArray && !type->canBeInArray)
63
- return dpiError__set(error, "check can be in array",
64
- DPI_ERR_NOT_SUPPORTED);
65
- if (oracleTypeNum == DPI_ORACLE_TYPE_BOOLEAN &&
66
- dpiUtils__checkClientVersion(conn->env->versionInfo, 12, 1,
67
- error) < 0)
68
- return DPI_FAILURE;
69
- if (nativeTypeNum != type->defaultNativeTypeNum) {
70
- if (dpiVar__validateTypes(type, nativeTypeNum, error) < 0)
71
- return DPI_FAILURE;
72
- }
73
-
74
- // calculate size in bytes
75
- if (size == 0)
76
- size = 1;
77
- if (type->sizeInBytes)
78
- sizeInBytes = type->sizeInBytes;
79
- else if (sizeIsBytes || !type->isCharacterData)
80
- sizeInBytes = size;
81
- else if (type->charsetForm == DPI_SQLCS_IMPLICIT)
82
- sizeInBytes = size * conn->env->maxBytesPerCharacter;
83
- else sizeInBytes = size * conn->env->nmaxBytesPerCharacter;
84
-
85
- // allocate memory for variable type
86
- if (dpiGen__allocate(DPI_HTYPE_VAR, conn->env, (void**) &tempVar,
87
- error) < 0)
88
- return DPI_FAILURE;
89
-
90
- // basic initialization
91
- tempVar->buffer.maxArraySize = maxArraySize;
92
- if (!isArray)
93
- tempVar->buffer.actualArraySize = maxArraySize;
94
- tempVar->sizeInBytes = sizeInBytes;
95
- if (sizeInBytes > DPI_MAX_BASIC_BUFFER_SIZE) {
96
- tempVar->sizeInBytes = 0;
97
- tempVar->isDynamic = 1;
98
- tempVar->requiresPreFetch = 1;
99
- }
100
- tempVar->type = type;
101
- tempVar->nativeTypeNum = nativeTypeNum;
102
- tempVar->isArray = isArray;
103
- dpiGen__setRefCount(conn, error, 1);
104
- tempVar->conn = conn;
105
- if (objType) {
106
- if (dpiGen__checkHandle(objType, DPI_HTYPE_OBJECT_TYPE,
107
- "check object type", error) < 0) {
108
- dpiVar__free(tempVar, error);
109
- return DPI_FAILURE;
110
- }
111
- dpiGen__setRefCount(objType, error, 1);
112
- tempVar->objectType = objType;
113
- }
114
-
115
- // allocate the data for the variable
116
- if (dpiVar__initBuffer(tempVar, &tempVar->buffer, error) < 0) {
117
- dpiVar__free(tempVar, error);
118
- return DPI_FAILURE;
119
- }
120
-
121
- *var = tempVar;
122
- *data = tempVar->buffer.externalData;
123
- return DPI_SUCCESS;
124
- }
125
-
126
-
127
- //-----------------------------------------------------------------------------
128
- // dpiVar__allocateChunks() [INTERNAL]
129
- // Allocate more chunks for handling dynamic bytes.
130
- //-----------------------------------------------------------------------------
131
- static int dpiVar__allocateChunks(dpiDynamicBytes *dynBytes, dpiError *error)
132
- {
133
- dpiDynamicBytesChunk *chunks;
134
- uint32_t allocatedChunks;
135
-
136
- allocatedChunks = dynBytes->allocatedChunks + 8;
137
- if (dpiUtils__allocateMemory(allocatedChunks, sizeof(dpiDynamicBytesChunk),
138
- 1, "allocate chunks", (void**) &chunks, error) < 0)
139
- return DPI_FAILURE;
140
- if (dynBytes->chunks) {
141
- memcpy(chunks, dynBytes->chunks,
142
- dynBytes->numChunks * sizeof(dpiDynamicBytesChunk));
143
- dpiUtils__freeMemory(dynBytes->chunks);
144
- }
145
- dynBytes->chunks = chunks;
146
- dynBytes->allocatedChunks = allocatedChunks;
147
- return DPI_SUCCESS;
148
- }
149
-
150
-
151
- //-----------------------------------------------------------------------------
152
- // dpiVar__allocateDynamicBytes() [INTERNAL]
153
- // Allocate space in the dynamic bytes structure for the specified number of
154
- // bytes. When complete, there will be exactly one allocated chunk of the
155
- // specified size or greater in the dynamic bytes structure.
156
- //-----------------------------------------------------------------------------
157
- static int dpiVar__allocateDynamicBytes(dpiDynamicBytes *dynBytes,
158
- uint32_t size, dpiError *error)
159
- {
160
- // if an error occurs, none of the original space is valid
161
- dynBytes->numChunks = 0;
162
-
163
- // if there are no chunks at all, make sure some exist
164
- if (dynBytes->allocatedChunks == 0 &&
165
- dpiVar__allocateChunks(dynBytes, error) < 0)
166
- return DPI_FAILURE;
167
-
168
- // at this point there should be 0 or 1 chunks as any retrieval that
169
- // resulted in multiple chunks would have been consolidated already
170
- // make sure that chunk has enough space in it
171
- if (size > dynBytes->chunks->allocatedLength) {
172
- if (dynBytes->chunks->ptr)
173
- dpiUtils__freeMemory(dynBytes->chunks->ptr);
174
- dynBytes->chunks->allocatedLength =
175
- (size + DPI_DYNAMIC_BYTES_CHUNK_SIZE - 1) &
176
- ~(DPI_DYNAMIC_BYTES_CHUNK_SIZE - 1);
177
- if (dpiUtils__allocateMemory(1, dynBytes->chunks->allocatedLength, 0,
178
- "allocate chunk", (void**) &dynBytes->chunks->ptr, error) < 0)
179
- return DPI_FAILURE;
180
- }
181
-
182
- return DPI_SUCCESS;
183
- }
184
-
185
-
186
- //-----------------------------------------------------------------------------
187
- // dpiVar__assignCallbackBuffer() [INTERNAL]
188
- // Assign callback pointers during OCI statement execution. This is used with
189
- // the callack functions used for dynamic binding during DML returning
190
- // statement execution.
191
- //-----------------------------------------------------------------------------
192
- static void dpiVar__assignCallbackBuffer(dpiVar *var, dpiVarBuffer *buffer,
193
- uint32_t index, void **bufpp)
194
- {
195
- switch (var->type->oracleTypeNum) {
196
- case DPI_ORACLE_TYPE_TIMESTAMP:
197
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
198
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
199
- *bufpp = buffer->data.asTimestamp[index];
200
- break;
201
- case DPI_ORACLE_TYPE_INTERVAL_DS:
202
- case DPI_ORACLE_TYPE_INTERVAL_YM:
203
- *bufpp = buffer->data.asInterval[index];
204
- break;
205
- case DPI_ORACLE_TYPE_CLOB:
206
- case DPI_ORACLE_TYPE_BLOB:
207
- case DPI_ORACLE_TYPE_NCLOB:
208
- case DPI_ORACLE_TYPE_BFILE:
209
- *bufpp = buffer->data.asLobLocator[index];
210
- break;
211
- case DPI_ORACLE_TYPE_ROWID:
212
- *bufpp = buffer->data.asRowid[index];
213
- break;
214
- case DPI_ORACLE_TYPE_STMT:
215
- *bufpp = buffer->data.asStmt[index];
216
- break;
217
- default:
218
- *bufpp = buffer->data.asBytes + index * var->sizeInBytes;
219
- break;
220
- }
221
- }
222
-
223
-
224
- //-----------------------------------------------------------------------------
225
- // dpiVar__checkArraySize() [INTERNAL]
226
- // Verifies that the array size has not been exceeded.
227
- //-----------------------------------------------------------------------------
228
- static int dpiVar__checkArraySize(dpiVar *var, uint32_t pos,
229
- const char *fnName, int needErrorHandle, dpiError *error)
230
- {
231
- if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, fnName, needErrorHandle,
232
- error) < 0)
233
- return DPI_FAILURE;
234
- if (pos >= var->buffer.maxArraySize)
235
- return dpiError__set(error, "check array size",
236
- DPI_ERR_INVALID_ARRAY_POSITION, pos,
237
- var->buffer.maxArraySize);
238
- return DPI_SUCCESS;
239
- }
240
-
241
-
242
- //-----------------------------------------------------------------------------
243
- // dpiVar__convertToLob() [INTERNAL]
244
- // Convert the variable from using dynamic bytes for a long string to using a
245
- // LOB instead. This is needed for PL/SQL which cannot handle more than 32K
246
- // without the use of a LOB.
247
- //-----------------------------------------------------------------------------
248
- int dpiVar__convertToLob(dpiVar *var, dpiError *error)
249
- {
250
- dpiDynamicBytes *dynBytes;
251
- dpiLob *lob;
252
- uint32_t i;
253
-
254
- // change type based on the original Oracle type
255
- if (var->type->oracleTypeNum == DPI_ORACLE_TYPE_RAW ||
256
- var->type->oracleTypeNum == DPI_ORACLE_TYPE_LONG_RAW)
257
- var->type = dpiOracleType__getFromNum(DPI_ORACLE_TYPE_BLOB, error);
258
- else if (var->type->oracleTypeNum == DPI_ORACLE_TYPE_NCHAR)
259
- var->type = dpiOracleType__getFromNum(DPI_ORACLE_TYPE_NCLOB,
260
- error);
261
- else var->type = dpiOracleType__getFromNum(DPI_ORACLE_TYPE_CLOB,
262
- error);
263
-
264
- // adjust attributes and re-initialize buffers
265
- // the dynamic bytes structures will not be removed
266
- var->sizeInBytes = var->type->sizeInBytes;
267
- var->isDynamic = 0;
268
- if (dpiVar__initBuffer(var, &var->buffer, error) < 0)
269
- return DPI_FAILURE;
270
-
271
- // copy any values already set
272
- for (i = 0; i < var->buffer.maxArraySize; i++) {
273
- dynBytes = &var->buffer.dynamicBytes[i];
274
- lob = var->buffer.references[i].asLOB;
275
- if (dynBytes->numChunks == 0)
276
- continue;
277
- if (dpiLob__setFromBytes(lob, dynBytes->chunks->ptr,
278
- dynBytes->chunks->length, error) < 0)
279
- return DPI_FAILURE;
280
- }
281
-
282
- return DPI_SUCCESS;
283
- }
284
-
285
-
286
- //-----------------------------------------------------------------------------
287
- // dpiVar__copyData() [INTERNAL]
288
- // Copy the data from the source to the target variable at the given array
289
- // position.
290
- //-----------------------------------------------------------------------------
291
- int dpiVar__copyData(dpiVar *var, uint32_t pos, dpiData *sourceData,
292
- dpiError *error)
293
- {
294
- dpiData *targetData = &var->buffer.externalData[pos];
295
-
296
- // handle null case
297
- targetData->isNull = sourceData->isNull;
298
- if (sourceData->isNull)
299
- return DPI_SUCCESS;
300
-
301
- // handle copying of value from source to target
302
- switch (var->nativeTypeNum) {
303
- case DPI_NATIVE_TYPE_BYTES:
304
- return dpiVar__setFromBytes(var, pos,
305
- sourceData->value.asBytes.ptr,
306
- sourceData->value.asBytes.length, error);
307
- case DPI_NATIVE_TYPE_LOB:
308
- return dpiVar__setFromLob(var, pos, sourceData->value.asLOB,
309
- error);
310
- case DPI_NATIVE_TYPE_OBJECT:
311
- return dpiVar__setFromObject(var, pos, sourceData->value.asObject,
312
- error);
313
- case DPI_NATIVE_TYPE_STMT:
314
- return dpiVar__setFromStmt(var, pos, sourceData->value.asStmt,
315
- error);
316
- case DPI_NATIVE_TYPE_ROWID:
317
- return dpiVar__setFromRowid(var, pos, sourceData->value.asRowid,
318
- error);
319
- default:
320
- memcpy(targetData, sourceData, sizeof(dpiData));
321
- }
322
-
323
- return DPI_SUCCESS;
324
- }
325
-
326
-
327
- //-----------------------------------------------------------------------------
328
- // dpiVar__defineCallback() [INTERNAL]
329
- // Callback which runs during OCI statement execution and allocates the
330
- // buffers required as well as provides that information to the OCI. This is
331
- // intended for handling string and raw columns for which the size is unknown.
332
- // These include LONG, LONG RAW and retrieving CLOB and BLOB as bytes, rather
333
- // than use the LOB API.
334
- //-----------------------------------------------------------------------------
335
- int32_t dpiVar__defineCallback(dpiVar *var, UNUSED void *defnp, uint32_t iter,
336
- void **bufpp, uint32_t **alenpp, UNUSED uint8_t *piecep, void **indpp,
337
- uint16_t **rcodepp)
338
- {
339
- dpiDynamicBytesChunk *chunk;
340
- dpiDynamicBytes *bytes;
341
-
342
- // allocate more chunks, if necessary
343
- bytes = &var->buffer.dynamicBytes[iter];
344
- if (bytes->numChunks == bytes->allocatedChunks &&
345
- dpiVar__allocateChunks(bytes, var->error) < 0)
346
- return DPI_OCI_ERROR;
347
-
348
- // allocate memory for the chunk, if needed
349
- chunk = &bytes->chunks[bytes->numChunks];
350
- if (!chunk->ptr) {
351
- chunk->allocatedLength = DPI_DYNAMIC_BYTES_CHUNK_SIZE;
352
- if (dpiUtils__allocateMemory(1, chunk->allocatedLength, 0,
353
- "allocate chunk", (void**) &chunk->ptr, var->error) < 0)
354
- return DPI_OCI_ERROR;
355
- }
356
-
357
- // return chunk to OCI
358
- bytes->numChunks++;
359
- chunk->length = chunk->allocatedLength;
360
- *bufpp = chunk->ptr;
361
- *alenpp = &chunk->length;
362
- *indpp = &(var->buffer.indicator[iter]);
363
- *rcodepp = NULL;
364
- return DPI_OCI_CONTINUE;
365
- }
366
-
367
-
368
- //-----------------------------------------------------------------------------
369
- // dpiVar__extendedPreFetch() [INTERNAL]
370
- // Perform any necessary actions prior to fetching data.
371
- //-----------------------------------------------------------------------------
372
- int dpiVar__extendedPreFetch(dpiVar *var, dpiVarBuffer *buffer,
373
- dpiError *error)
374
- {
375
- dpiRowid *rowid;
376
- dpiData *data;
377
- dpiStmt *stmt;
378
- dpiLob *lob;
379
- uint32_t i;
380
-
381
- if (var->isDynamic) {
382
- for (i = 0; i < buffer->maxArraySize; i++)
383
- buffer->dynamicBytes[i].numChunks = 0;
384
- return DPI_SUCCESS;
385
- }
386
-
387
- switch (var->type->oracleTypeNum) {
388
- case DPI_ORACLE_TYPE_STMT:
389
- for (i = 0; i < buffer->maxArraySize; i++) {
390
- data = &buffer->externalData[i];
391
- if (buffer->references[i].asStmt) {
392
- dpiGen__setRefCount(buffer->references[i].asStmt,
393
- error, -1);
394
- buffer->references[i].asStmt = NULL;
395
- }
396
- buffer->data.asStmt[i] = NULL;
397
- data->value.asStmt = NULL;
398
- if (dpiStmt__allocate(var->conn, 0, &stmt, error) < 0)
399
- return DPI_FAILURE;
400
- if (dpiOci__handleAlloc(var->env->handle, &stmt->handle,
401
- DPI_OCI_HTYPE_STMT, "allocate statement", error) < 0) {
402
- dpiStmt__free(stmt, error);
403
- return DPI_FAILURE;
404
- }
405
- if (dpiHandleList__addHandle(var->conn->openStmts, stmt,
406
- &stmt->openSlotNum, error) < 0) {
407
- dpiOci__handleFree(stmt->handle, DPI_OCI_HTYPE_STMT);
408
- stmt->handle = NULL;
409
- dpiStmt__free(stmt, error);
410
- return DPI_FAILURE;
411
- }
412
- buffer->references[i].asStmt = stmt;
413
- stmt->isOwned = 1;
414
- buffer->data.asStmt[i] = stmt->handle;
415
- data->value.asStmt = stmt;
416
- }
417
- break;
418
- case DPI_ORACLE_TYPE_CLOB:
419
- case DPI_ORACLE_TYPE_BLOB:
420
- case DPI_ORACLE_TYPE_NCLOB:
421
- case DPI_ORACLE_TYPE_BFILE:
422
- for (i = 0; i < buffer->maxArraySize; i++) {
423
- data = &buffer->externalData[i];
424
- if (buffer->references[i].asLOB) {
425
- dpiGen__setRefCount(buffer->references[i].asLOB,
426
- error, -1);
427
- buffer->references[i].asLOB = NULL;
428
- }
429
- buffer->data.asLobLocator[i] = NULL;
430
- data->value.asLOB = NULL;
431
- if (dpiLob__allocate(var->conn, var->type, &lob, error) < 0)
432
- return DPI_FAILURE;
433
- buffer->references[i].asLOB = lob;
434
- buffer->data.asLobLocator[i] = lob->locator;
435
- data->value.asLOB = lob;
436
- if (buffer->dynamicBytes &&
437
- dpiOci__lobCreateTemporary(lob, error) < 0)
438
- return DPI_FAILURE;
439
- }
440
- break;
441
- case DPI_ORACLE_TYPE_ROWID:
442
- for (i = 0; i < buffer->maxArraySize; i++) {
443
- data = &buffer->externalData[i];
444
- if (buffer->references[i].asRowid) {
445
- dpiGen__setRefCount(buffer->references[i].asRowid,
446
- error, -1);
447
- buffer->references[i].asRowid = NULL;
448
- }
449
- buffer->data.asRowid[i] = NULL;
450
- data->value.asRowid = NULL;
451
- if (dpiRowid__allocate(var->conn, &rowid, error) < 0)
452
- return DPI_FAILURE;
453
- buffer->references[i].asRowid = rowid;
454
- buffer->data.asRowid[i] = rowid->handle;
455
- data->value.asRowid = rowid;
456
- }
457
- break;
458
- case DPI_ORACLE_TYPE_OBJECT:
459
- for (i = 0; i < buffer->maxArraySize; i++) {
460
- data = &buffer->externalData[i];
461
- if (buffer->references[i].asObject) {
462
- dpiGen__setRefCount(buffer->references[i].asObject,
463
- error, -1);
464
- buffer->references[i].asObject = NULL;
465
- }
466
- buffer->data.asObject[i] = NULL;
467
- buffer->objectIndicator[i] = NULL;
468
- data->value.asObject = NULL;
469
- }
470
- break;
471
- default:
472
- break;
473
- }
474
-
475
- return DPI_SUCCESS;
476
- }
477
-
478
-
479
- //-----------------------------------------------------------------------------
480
- // dpiVar__finalizeBuffer() [INTERNAL]
481
- // Finalize buffer used for passing data to/from Oracle.
482
- //-----------------------------------------------------------------------------
483
- static void dpiVar__finalizeBuffer(dpiVar *var, dpiVarBuffer *buffer,
484
- dpiError *error)
485
- {
486
- dpiDynamicBytes *dynBytes;
487
- uint32_t i, j;
488
-
489
- // free any descriptors that were created
490
- switch (var->type->oracleTypeNum) {
491
- case DPI_ORACLE_TYPE_TIMESTAMP:
492
- dpiOci__arrayDescriptorFree(&buffer->data.asTimestamp[0],
493
- DPI_OCI_DTYPE_TIMESTAMP);
494
- break;
495
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
496
- dpiOci__arrayDescriptorFree(&buffer->data.asTimestamp[0],
497
- DPI_OCI_DTYPE_TIMESTAMP_TZ);
498
- break;
499
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
500
- dpiOci__arrayDescriptorFree(&buffer->data.asTimestamp[0],
501
- DPI_OCI_DTYPE_TIMESTAMP_LTZ);
502
- break;
503
- case DPI_ORACLE_TYPE_INTERVAL_DS:
504
- dpiOci__arrayDescriptorFree(&buffer->data.asInterval[0],
505
- DPI_OCI_DTYPE_INTERVAL_DS);
506
- break;
507
- case DPI_ORACLE_TYPE_INTERVAL_YM:
508
- dpiOci__arrayDescriptorFree(&buffer->data.asInterval[0],
509
- DPI_OCI_DTYPE_INTERVAL_YM);
510
- break;
511
- default:
512
- break;
513
- }
514
-
515
- // release any references that were created
516
- if (buffer->references) {
517
- for (i = 0; i < buffer->maxArraySize; i++) {
518
- if (buffer->references[i].asHandle) {
519
- dpiGen__setRefCount(buffer->references[i].asHandle, error, -1);
520
- buffer->references[i].asHandle = NULL;
521
- }
522
- }
523
- dpiUtils__freeMemory(buffer->references);
524
- buffer->references = NULL;
525
- }
526
-
527
- // free any dynamic buffers
528
- if (buffer->dynamicBytes) {
529
- for (i = 0; i < buffer->maxArraySize; i++) {
530
- dynBytes = &buffer->dynamicBytes[i];
531
- if (dynBytes->allocatedChunks > 0) {
532
- for (j = 0; j < dynBytes->allocatedChunks; j++) {
533
- if (dynBytes->chunks[j].ptr) {
534
- dpiUtils__freeMemory(dynBytes->chunks[j].ptr);
535
- dynBytes->chunks[j].ptr = NULL;
536
- }
537
- }
538
- dpiUtils__freeMemory(dynBytes->chunks);
539
- dynBytes->allocatedChunks = 0;
540
- dynBytes->chunks = NULL;
541
- }
542
- }
543
- dpiUtils__freeMemory(buffer->dynamicBytes);
544
- buffer->dynamicBytes = NULL;
545
- }
546
-
547
- // free other memory allocated
548
- if (buffer->indicator) {
549
- dpiUtils__freeMemory(buffer->indicator);
550
- buffer->indicator = NULL;
551
- }
552
- if (buffer->returnCode) {
553
- dpiUtils__freeMemory(buffer->returnCode);
554
- buffer->returnCode = NULL;
555
- }
556
- if (buffer->actualLength16) {
557
- dpiUtils__freeMemory(buffer->actualLength16);
558
- buffer->actualLength16 = NULL;
559
- }
560
- if (buffer->actualLength32) {
561
- dpiUtils__freeMemory(buffer->actualLength32);
562
- buffer->actualLength32 = NULL;
563
- }
564
- if (buffer->externalData) {
565
- dpiUtils__freeMemory(buffer->externalData);
566
- buffer->externalData = NULL;
567
- }
568
- if (buffer->data.asRaw) {
569
- dpiUtils__freeMemory(buffer->data.asRaw);
570
- buffer->data.asRaw = NULL;
571
- }
572
- if (buffer->objectIndicator) {
573
- dpiUtils__freeMemory(buffer->objectIndicator);
574
- buffer->objectIndicator = NULL;
575
- }
576
- if (buffer->tempBuffer) {
577
- dpiUtils__freeMemory(buffer->tempBuffer);
578
- buffer->tempBuffer = NULL;
579
- }
580
- }
581
-
582
-
583
- //-----------------------------------------------------------------------------
584
- // dpiVar__free() [INTERNAL]
585
- // Free the memory associated with the variable.
586
- //-----------------------------------------------------------------------------
587
- void dpiVar__free(dpiVar *var, dpiError *error)
588
- {
589
- uint32_t i;
590
-
591
- dpiVar__finalizeBuffer(var, &var->buffer, error);
592
- if (var->dynBindBuffers) {
593
- for (i = 0; i < var->buffer.maxArraySize; i++)
594
- dpiVar__finalizeBuffer(var, &var->dynBindBuffers[i], error);
595
- dpiUtils__freeMemory(var->dynBindBuffers);
596
- var->dynBindBuffers = NULL;
597
- }
598
- if (var->objectType) {
599
- dpiGen__setRefCount(var->objectType, error, -1);
600
- var->objectType = NULL;
601
- }
602
- if (var->conn) {
603
- dpiGen__setRefCount(var->conn, error, -1);
604
- var->conn = NULL;
605
- }
606
- dpiUtils__freeMemory(var);
607
- }
608
-
609
-
610
- //-----------------------------------------------------------------------------
611
- // dpiVar__getValue() [PRIVATE]
612
- // Returns the contents of the variable in the type specified, if possible.
613
- //-----------------------------------------------------------------------------
614
- int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos,
615
- int inFetch, dpiError *error)
616
- {
617
- dpiOracleTypeNum oracleTypeNum;
618
- dpiBytes *bytes;
619
- dpiData *data;
620
- uint32_t i;
621
-
622
- // check for dynamic binds first; if they exist, process them instead
623
- if (var->dynBindBuffers && buffer == &var->buffer) {
624
- buffer = &var->dynBindBuffers[pos];
625
- for (i = 0; i < buffer->maxArraySize; i++) {
626
- if (dpiVar__getValue(var, buffer, i, inFetch, error) < 0)
627
- return DPI_FAILURE;
628
- }
629
- return DPI_SUCCESS;
630
- }
631
-
632
-
633
- // check for a NULL value; for objects the indicator is elsewhere
634
- data = &buffer->externalData[pos];
635
- if (!buffer->objectIndicator)
636
- data->isNull = (buffer->indicator[pos] == DPI_OCI_IND_NULL);
637
- else if (buffer->objectIndicator[pos])
638
- data->isNull = (*((int16_t*) buffer->objectIndicator[pos]) ==
639
- DPI_OCI_IND_NULL);
640
- else data->isNull = 1;
641
- if (data->isNull)
642
- return DPI_SUCCESS;
643
-
644
- // check return code for variable length data
645
- if (buffer->returnCode) {
646
- if (buffer->returnCode[pos] != 0) {
647
- dpiError__set(error, "check return code", DPI_ERR_COLUMN_FETCH,
648
- pos, buffer->returnCode[pos]);
649
- error->buffer->code = buffer->returnCode[pos];
650
- return DPI_FAILURE;
651
- }
652
- }
653
-
654
- // for 11g, dynamic lengths are 32-bit whereas static lengths are 16-bit
655
- if (buffer->actualLength16 && buffer->actualLength32)
656
- buffer->actualLength16[pos] = (uint16_t) buffer->actualLength32[pos];
657
-
658
- // transform the various types
659
- oracleTypeNum = var->type->oracleTypeNum;
660
- switch (var->nativeTypeNum) {
661
- case DPI_NATIVE_TYPE_INT64:
662
- case DPI_NATIVE_TYPE_UINT64:
663
- switch (oracleTypeNum) {
664
- case DPI_ORACLE_TYPE_NATIVE_INT:
665
- data->value.asInt64 = buffer->data.asInt64[pos];
666
- return DPI_SUCCESS;
667
- case DPI_ORACLE_TYPE_NATIVE_UINT:
668
- data->value.asUint64 = buffer->data.asUint64[pos];
669
- return DPI_SUCCESS;
670
- case DPI_ORACLE_TYPE_NUMBER:
671
- if (var->nativeTypeNum == DPI_NATIVE_TYPE_INT64)
672
- return dpiDataBuffer__fromOracleNumberAsInteger(
673
- &data->value, error,
674
- &buffer->data.asNumber[pos]);
675
- return dpiDataBuffer__fromOracleNumberAsUnsignedInteger(
676
- &data->value, error, &buffer->data.asNumber[pos]);
677
- default:
678
- break;
679
- }
680
- break;
681
- case DPI_NATIVE_TYPE_DOUBLE:
682
- switch (oracleTypeNum) {
683
- case DPI_ORACLE_TYPE_NUMBER:
684
- return dpiDataBuffer__fromOracleNumberAsDouble(
685
- &data->value, error, &buffer->data.asNumber[pos]);
686
- case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
687
- data->value.asDouble = buffer->data.asDouble[pos];
688
- return DPI_SUCCESS;
689
- case DPI_ORACLE_TYPE_TIMESTAMP:
690
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
691
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
692
- return dpiDataBuffer__fromOracleTimestampAsDouble(
693
- &data->value, var->env, error,
694
- buffer->data.asTimestamp[pos]);
695
- default:
696
- break;
697
- }
698
- break;
699
- case DPI_NATIVE_TYPE_BYTES:
700
- bytes = &data->value.asBytes;
701
- switch (oracleTypeNum) {
702
- case DPI_ORACLE_TYPE_VARCHAR:
703
- case DPI_ORACLE_TYPE_NVARCHAR:
704
- case DPI_ORACLE_TYPE_CHAR:
705
- case DPI_ORACLE_TYPE_NCHAR:
706
- case DPI_ORACLE_TYPE_ROWID:
707
- case DPI_ORACLE_TYPE_RAW:
708
- case DPI_ORACLE_TYPE_LONG_VARCHAR:
709
- case DPI_ORACLE_TYPE_LONG_RAW:
710
- if (buffer->dynamicBytes)
711
- return dpiVar__setBytesFromDynamicBytes(bytes,
712
- &buffer->dynamicBytes[pos], error);
713
- if (buffer->actualLength16)
714
- bytes->length = buffer->actualLength16[pos];
715
- else bytes->length = buffer->actualLength32[pos];
716
- return DPI_SUCCESS;
717
- case DPI_ORACLE_TYPE_CLOB:
718
- case DPI_ORACLE_TYPE_NCLOB:
719
- case DPI_ORACLE_TYPE_BLOB:
720
- case DPI_ORACLE_TYPE_BFILE:
721
- return dpiVar__setBytesFromLob(bytes,
722
- &buffer->dynamicBytes[pos],
723
- buffer->references[pos].asLOB, error);
724
- case DPI_ORACLE_TYPE_NUMBER:
725
- bytes->length = DPI_NUMBER_AS_TEXT_CHARS;
726
- if (var->env->charsetId == DPI_CHARSET_ID_UTF16)
727
- bytes->length *= 2;
728
- return dpiDataBuffer__fromOracleNumberAsText(&data->value,
729
- var->env, error, &buffer->data.asNumber[pos]);
730
- default:
731
- break;
732
- }
733
- break;
734
- case DPI_NATIVE_TYPE_FLOAT:
735
- data->value.asFloat = buffer->data.asFloat[pos];
736
- break;
737
- case DPI_NATIVE_TYPE_TIMESTAMP:
738
- if (oracleTypeNum == DPI_ORACLE_TYPE_DATE)
739
- return dpiDataBuffer__fromOracleDate(&data->value,
740
- &buffer->data.asDate[pos]);
741
- return dpiDataBuffer__fromOracleTimestamp(&data->value, var->env,
742
- error, buffer->data.asTimestamp[pos],
743
- oracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP);
744
- break;
745
- case DPI_NATIVE_TYPE_INTERVAL_DS:
746
- return dpiDataBuffer__fromOracleIntervalDS(&data->value, var->env,
747
- error, buffer->data.asInterval[pos]);
748
- case DPI_NATIVE_TYPE_INTERVAL_YM:
749
- return dpiDataBuffer__fromOracleIntervalYM(&data->value, var->env,
750
- error, buffer->data.asInterval[pos]);
751
- case DPI_NATIVE_TYPE_OBJECT:
752
- data->value.asObject = NULL;
753
- if (!buffer->references[pos].asObject) {
754
- if (dpiObject__allocate(var->objectType,
755
- buffer->data.asObject[pos],
756
- buffer->objectIndicator[pos], NULL,
757
- &buffer->references[pos].asObject, error) < 0)
758
- return DPI_FAILURE;
759
- if (inFetch && var->objectType->isCollection)
760
- buffer->references[pos].asObject->freeIndicator = 1;
761
- }
762
- data->value.asObject = buffer->references[pos].asObject;
763
- break;
764
- case DPI_NATIVE_TYPE_STMT:
765
- data->value.asStmt = buffer->references[pos].asStmt;
766
- break;
767
- case DPI_NATIVE_TYPE_BOOLEAN:
768
- data->value.asBoolean = buffer->data.asBoolean[pos];
769
- break;
770
- default:
771
- break;
772
- }
773
- return DPI_SUCCESS;
774
- }
775
-
776
-
777
- //-----------------------------------------------------------------------------
778
- // dpiVar__inBindCallback() [INTERNAL]
779
- // Callback which runs during OCI statement execution and provides buffers to
780
- // OCI for binding data IN. This is not used with DML returning so this method
781
- // does nothing useful except satisfy OCI requirements.
782
- //-----------------------------------------------------------------------------
783
- int32_t dpiVar__inBindCallback(dpiVar *var, UNUSED void *bindp,
784
- UNUSED uint32_t iter, uint32_t index, void **bufpp, uint32_t *alenp,
785
- uint8_t *piecep, void **indpp)
786
- {
787
- dpiDynamicBytes *dynBytes;
788
-
789
- if (var->isDynamic) {
790
- dynBytes = &var->buffer.dynamicBytes[iter];
791
- if (dynBytes->allocatedChunks == 0) {
792
- *bufpp = NULL;
793
- *alenp = 0;
794
- } else {
795
- *bufpp = dynBytes->chunks->ptr;
796
- *alenp = dynBytes->chunks->length;
797
- }
798
- } else {
799
- dpiVar__assignCallbackBuffer(var, &var->buffer, iter, bufpp);
800
- if (var->buffer.actualLength16)
801
- *alenp = var->buffer.actualLength16[iter];
802
- else if (var->buffer.actualLength32)
803
- *alenp = var->buffer.actualLength32[iter];
804
- else *alenp = var->type->sizeInBytes;
805
- }
806
- *piecep = DPI_OCI_ONE_PIECE;
807
- if (var->buffer.objectIndicator)
808
- *indpp = var->buffer.objectIndicator[iter];
809
- else *indpp = &var->buffer.indicator[iter];
810
- return DPI_OCI_CONTINUE;
811
- }
812
-
813
-
814
- //-----------------------------------------------------------------------------
815
- // dpiVar__initBuffer() [INTERNAL]
816
- // Initialize buffers necessary for passing data to/from Oracle.
817
- //-----------------------------------------------------------------------------
818
- static int dpiVar__initBuffer(dpiVar *var, dpiVarBuffer *buffer,
819
- dpiError *error)
820
- {
821
- uint32_t i, tempBufferSize = 0;
822
- unsigned long long dataLength;
823
- dpiBytes *bytes;
824
-
825
- // initialize dynamic buffers for dynamic variables
826
- if (var->isDynamic) {
827
- if (dpiUtils__allocateMemory(buffer->maxArraySize,
828
- sizeof(dpiDynamicBytes), 1, "allocate dynamic bytes",
829
- (void**) &buffer->dynamicBytes, error) < 0)
830
- return DPI_FAILURE;
831
-
832
- // for all other variables, validate length and allocate buffers
833
- } else {
834
- dataLength = (unsigned long long) buffer->maxArraySize *
835
- (unsigned long long) var->sizeInBytes;
836
- if (dataLength > INT_MAX)
837
- return dpiError__set(error, "check max array size",
838
- DPI_ERR_ARRAY_SIZE_TOO_BIG, buffer->maxArraySize);
839
- if (dpiUtils__allocateMemory(1, (size_t) dataLength, 0,
840
- "allocate buffer", (void**) &buffer->data.asRaw, error) < 0)
841
- return DPI_FAILURE;
842
- }
843
-
844
- // allocate the indicator for the variable
845
- // ensure all values start out as null
846
- if (!buffer->indicator) {
847
- if (dpiUtils__allocateMemory(buffer->maxArraySize, sizeof(int16_t), 0,
848
- "allocate indicator", (void**) &buffer->indicator, error) < 0)
849
- return DPI_FAILURE;
850
- for (i = 0; i < buffer->maxArraySize; i++)
851
- buffer->indicator[i] = DPI_OCI_IND_NULL;
852
- }
853
-
854
- // allocate the actual length buffers for all but dynamic bytes which are
855
- // handled differently; ensure actual length starts out as maximum value
856
- if (!var->isDynamic && !buffer->actualLength16 &&
857
- !buffer->actualLength32) {
858
- if (var->env->versionInfo->versionNum < 12 && buffer == &var->buffer) {
859
- if (dpiUtils__allocateMemory(buffer->maxArraySize,
860
- sizeof(uint16_t), 0, "allocate actual length",
861
- (void**) &buffer->actualLength16, error) < 0)
862
- return DPI_FAILURE;
863
- for (i = 0; i < buffer->maxArraySize; i++)
864
- buffer->actualLength16[i] = (uint16_t) var->sizeInBytes;
865
- } else {
866
- if (dpiUtils__allocateMemory(buffer->maxArraySize,
867
- sizeof(uint32_t), 0, "allocate actual length",
868
- (void**) &buffer->actualLength32, error) < 0)
869
- return DPI_FAILURE;
870
- for (i = 0; i < buffer->maxArraySize; i++)
871
- buffer->actualLength32[i] = var->sizeInBytes;
872
- }
873
- }
874
-
875
- // for variable length data, also allocate the return code array
876
- if (var->type->defaultNativeTypeNum == DPI_NATIVE_TYPE_BYTES &&
877
- !var->isDynamic && !buffer->returnCode) {
878
- if (dpiUtils__allocateMemory(buffer->maxArraySize, sizeof(uint16_t), 0,
879
- "allocate return code", (void**) &buffer->returnCode,
880
- error) < 0)
881
- return DPI_FAILURE;
882
- }
883
-
884
- // for numbers transferred to/from Oracle as bytes, allocate an additional
885
- // set of buffers
886
- if (var->type->oracleTypeNum == DPI_ORACLE_TYPE_NUMBER &&
887
- var->nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
888
- tempBufferSize = DPI_NUMBER_AS_TEXT_CHARS;
889
- if (var->env->charsetId == DPI_CHARSET_ID_UTF16)
890
- tempBufferSize *= 2;
891
- if (!buffer->tempBuffer) {
892
- if (dpiUtils__allocateMemory(buffer->maxArraySize, tempBufferSize,
893
- 0, "allocate temp buffer", (void**) &buffer->tempBuffer,
894
- error) < 0)
895
- return DPI_FAILURE;
896
- }
897
- }
898
-
899
- // allocate the external data array, if needed
900
- if (!buffer->externalData) {
901
- if (dpiUtils__allocateMemory(buffer->maxArraySize, sizeof(dpiData), 1,
902
- "allocate external data", (void**) &buffer->externalData,
903
- error) < 0)
904
- return DPI_FAILURE;
905
- for (i = 0; i < buffer->maxArraySize; i++)
906
- buffer->externalData[i].isNull = 1;
907
- }
908
-
909
- // for bytes transfers, set encoding and pointers for small strings
910
- if (var->nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
911
- for (i = 0; i < buffer->maxArraySize; i++) {
912
- bytes = &buffer->externalData[i].value.asBytes;
913
- if (var->type->charsetForm == DPI_SQLCS_IMPLICIT)
914
- bytes->encoding = var->env->encoding;
915
- else bytes->encoding = var->env->nencoding;
916
- if (buffer->tempBuffer)
917
- bytes->ptr = buffer->tempBuffer + i * tempBufferSize;
918
- else if (!var->isDynamic && !buffer->dynamicBytes)
919
- bytes->ptr = buffer->data.asBytes + i * var->sizeInBytes;
920
- }
921
- }
922
-
923
- // create array of references, if applicable
924
- if (var->type->requiresPreFetch && !var->isDynamic) {
925
- if (dpiUtils__allocateMemory(buffer->maxArraySize,
926
- sizeof(dpiReferenceBuffer), 1, "allocate references",
927
- (void**) &buffer->references, error) < 0)
928
- return DPI_FAILURE;
929
- }
930
-
931
- // perform variable specific initialization
932
- switch (var->type->oracleTypeNum) {
933
- case DPI_ORACLE_TYPE_TIMESTAMP:
934
- return dpiOci__arrayDescriptorAlloc(var->env->handle,
935
- &buffer->data.asTimestamp[0], DPI_OCI_DTYPE_TIMESTAMP,
936
- buffer->maxArraySize, error);
937
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
938
- return dpiOci__arrayDescriptorAlloc(var->env->handle,
939
- &buffer->data.asTimestamp[0], DPI_OCI_DTYPE_TIMESTAMP_TZ,
940
- buffer->maxArraySize, error);
941
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
942
- return dpiOci__arrayDescriptorAlloc(var->env->handle,
943
- &buffer->data.asTimestamp[0], DPI_OCI_DTYPE_TIMESTAMP_LTZ,
944
- buffer->maxArraySize, error);
945
- case DPI_ORACLE_TYPE_INTERVAL_DS:
946
- return dpiOci__arrayDescriptorAlloc(var->env->handle,
947
- &buffer->data.asInterval[0], DPI_OCI_DTYPE_INTERVAL_DS,
948
- buffer->maxArraySize, error);
949
- case DPI_ORACLE_TYPE_INTERVAL_YM:
950
- return dpiOci__arrayDescriptorAlloc(var->env->handle,
951
- &buffer->data.asInterval[0], DPI_OCI_DTYPE_INTERVAL_YM,
952
- buffer->maxArraySize, error);
953
- break;
954
- case DPI_ORACLE_TYPE_CLOB:
955
- case DPI_ORACLE_TYPE_BLOB:
956
- case DPI_ORACLE_TYPE_NCLOB:
957
- case DPI_ORACLE_TYPE_BFILE:
958
- case DPI_ORACLE_TYPE_STMT:
959
- case DPI_ORACLE_TYPE_ROWID:
960
- return dpiVar__extendedPreFetch(var, buffer, error);
961
- case DPI_ORACLE_TYPE_OBJECT:
962
- if (!var->objectType)
963
- return dpiError__set(error, "check object type",
964
- DPI_ERR_NO_OBJECT_TYPE);
965
- if (dpiUtils__allocateMemory(buffer->maxArraySize, sizeof(void*),
966
- 0, "allocate object indicator",
967
- (void**) &buffer->objectIndicator, error) < 0)
968
- return DPI_FAILURE;
969
- return dpiVar__extendedPreFetch(var, buffer, error);
970
- default:
971
- break;
972
- }
973
-
974
- return DPI_SUCCESS;
975
- }
976
-
977
-
978
- //-----------------------------------------------------------------------------
979
- // dpiVar__outBindCallback() [INTERNAL]
980
- // Callback which runs during OCI statement execution and allocates the
981
- // buffers required as well as provides that information to the OCI. This is
982
- // intended for use with DML returning only.
983
- //-----------------------------------------------------------------------------
984
- int32_t dpiVar__outBindCallback(dpiVar *var, void *bindp, UNUSED uint32_t iter,
985
- uint32_t index, void **bufpp, uint32_t **alenpp, uint8_t *piecep,
986
- void **indpp, uint16_t **rcodepp)
987
- {
988
- dpiDynamicBytesChunk *chunk;
989
- uint32_t numRowsReturned;
990
- dpiDynamicBytes *bytes;
991
- dpiVarBuffer *buffer;
992
-
993
- // determine which variable buffer to use
994
- if (!var->dynBindBuffers) {
995
- if (dpiUtils__allocateMemory(var->buffer.maxArraySize,
996
- sizeof(dpiVarBuffer), 1, "allocate DML returning buffers",
997
- (void**) &var->dynBindBuffers, var->error) < 0)
998
- return DPI_FAILURE;
999
- }
1000
- buffer = &var->dynBindBuffers[iter];
1001
-
1002
- // special processing during first value returned for each iteration
1003
- if (index == 0) {
1004
-
1005
- // determine number of rows returned
1006
- if (dpiOci__attrGet(bindp, DPI_OCI_HTYPE_BIND, &numRowsReturned, 0,
1007
- DPI_OCI_ATTR_ROWS_RETURNED, "get rows returned",
1008
- var->error) < 0)
1009
- return DPI_OCI_ERROR;
1010
-
1011
- // reallocate buffers, if needed
1012
- if (numRowsReturned > buffer->maxArraySize) {
1013
- dpiVar__finalizeBuffer(var, buffer, var->error);
1014
- buffer->maxArraySize = numRowsReturned;
1015
- if (dpiVar__initBuffer(var, buffer, var->error) < 0)
1016
- return DPI_OCI_ERROR;
1017
- }
1018
-
1019
- // set actual array size to number of rows returned
1020
- buffer->actualArraySize = numRowsReturned;
1021
-
1022
- }
1023
-
1024
- // handle dynamically allocated strings (multiple piece)
1025
- // index is the current index into the chunks
1026
- if (var->isDynamic) {
1027
-
1028
- // allocate more chunks, if necessary
1029
- bytes = &buffer->dynamicBytes[index];
1030
- if (*piecep == DPI_OCI_ONE_PIECE)
1031
- bytes->numChunks = 0;
1032
- if (bytes->numChunks == bytes->allocatedChunks &&
1033
- dpiVar__allocateChunks(bytes, var->error) < 0)
1034
- return DPI_OCI_ERROR;
1035
-
1036
- // allocate memory for the chunk, if needed
1037
- chunk = &bytes->chunks[bytes->numChunks];
1038
- if (!chunk->ptr) {
1039
- chunk->allocatedLength = DPI_DYNAMIC_BYTES_CHUNK_SIZE;
1040
- if (dpiUtils__allocateMemory(1, chunk->allocatedLength, 0,
1041
- "allocate chunk", (void**) &chunk->ptr, var->error) < 0)
1042
- return DPI_OCI_ERROR;
1043
- }
1044
-
1045
- // return chunk to OCI
1046
- bytes->numChunks++;
1047
- chunk->length = chunk->allocatedLength;
1048
- *bufpp = chunk->ptr;
1049
- *alenpp = &chunk->length;
1050
- *indpp = &(buffer->indicator[index]);
1051
- *rcodepp = NULL;
1052
-
1053
- // handle normally allocated variables (one piece)
1054
- } else {
1055
-
1056
- *piecep = DPI_OCI_ONE_PIECE;
1057
- if (dpiVar__setValue(var, buffer, index, &buffer->externalData[index],
1058
- var->error) < 0)
1059
- return DPI_OCI_ERROR;
1060
- dpiVar__assignCallbackBuffer(var, buffer, index, bufpp);
1061
- if (buffer->actualLength32 || buffer->actualLength16) {
1062
- if (!buffer->actualLength32) {
1063
- if (dpiUtils__allocateMemory(buffer->maxArraySize,
1064
- sizeof(uint32_t), 1, "allocate 11g lengths",
1065
- (void**) &buffer->actualLength32, var->error) < 0)
1066
- return DPI_OCI_ERROR;
1067
- }
1068
- buffer->actualLength32[index] = var->sizeInBytes;
1069
- *alenpp = &(buffer->actualLength32[index]);
1070
- } else if (*alenpp && var->type->sizeInBytes)
1071
- **alenpp = var->type->sizeInBytes;
1072
- if (buffer->objectIndicator)
1073
- *indpp = buffer->objectIndicator[index];
1074
- else *indpp = &(buffer->indicator[index]);
1075
- if (buffer->returnCode)
1076
- *rcodepp = &buffer->returnCode[index];
1077
-
1078
- }
1079
-
1080
- return DPI_OCI_CONTINUE;
1081
- }
1082
-
1083
-
1084
- //-----------------------------------------------------------------------------
1085
- // dpiVar__setBytesFromDynamicBytes() [PRIVATE]
1086
- // Set the pointer and length in the dpiBytes structure to the values
1087
- // retrieved from the database. At this point, if multiple chunks exist, they
1088
- // are combined into one.
1089
- //-----------------------------------------------------------------------------
1090
- static int dpiVar__setBytesFromDynamicBytes(dpiBytes *bytes,
1091
- dpiDynamicBytes *dynBytes, dpiError *error)
1092
- {
1093
- uint32_t i, totalAllocatedLength;
1094
-
1095
- // if only one chunk is available, make use of it
1096
- if (dynBytes->numChunks == 1) {
1097
- bytes->ptr = dynBytes->chunks->ptr;
1098
- bytes->length = dynBytes->chunks->length;
1099
- return DPI_SUCCESS;
1100
- }
1101
-
1102
- // determine total allocated size of all chunks
1103
- totalAllocatedLength = 0;
1104
- for (i = 0; i < dynBytes->numChunks; i++)
1105
- totalAllocatedLength += dynBytes->chunks[i].allocatedLength;
1106
-
1107
- // allocate new memory consolidating all of the chunks
1108
- if (dpiUtils__allocateMemory(1, totalAllocatedLength, 0,
1109
- "allocate consolidated chunk", (void**) &bytes->ptr, error) < 0)
1110
- return DPI_FAILURE;
1111
-
1112
- // copy memory from chunks to consolidated chunk
1113
- bytes->length = 0;
1114
- for (i = 0; i < dynBytes->numChunks; i++) {
1115
- memcpy(bytes->ptr + bytes->length, dynBytes->chunks[i].ptr,
1116
- dynBytes->chunks[i].length);
1117
- bytes->length += dynBytes->chunks[i].length;
1118
- dpiUtils__freeMemory(dynBytes->chunks[i].ptr);
1119
- dynBytes->chunks[i].ptr = NULL;
1120
- dynBytes->chunks[i].length = 0;
1121
- dynBytes->chunks[i].allocatedLength = 0;
1122
- }
1123
-
1124
- // populate first chunk with consolidated information
1125
- dynBytes->numChunks = 1;
1126
- dynBytes->chunks->ptr = bytes->ptr;
1127
- dynBytes->chunks->length = bytes->length;
1128
- dynBytes->chunks->allocatedLength = totalAllocatedLength;
1129
-
1130
- return DPI_SUCCESS;
1131
- }
1132
-
1133
-
1134
- //-----------------------------------------------------------------------------
1135
- // dpiVar__setBytesFromLob() [PRIVATE]
1136
- // Populate the dynamic bytes structure with the data from the LOB and then
1137
- // populate the bytes structure.
1138
- //-----------------------------------------------------------------------------
1139
- static int dpiVar__setBytesFromLob(dpiBytes *bytes, dpiDynamicBytes *dynBytes,
1140
- dpiLob *lob, dpiError *error)
1141
- {
1142
- uint64_t length, lengthInBytes, lengthReadInBytes;
1143
-
1144
- // determine length of LOB in bytes
1145
- if (dpiOci__lobGetLength2(lob, &length, error) < 0)
1146
- return DPI_FAILURE;
1147
- if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_CLOB)
1148
- lengthInBytes = length * lob->env->maxBytesPerCharacter;
1149
- else if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_NCLOB)
1150
- lengthInBytes = length * lob->env->nmaxBytesPerCharacter;
1151
- else lengthInBytes = length;
1152
-
1153
- // ensure there is enough space to store the entire LOB value
1154
- if (lengthInBytes > UINT_MAX)
1155
- return dpiError__set(error, "check max length", DPI_ERR_NOT_SUPPORTED);
1156
- if (dpiVar__allocateDynamicBytes(dynBytes, (uint32_t) lengthInBytes,
1157
- error) < 0)
1158
- return DPI_FAILURE;
1159
-
1160
- // read data from the LOB
1161
- lengthReadInBytes = lengthInBytes;
1162
- if (length > 0 && dpiLob__readBytes(lob, 1, length, dynBytes->chunks->ptr,
1163
- &lengthReadInBytes, error) < 0)
1164
- return DPI_FAILURE;
1165
-
1166
- dynBytes->chunks->length = (uint32_t) lengthReadInBytes;
1167
- bytes->ptr = dynBytes->chunks->ptr;
1168
- bytes->length = dynBytes->chunks->length;
1169
- return DPI_SUCCESS;
1170
- }
1171
-
1172
-
1173
- //-----------------------------------------------------------------------------
1174
- // dpiVar__setFromBytes() [PRIVATE]
1175
- // Set the value of the variable at the given array position from a byte
1176
- // string. The byte string is not retained in any way. A copy will be made into
1177
- // buffers allocated by ODPI-C.
1178
- //-----------------------------------------------------------------------------
1179
- static int dpiVar__setFromBytes(dpiVar *var, uint32_t pos, const char *value,
1180
- uint32_t valueLength, dpiError *error)
1181
- {
1182
- dpiData *data = &var->buffer.externalData[pos];
1183
- dpiDynamicBytes *dynBytes;
1184
- dpiBytes *bytes;
1185
-
1186
- // for internally used LOBs, write the data directly
1187
- if (var->buffer.references) {
1188
- data->isNull = 0;
1189
- return dpiLob__setFromBytes(var->buffer.references[pos].asLOB, value,
1190
- valueLength, error);
1191
- }
1192
-
1193
- // validate the target can accept the input
1194
- if ((var->buffer.tempBuffer &&
1195
- var->env->charsetId == DPI_CHARSET_ID_UTF16 &&
1196
- valueLength > DPI_NUMBER_AS_TEXT_CHARS * 2) ||
1197
- (var->buffer.tempBuffer &&
1198
- var->env->charsetId != DPI_CHARSET_ID_UTF16 &&
1199
- valueLength > DPI_NUMBER_AS_TEXT_CHARS) ||
1200
- (!var->buffer.dynamicBytes && !var->buffer.tempBuffer &&
1201
- valueLength > var->sizeInBytes))
1202
- return dpiError__set(error, "check source length",
1203
- DPI_ERR_BUFFER_SIZE_TOO_SMALL, var->sizeInBytes);
1204
-
1205
- // for dynamic bytes, allocate space as needed
1206
- bytes = &data->value.asBytes;
1207
- if (var->buffer.dynamicBytes) {
1208
- dynBytes = &var->buffer.dynamicBytes[pos];
1209
- if (dpiVar__allocateDynamicBytes(dynBytes, valueLength, error) < 0)
1210
- return DPI_FAILURE;
1211
- memcpy(dynBytes->chunks->ptr, value, valueLength);
1212
- dynBytes->numChunks = 1;
1213
- dynBytes->chunks->length = valueLength;
1214
- bytes->ptr = dynBytes->chunks->ptr;
1215
- bytes->length = valueLength;
1216
-
1217
- // for everything else, space has already been allocated
1218
- } else {
1219
- bytes->length = valueLength;
1220
- if (valueLength > 0)
1221
- memcpy(bytes->ptr, value, valueLength);
1222
- if (var->type->sizeInBytes == 0) {
1223
- if (var->buffer.actualLength32)
1224
- var->buffer.actualLength32[pos] = valueLength;
1225
- else if (var->buffer.actualLength16)
1226
- var->buffer.actualLength16[pos] = (uint16_t) valueLength;
1227
- }
1228
- if (var->buffer.returnCode)
1229
- var->buffer.returnCode[pos] = 0;
1230
- }
1231
- data->isNull = 0;
1232
-
1233
- return DPI_SUCCESS;
1234
- }
1235
-
1236
-
1237
- //-----------------------------------------------------------------------------
1238
- // dpiVar__setFromLob() [PRIVATE]
1239
- // Set the value of the variable at the given array position from a LOB.
1240
- // A reference to the LOB is retained by the variable.
1241
- //-----------------------------------------------------------------------------
1242
- static int dpiVar__setFromLob(dpiVar *var, uint32_t pos, dpiLob *lob,
1243
- dpiError *error)
1244
- {
1245
- dpiData *data;
1246
-
1247
- // validate the LOB object
1248
- if (dpiGen__checkHandle(lob, DPI_HTYPE_LOB, "check LOB", error) < 0)
1249
- return DPI_FAILURE;
1250
-
1251
- // mark the value as not null
1252
- data = &var->buffer.externalData[pos];
1253
- data->isNull = 0;
1254
-
1255
- // if values are the same, nothing to do
1256
- if (var->buffer.references[pos].asLOB == lob)
1257
- return DPI_SUCCESS;
1258
-
1259
- // clear original value, if needed
1260
- if (var->buffer.references[pos].asLOB) {
1261
- dpiGen__setRefCount(var->buffer.references[pos].asLOB, error, -1);
1262
- var->buffer.references[pos].asLOB = NULL;
1263
- }
1264
-
1265
- // add reference to passed object
1266
- dpiGen__setRefCount(lob, error, 1);
1267
- var->buffer.references[pos].asLOB = lob;
1268
- var->buffer.data.asLobLocator[pos] = lob->locator;
1269
- data->value.asLOB = lob;
1270
- return DPI_SUCCESS;
1271
- }
1272
-
1273
-
1274
- //-----------------------------------------------------------------------------
1275
- // dpiVar__setFromObject() [PRIVATE]
1276
- // Set the value of the variable at the given array position from an object.
1277
- // The variable and position are assumed to be valid at this point. A reference
1278
- // to the object is retained by the variable.
1279
- //-----------------------------------------------------------------------------
1280
- static int dpiVar__setFromObject(dpiVar *var, uint32_t pos, dpiObject *obj,
1281
- dpiError *error)
1282
- {
1283
- dpiData *data;
1284
-
1285
- // validate the object
1286
- if (dpiGen__checkHandle(obj, DPI_HTYPE_OBJECT, "check obj", error) < 0)
1287
- return DPI_FAILURE;
1288
- if (obj->type->tdo != var->objectType->tdo)
1289
- return dpiError__set(error, "check type", DPI_ERR_WRONG_TYPE,
1290
- obj->type->schemaLength, obj->type->schema,
1291
- obj->type->nameLength, obj->type->name,
1292
- var->objectType->schemaLength, var->objectType->schema,
1293
- var->objectType->nameLength, var->objectType->name);
1294
-
1295
- // mark the value as not null
1296
- data = &var->buffer.externalData[pos];
1297
- data->isNull = 0;
1298
-
1299
- // if values are the same, nothing to do
1300
- if (var->buffer.references[pos].asObject == obj)
1301
- return DPI_SUCCESS;
1302
-
1303
- // clear original value, if needed
1304
- if (var->buffer.references[pos].asObject) {
1305
- dpiGen__setRefCount(var->buffer.references[pos].asObject, error, -1);
1306
- var->buffer.references[pos].asObject = NULL;
1307
- }
1308
-
1309
- // add reference to passed object
1310
- dpiGen__setRefCount(obj, error, 1);
1311
- var->buffer.references[pos].asObject = obj;
1312
- var->buffer.data.asObject[pos] = obj->instance;
1313
- var->buffer.objectIndicator[pos] = obj->indicator;
1314
- data->value.asObject = obj;
1315
- return DPI_SUCCESS;
1316
- }
1317
-
1318
-
1319
- //-----------------------------------------------------------------------------
1320
- // dpiVar__setFromRowid() [PRIVATE]
1321
- // Set the value of the variable at the given array position from a rowid.
1322
- // A reference to the rowid is retained by the variable.
1323
- //-----------------------------------------------------------------------------
1324
- static int dpiVar__setFromRowid(dpiVar *var, uint32_t pos, dpiRowid *rowid,
1325
- dpiError *error)
1326
- {
1327
- dpiData *data;
1328
-
1329
- // validate the rowid
1330
- if (dpiGen__checkHandle(rowid, DPI_HTYPE_ROWID, "check rowid", error) < 0)
1331
- return DPI_FAILURE;
1332
-
1333
- // mark the value as not null
1334
- data = &var->buffer.externalData[pos];
1335
- data->isNull = 0;
1336
-
1337
- // if values are the same, nothing to do
1338
- if (var->buffer.references[pos].asRowid == rowid)
1339
- return DPI_SUCCESS;
1340
-
1341
- // clear original value, if needed
1342
- if (var->buffer.references[pos].asRowid) {
1343
- dpiGen__setRefCount(var->buffer.references[pos].asRowid, error, -1);
1344
- var->buffer.references[pos].asRowid = NULL;
1345
- }
1346
-
1347
- // add reference to passed object
1348
- dpiGen__setRefCount(rowid, error, 1);
1349
- var->buffer.references[pos].asRowid = rowid;
1350
- var->buffer.data.asRowid[pos] = rowid->handle;
1351
- data->value.asRowid = rowid;
1352
- return DPI_SUCCESS;
1353
- }
1354
-
1355
-
1356
- //-----------------------------------------------------------------------------
1357
- // dpiVar__setFromStmt() [PRIVATE]
1358
- // Set the value of the variable at the given array position from a
1359
- // statement. A reference to the statement is retained by the variable.
1360
- //-----------------------------------------------------------------------------
1361
- static int dpiVar__setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt,
1362
- dpiError *error)
1363
- {
1364
- dpiData *data;
1365
-
1366
- // validate the statement
1367
- if (dpiGen__checkHandle(stmt, DPI_HTYPE_STMT, "check stmt", error) < 0)
1368
- return DPI_FAILURE;
1369
-
1370
- // mark the value as not null
1371
- data = &var->buffer.externalData[pos];
1372
- data->isNull = 0;
1373
-
1374
- // if values are the same, nothing to do
1375
- if (var->buffer.references[pos].asStmt == stmt)
1376
- return DPI_SUCCESS;
1377
-
1378
- // clear original value, if needed
1379
- if (var->buffer.references[pos].asStmt) {
1380
- dpiGen__setRefCount(var->buffer.references[pos].asStmt, error, -1);
1381
- var->buffer.references[pos].asStmt = NULL;
1382
- }
1383
-
1384
- // add reference to passed object
1385
- dpiGen__setRefCount(stmt, error, 1);
1386
- var->buffer.references[pos].asStmt = stmt;
1387
- var->buffer.data.asStmt[pos] = stmt->handle;
1388
- data->value.asStmt = stmt;
1389
- return DPI_SUCCESS;
1390
- }
1391
-
1392
-
1393
- //-----------------------------------------------------------------------------
1394
- // dpiVar__setValue() [PRIVATE]
1395
- // Sets the contents of the variable using the type specified, if possible.
1396
- //-----------------------------------------------------------------------------
1397
- int dpiVar__setValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos,
1398
- dpiData *data, dpiError *error)
1399
- {
1400
- dpiOracleTypeNum oracleTypeNum;
1401
- dpiObject *obj;
1402
-
1403
- // if value is null, no need to proceed further
1404
- // however, when binding objects a value MUST be present or OCI will
1405
- // segfault!
1406
- if (data->isNull) {
1407
- buffer->indicator[pos] = DPI_OCI_IND_NULL;
1408
- if (buffer->objectIndicator && !buffer->data.asObject[pos]) {
1409
- if (dpiObject__allocate(var->objectType, NULL, NULL, NULL, &obj,
1410
- error) < 0)
1411
- return DPI_FAILURE;
1412
- buffer->references[pos].asObject = obj;
1413
- data->value.asObject = obj;
1414
- buffer->data.asObject[pos] = obj->instance;
1415
- buffer->objectIndicator[pos] = obj->indicator;
1416
- if (buffer->objectIndicator[pos])
1417
- *((int16_t*) buffer->objectIndicator[pos]) = DPI_OCI_IND_NULL;
1418
- }
1419
- return DPI_SUCCESS;
1420
- }
1421
-
1422
- // transform the various types
1423
- buffer->indicator[pos] = DPI_OCI_IND_NOTNULL;
1424
- oracleTypeNum = var->type->oracleTypeNum;
1425
- switch (var->nativeTypeNum) {
1426
- case DPI_NATIVE_TYPE_INT64:
1427
- case DPI_NATIVE_TYPE_UINT64:
1428
- switch (oracleTypeNum) {
1429
- case DPI_ORACLE_TYPE_NATIVE_INT:
1430
- buffer->data.asInt64[pos] = data->value.asInt64;
1431
- return DPI_SUCCESS;
1432
- case DPI_ORACLE_TYPE_NATIVE_UINT:
1433
- buffer->data.asUint64[pos] = data->value.asUint64;
1434
- return DPI_SUCCESS;
1435
- case DPI_ORACLE_TYPE_NUMBER:
1436
- if (var->nativeTypeNum == DPI_NATIVE_TYPE_INT64)
1437
- return dpiDataBuffer__toOracleNumberFromInteger(
1438
- &data->value, error,
1439
- &buffer->data.asNumber[pos]);
1440
- return dpiDataBuffer__toOracleNumberFromUnsignedInteger(
1441
- &data->value, error, &buffer->data.asNumber[pos]);
1442
- default:
1443
- break;
1444
- }
1445
- break;
1446
- case DPI_NATIVE_TYPE_FLOAT:
1447
- buffer->data.asFloat[pos] = data->value.asFloat;
1448
- return DPI_SUCCESS;
1449
- case DPI_NATIVE_TYPE_DOUBLE:
1450
- switch (oracleTypeNum) {
1451
- case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
1452
- buffer->data.asDouble[pos] = data->value.asDouble;
1453
- return DPI_SUCCESS;
1454
- case DPI_ORACLE_TYPE_NUMBER:
1455
- return dpiDataBuffer__toOracleNumberFromDouble(
1456
- &data->value, error, &buffer->data.asNumber[pos]);
1457
- case DPI_ORACLE_TYPE_TIMESTAMP:
1458
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
1459
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
1460
- return dpiDataBuffer__toOracleTimestampFromDouble(
1461
- &data->value, var->env, error,
1462
- buffer->data.asTimestamp[pos]);
1463
- default:
1464
- break;
1465
- }
1466
- break;
1467
- case DPI_NATIVE_TYPE_BYTES:
1468
- if (oracleTypeNum == DPI_ORACLE_TYPE_NUMBER)
1469
- return dpiDataBuffer__toOracleNumberFromText(&data->value,
1470
- var->env, error, &buffer->data.asNumber[pos]);
1471
- if (buffer->actualLength32)
1472
- buffer->actualLength32[pos] = data->value.asBytes.length;
1473
- else if (buffer->actualLength16)
1474
- buffer->actualLength16[pos] =
1475
- (uint16_t) data->value.asBytes.length;
1476
- if (buffer->returnCode)
1477
- buffer->returnCode[pos] = 0;
1478
- break;
1479
- case DPI_NATIVE_TYPE_TIMESTAMP:
1480
- if (oracleTypeNum == DPI_ORACLE_TYPE_DATE)
1481
- return dpiDataBuffer__toOracleDate(&data->value,
1482
- &buffer->data.asDate[pos]);
1483
- else if (oracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP)
1484
- return dpiDataBuffer__toOracleTimestamp(&data->value,
1485
- var->env, error, buffer->data.asTimestamp[pos], 0);
1486
- else if (oracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_TZ ||
1487
- oracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_LTZ)
1488
- return dpiDataBuffer__toOracleTimestamp(&data->value,
1489
- var->env, error, buffer->data.asTimestamp[pos], 1);
1490
- break;
1491
- case DPI_NATIVE_TYPE_INTERVAL_DS:
1492
- return dpiDataBuffer__toOracleIntervalDS(&data->value, var->env,
1493
- error, buffer->data.asInterval[pos]);
1494
- case DPI_NATIVE_TYPE_INTERVAL_YM:
1495
- return dpiDataBuffer__toOracleIntervalYM(&data->value, var->env,
1496
- error, buffer->data.asInterval[pos]);
1497
- case DPI_NATIVE_TYPE_BOOLEAN:
1498
- buffer->data.asBoolean[pos] = data->value.asBoolean;
1499
- return DPI_SUCCESS;
1500
- default:
1501
- break;
1502
- }
1503
- return DPI_SUCCESS;
1504
- }
1505
-
1506
-
1507
- //-----------------------------------------------------------------------------
1508
- // dpiVar__validateTypes() [PRIVATE]
1509
- // Validate that the Oracle type and the native type are compatible with
1510
- // each other when the native type is not already the default native type.
1511
- //-----------------------------------------------------------------------------
1512
- static int dpiVar__validateTypes(const dpiOracleType *oracleType,
1513
- dpiNativeTypeNum nativeTypeNum, dpiError *error)
1514
- {
1515
- switch (oracleType->oracleTypeNum) {
1516
- case DPI_ORACLE_TYPE_TIMESTAMP:
1517
- case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
1518
- case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
1519
- if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE)
1520
- return DPI_SUCCESS;
1521
- break;
1522
- case DPI_ORACLE_TYPE_NUMBER:
1523
- if (nativeTypeNum == DPI_NATIVE_TYPE_INT64 ||
1524
- nativeTypeNum == DPI_NATIVE_TYPE_UINT64 ||
1525
- nativeTypeNum == DPI_NATIVE_TYPE_BYTES)
1526
- return DPI_SUCCESS;
1527
- break;
1528
- default:
1529
- break;
1530
- }
1531
- return dpiError__set(error, "validate types", DPI_ERR_UNHANDLED_CONVERSION,
1532
- oracleType->oracleTypeNum, nativeTypeNum);
1533
- }
1534
-
1535
-
1536
- //-----------------------------------------------------------------------------
1537
- // dpiVar_addRef() [PUBLIC]
1538
- // Add a reference to the variable.
1539
- //-----------------------------------------------------------------------------
1540
- int dpiVar_addRef(dpiVar *var)
1541
- {
1542
- return dpiGen__addRef(var, DPI_HTYPE_VAR, __func__);
1543
- }
1544
-
1545
-
1546
- //-----------------------------------------------------------------------------
1547
- // dpiVar_copyData() [PUBLIC]
1548
- // Copy the data from the source variable to the target variable at the given
1549
- // array position. The variables must use the same native type. If the
1550
- // variables contain variable length data, the source length must not exceed
1551
- // the target allocated memory.
1552
- //-----------------------------------------------------------------------------
1553
- int dpiVar_copyData(dpiVar *var, uint32_t pos, dpiVar *sourceVar,
1554
- uint32_t sourcePos)
1555
- {
1556
- dpiData *sourceData;
1557
- dpiError error;
1558
- int status;
1559
-
1560
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1561
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1562
- if (dpiGen__checkHandle(sourceVar, DPI_HTYPE_VAR, "check source var",
1563
- &error) < 0)
1564
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1565
- if (sourcePos >= sourceVar->buffer.maxArraySize) {
1566
- dpiError__set(&error, "check source size",
1567
- DPI_ERR_INVALID_ARRAY_POSITION, sourcePos,
1568
- sourceVar->buffer.maxArraySize);
1569
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1570
- }
1571
- if (var->nativeTypeNum != sourceVar->nativeTypeNum) {
1572
- dpiError__set(&error, "check types match", DPI_ERR_NOT_SUPPORTED);
1573
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1574
- }
1575
- sourceData = &sourceVar->buffer.externalData[sourcePos];
1576
- status = dpiVar__copyData(var, pos, sourceData, &error);
1577
- return dpiGen__endPublicFn(var, status, &error);
1578
- }
1579
-
1580
-
1581
- //-----------------------------------------------------------------------------
1582
- // dpiVar_getNumElementsInArray() [PUBLIC]
1583
- // Return the actual number of elements in the array. This value is only
1584
- // relevant if the variable is bound as an array.
1585
- //-----------------------------------------------------------------------------
1586
- int dpiVar_getNumElementsInArray(dpiVar *var, uint32_t *numElements)
1587
- {
1588
- dpiError error;
1589
-
1590
- if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0)
1591
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1592
- DPI_CHECK_PTR_NOT_NULL(var, numElements)
1593
- if (var->dynBindBuffers)
1594
- *numElements = var->dynBindBuffers->actualArraySize;
1595
- else *numElements = var->buffer.actualArraySize;
1596
- return dpiGen__endPublicFn(var, DPI_SUCCESS, &error);
1597
- }
1598
-
1599
- //-----------------------------------------------------------------------------
1600
- // dpiVar_getReturnedData() [PUBLIC]
1601
- // Return a pointer to the array of dpiData structures allocated for the
1602
- // given row that have been returned by a DML returning statement. The number
1603
- // of returned rows is also provided. If the bind variable had no data
1604
- // returned, the number of rows returned will be 0 and the pointer to the array
1605
- // of dpiData structures will be NULL. This will also be the case if the
1606
- // variable was only bound IN or was not bound to a DML returning statement.
1607
- // There is no way to differentiate between the two.
1608
- //-----------------------------------------------------------------------------
1609
- int dpiVar_getReturnedData(dpiVar *var, uint32_t pos, uint32_t *numElements,
1610
- dpiData **data)
1611
- {
1612
- dpiError error;
1613
-
1614
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1615
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1616
- DPI_CHECK_PTR_NOT_NULL(var, numElements)
1617
- DPI_CHECK_PTR_NOT_NULL(var, data)
1618
- if (var->dynBindBuffers) {
1619
- *numElements = var->dynBindBuffers[pos].actualArraySize;
1620
- *data = var->dynBindBuffers[pos].externalData;
1621
- } else {
1622
- *numElements = 0;
1623
- *data = NULL;
1624
- }
1625
- return dpiGen__endPublicFn(var, DPI_SUCCESS, &error);
1626
- }
1627
-
1628
-
1629
-
1630
- //-----------------------------------------------------------------------------
1631
- // dpiVar_getSizeInBytes() [PUBLIC]
1632
- // Returns the size in bytes of the buffer allocated for the variable.
1633
- //-----------------------------------------------------------------------------
1634
- int dpiVar_getSizeInBytes(dpiVar *var, uint32_t *sizeInBytes)
1635
- {
1636
- dpiError error;
1637
-
1638
- if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0)
1639
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1640
- DPI_CHECK_PTR_NOT_NULL(var, sizeInBytes)
1641
- *sizeInBytes = var->sizeInBytes;
1642
- return dpiGen__endPublicFn(var, DPI_SUCCESS, &error);
1643
- }
1644
-
1645
-
1646
- //-----------------------------------------------------------------------------
1647
- // dpiVar_release() [PUBLIC]
1648
- // Release a reference to the variable.
1649
- //-----------------------------------------------------------------------------
1650
- int dpiVar_release(dpiVar *var)
1651
- {
1652
- return dpiGen__release(var, DPI_HTYPE_VAR, __func__);
1653
- }
1654
-
1655
-
1656
- //-----------------------------------------------------------------------------
1657
- // dpiVar_setFromBytes() [PUBLIC]
1658
- // Set the value of the variable at the given array position from a byte
1659
- // string. Checks on the array position, the size of the string and the type of
1660
- // variable will be made. The byte string is not retained in any way. A copy
1661
- // will be made into buffers allocated by ODPI-C.
1662
- //-----------------------------------------------------------------------------
1663
- int dpiVar_setFromBytes(dpiVar *var, uint32_t pos, const char *value,
1664
- uint32_t valueLength)
1665
- {
1666
- dpiError error;
1667
- int status;
1668
-
1669
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1670
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1671
- DPI_CHECK_PTR_NOT_NULL(var, value)
1672
- if (var->nativeTypeNum != DPI_NATIVE_TYPE_BYTES &&
1673
- var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) {
1674
- dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED);
1675
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1676
- }
1677
- if (valueLength > DPI_MAX_VAR_BUFFER_SIZE) {
1678
- dpiError__set(&error, "check buffer", DPI_ERR_BUFFER_SIZE_TOO_LARGE,
1679
- valueLength, DPI_MAX_VAR_BUFFER_SIZE);
1680
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1681
- }
1682
- status = dpiVar__setFromBytes(var, pos, value, valueLength, &error);
1683
- return dpiGen__endPublicFn(var, status, &error);
1684
- }
1685
-
1686
-
1687
- //-----------------------------------------------------------------------------
1688
- // dpiVar_setFromLob() [PUBLIC]
1689
- // Set the value of the variable at the given array position from a LOB.
1690
- // Checks on the array position and the validity of the passed handle. A
1691
- // reference to the LOB is retained by the variable.
1692
- //-----------------------------------------------------------------------------
1693
- int dpiVar_setFromLob(dpiVar *var, uint32_t pos, dpiLob *lob)
1694
- {
1695
- dpiError error;
1696
- int status;
1697
-
1698
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1699
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1700
- if (var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) {
1701
- dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED);
1702
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1703
- }
1704
- status = dpiVar__setFromLob(var, pos, lob, &error);
1705
- return dpiGen__endPublicFn(var, status, &error);
1706
- }
1707
-
1708
-
1709
- //-----------------------------------------------------------------------------
1710
- // dpiVar_setFromObject() [PUBLIC]
1711
- // Set the value of the variable at the given array position from an object.
1712
- // Checks on the array position and the validity of the passed handle. A
1713
- // reference to the object is retained by the variable.
1714
- //-----------------------------------------------------------------------------
1715
- int dpiVar_setFromObject(dpiVar *var, uint32_t pos, dpiObject *obj)
1716
- {
1717
- dpiError error;
1718
- int status;
1719
-
1720
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1721
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1722
- if (var->nativeTypeNum != DPI_NATIVE_TYPE_OBJECT) {
1723
- dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED);
1724
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1725
- }
1726
- status = dpiVar__setFromObject(var, pos, obj, &error);
1727
- return dpiGen__endPublicFn(var, status, &error);
1728
- }
1729
-
1730
-
1731
- //-----------------------------------------------------------------------------
1732
- // dpiVar_setFromRowid() [PUBLIC]
1733
- // Set the value of the variable at the given array position from a rowid.
1734
- // Checks on the array position and the validity of the passed handle. A
1735
- // reference to the rowid is retained by the variable.
1736
- //-----------------------------------------------------------------------------
1737
- int dpiVar_setFromRowid(dpiVar *var, uint32_t pos, dpiRowid *rowid)
1738
- {
1739
- dpiError error;
1740
- int status;
1741
-
1742
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1743
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1744
- if (var->nativeTypeNum != DPI_NATIVE_TYPE_ROWID) {
1745
- dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED);
1746
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1747
- }
1748
- status = dpiVar__setFromRowid(var, pos, rowid, &error);
1749
- return dpiGen__endPublicFn(var, status, &error);
1750
- }
1751
-
1752
-
1753
- //-----------------------------------------------------------------------------
1754
- // dpiVar_setFromStmt() [PUBLIC]
1755
- // Set the value of the variable at the given array position from a
1756
- // statement. Checks on the array position and the validity of the passed
1757
- // handle. A reference to the statement is retained by the variable.
1758
- //-----------------------------------------------------------------------------
1759
- int dpiVar_setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt)
1760
- {
1761
- dpiError error;
1762
- int status;
1763
-
1764
- if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0)
1765
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1766
- if (var->nativeTypeNum != DPI_NATIVE_TYPE_STMT) {
1767
- dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED);
1768
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1769
- }
1770
- status = dpiVar__setFromStmt(var, pos, stmt, &error);
1771
- return dpiGen__endPublicFn(var, status, &error);
1772
- }
1773
-
1774
-
1775
- //-----------------------------------------------------------------------------
1776
- // dpiVar_setNumElementsInArray() [PUBLIC]
1777
- // Set the number of elements in the array (different from the number of
1778
- // allocated elements).
1779
- //-----------------------------------------------------------------------------
1780
- int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements)
1781
- {
1782
- dpiError error;
1783
-
1784
- if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0)
1785
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1786
- if (numElements > var->buffer.maxArraySize) {
1787
- dpiError__set(&error, "check num elements",
1788
- DPI_ERR_ARRAY_SIZE_TOO_SMALL, var->buffer.maxArraySize);
1789
- return dpiGen__endPublicFn(var, DPI_FAILURE, &error);
1790
- }
1791
- var->buffer.actualArraySize = numElements;
1792
- return dpiGen__endPublicFn(var, DPI_SUCCESS, &error);
1793
- }
1794
-