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.
- package/CHANGELOG.md +135 -8
- package/README.md +6 -4
- package/build/Release/oracledb-abi48-darwin-x64.node +0 -0
- package/build/Release/oracledb-abi48-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi48-linux-x64.node +0 -0
- package/build/Release/oracledb-abi48-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi48-win32-x64.node +0 -0
- package/build/Release/oracledb-abi48-win32-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi57-darwin-x64.node +0 -0
- package/build/Release/oracledb-abi57-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi57-linux-x64.node +0 -0
- package/build/Release/oracledb-abi57-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi57-win32-x64.node +0 -0
- package/build/Release/oracledb-abi57-win32-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi64-darwin-x64.node +0 -0
- package/build/Release/oracledb-abi64-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi64-linux-x64.node +0 -0
- package/build/Release/oracledb-abi64-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi64-win32-x64.node +0 -0
- package/build/Release/oracledb-abi64-win32-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi67-darwin-x64.node +0 -0
- package/build/Release/oracledb-abi67-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi67-linux-x64.node +0 -0
- package/build/Release/oracledb-abi67-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-abi67-win32-x64.node +0 -0
- package/build/Release/oracledb-abi67-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +18 -4
- package/lib/oracledb.js +44 -92
- package/lib/pool.js +36 -2
- package/lib/sodaCollection.js +1 -1
- package/lib/sodaDatabase.js +1 -1
- package/lib/util.js +82 -5
- package/package/README.md +32 -101
- package/package/install.js +139 -0
- package/package/prunebinaries.js +51 -0
- package/package.json +4 -11
- package/binding.gyp +0 -162
- package/lib/rel.txt +0 -1
- package/odpi/.npmignore +0 -4
- package/odpi/LICENSE.md +0 -218
- package/odpi/README.md +0 -61
- package/odpi/embed/README.md +0 -4
- package/odpi/embed/dpi.c +0 -50
- package/odpi/include/dpi.h +0 -1748
- package/odpi/src/dpiConn.c +0 -2089
- package/odpi/src/dpiContext.c +0 -296
- package/odpi/src/dpiData.c +0 -797
- package/odpi/src/dpiDebug.c +0 -184
- package/odpi/src/dpiDeqOptions.c +0 -370
- package/odpi/src/dpiEnqOptions.c +0 -174
- package/odpi/src/dpiEnv.c +0 -189
- package/odpi/src/dpiError.c +0 -204
- package/odpi/src/dpiErrorMessages.h +0 -86
- package/odpi/src/dpiGen.c +0 -303
- package/odpi/src/dpiGlobal.c +0 -292
- package/odpi/src/dpiHandleList.c +0 -117
- package/odpi/src/dpiHandlePool.c +0 -118
- package/odpi/src/dpiImpl.h +0 -1707
- package/odpi/src/dpiLob.c +0 -506
- package/odpi/src/dpiMsgProps.c +0 -386
- package/odpi/src/dpiObject.c +0 -897
- package/odpi/src/dpiObjectAttr.c +0 -115
- package/odpi/src/dpiObjectType.c +0 -326
- package/odpi/src/dpiOci.c +0 -3527
- package/odpi/src/dpiOracleType.c +0 -492
- package/odpi/src/dpiPool.c +0 -549
- package/odpi/src/dpiRowid.c +0 -136
- package/odpi/src/dpiSodaColl.c +0 -685
- package/odpi/src/dpiSodaCollCursor.c +0 -143
- package/odpi/src/dpiSodaDb.c +0 -432
- package/odpi/src/dpiSodaDoc.c +0 -230
- package/odpi/src/dpiSodaDocCursor.c +0 -143
- package/odpi/src/dpiStmt.c +0 -1797
- package/odpi/src/dpiSubscr.c +0 -674
- package/odpi/src/dpiUtils.c +0 -410
- package/odpi/src/dpiVar.c +0 -1794
- package/package/MAKEPKG.BAT +0 -156
- package/package/Makefile +0 -85
- package/package/createpackage.js +0 -186
- package/package/extractpackage.js +0 -76
- package/package/getversion.js +0 -37
- package/package/oracledbinstall.js +0 -497
- package/package/package.json +0 -54
- package/package/util.js +0 -286
- package/src/njsCommon.cpp +0 -1055
- package/src/njsCommon.h +0 -484
- package/src/njsConnection.cpp +0 -2926
- package/src/njsConnection.h +0 -227
- package/src/njsIntLob.cpp +0 -618
- package/src/njsIntLob.h +0 -179
- package/src/njsMessages.cpp +0 -122
- package/src/njsMessages.h +0 -118
- package/src/njsOracle.cpp +0 -1274
- package/src/njsOracle.h +0 -237
- package/src/njsPool.cpp +0 -482
- package/src/njsPool.h +0 -132
- package/src/njsResultSet.cpp +0 -478
- package/src/njsResultSet.h +0 -120
- package/src/njsSodaCollection.cpp +0 -507
- package/src/njsSodaCollection.h +0 -128
- package/src/njsSodaDatabase.cpp +0 -335
- package/src/njsSodaDatabase.h +0 -108
- package/src/njsSodaDocCursor.cpp +0 -203
- package/src/njsSodaDocCursor.h +0 -94
- package/src/njsSodaDocument.cpp +0 -412
- package/src/njsSodaDocument.h +0 -105
- package/src/njsSodaOperation.cpp +0 -557
- package/src/njsSodaOperation.h +0 -123
- package/src/njsSubscription.cpp +0 -388
- package/src/njsSubscription.h +0 -111
- package/src/njsUtils.cpp +0 -158
- 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
|
-
|