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/dpiGen.c
DELETED
|
@@ -1,303 +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
|
-
// dpiGen.c
|
|
14
|
-
// Generic routines for managing the types available through public APIs.
|
|
15
|
-
//-----------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
#include "dpiImpl.h"
|
|
18
|
-
|
|
19
|
-
//-----------------------------------------------------------------------------
|
|
20
|
-
// definition of handle types
|
|
21
|
-
//-----------------------------------------------------------------------------
|
|
22
|
-
static const dpiTypeDef dpiAllTypeDefs[DPI_HTYPE_MAX - DPI_HTYPE_NONE - 1] = {
|
|
23
|
-
{
|
|
24
|
-
"dpiConn", // name
|
|
25
|
-
sizeof(dpiConn), // size of structure
|
|
26
|
-
0x49DC600C, // check integer
|
|
27
|
-
(dpiTypeFreeProc) dpiConn__free
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"dpiPool", // name
|
|
31
|
-
sizeof(dpiPool), // size of structure
|
|
32
|
-
0x18E1AA4B, // check integer
|
|
33
|
-
(dpiTypeFreeProc) dpiPool__free
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"dpiStmt", // name
|
|
37
|
-
sizeof(dpiStmt), // size of structure
|
|
38
|
-
0x31B02B2E, // check integer
|
|
39
|
-
(dpiTypeFreeProc) dpiStmt__free
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"dpiVar", // name
|
|
43
|
-
sizeof(dpiVar), // size of structure
|
|
44
|
-
0x2AE8C6DC, // check integer
|
|
45
|
-
(dpiTypeFreeProc) dpiVar__free
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"dpiLob", // name
|
|
49
|
-
sizeof(dpiLob), // size of structure
|
|
50
|
-
0xD8F31746, // check integer
|
|
51
|
-
(dpiTypeFreeProc) dpiLob__free
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"dpiObject", // name
|
|
55
|
-
sizeof(dpiObject), // size of structure
|
|
56
|
-
0x38616080, // check integer
|
|
57
|
-
(dpiTypeFreeProc) dpiObject__free
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"dpiObjectType", // name
|
|
61
|
-
sizeof(dpiObjectType), // size of structure
|
|
62
|
-
0x86036059, // check integer
|
|
63
|
-
(dpiTypeFreeProc) dpiObjectType__free
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"dpiObjectAttr", // name
|
|
67
|
-
sizeof(dpiObjectAttr), // size of structure
|
|
68
|
-
0xea6d5dde, // check integer
|
|
69
|
-
(dpiTypeFreeProc) dpiObjectAttr__free
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"dpiSubscr", // name
|
|
73
|
-
sizeof(dpiSubscr), // size of structure
|
|
74
|
-
0xa415a1c0, // check integer
|
|
75
|
-
(dpiTypeFreeProc) dpiSubscr__free
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"dpiDeqOptions", // name
|
|
79
|
-
sizeof(dpiDeqOptions), // size of structure
|
|
80
|
-
0x70ee498d, // check integer
|
|
81
|
-
(dpiTypeFreeProc) dpiDeqOptions__free
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"dpiEnqOptions", // name
|
|
85
|
-
sizeof(dpiEnqOptions), // size of structure
|
|
86
|
-
0x682f3946, // check integer
|
|
87
|
-
(dpiTypeFreeProc) dpiEnqOptions__free
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"dpiMsgProps", // name
|
|
91
|
-
sizeof(dpiMsgProps), // size of structure
|
|
92
|
-
0xa2b75506, // check integer
|
|
93
|
-
(dpiTypeFreeProc) dpiMsgProps__free
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"dpiRowid", // name
|
|
97
|
-
sizeof(dpiRowid), // size of structure
|
|
98
|
-
0x6204fa04, // check integer
|
|
99
|
-
(dpiTypeFreeProc) dpiRowid__free
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
"dpiContext", // name
|
|
103
|
-
sizeof(dpiContext), // size of structure
|
|
104
|
-
0xd81b9181, // check integer
|
|
105
|
-
NULL
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"dpiSodaColl", // name
|
|
109
|
-
sizeof(dpiSodaColl), // size of structure
|
|
110
|
-
0x3684db22, // check integer
|
|
111
|
-
(dpiTypeFreeProc) dpiSodaColl__free
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"dpiSodaCollCursor", // name
|
|
115
|
-
sizeof(dpiSodaCollCursor), // size of structure
|
|
116
|
-
0xcdc73b86, // check integer
|
|
117
|
-
(dpiTypeFreeProc) dpiSodaCollCursor__free
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
"dpiSodaDb", // name
|
|
121
|
-
sizeof(dpiSodaDb), // size of structure
|
|
122
|
-
0x1f386121, // check integer
|
|
123
|
-
(dpiTypeFreeProc) dpiSodaDb__free
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
"dpiSodaDoc", // name
|
|
127
|
-
sizeof(dpiSodaDoc), // size of structure
|
|
128
|
-
0xaffd950a, // check integer
|
|
129
|
-
(dpiTypeFreeProc) dpiSodaDoc__free
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
"dpiSodaDocCursor", // name
|
|
133
|
-
sizeof(dpiSodaDocCursor), // size of structure
|
|
134
|
-
0x80ceb83b, // check integer
|
|
135
|
-
(dpiTypeFreeProc) dpiSodaDocCursor__free
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
//-----------------------------------------------------------------------------
|
|
141
|
-
// dpiGen__addRef() [INTERNAL]
|
|
142
|
-
// Add a reference to the specified handle.
|
|
143
|
-
//-----------------------------------------------------------------------------
|
|
144
|
-
int dpiGen__addRef(void *ptr, dpiHandleTypeNum typeNum, const char *fnName)
|
|
145
|
-
{
|
|
146
|
-
dpiError error;
|
|
147
|
-
|
|
148
|
-
if (dpiGen__startPublicFn(ptr, typeNum, fnName, 0, &error) < 0)
|
|
149
|
-
return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error);
|
|
150
|
-
dpiGen__setRefCount(ptr, &error, 1);
|
|
151
|
-
return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
//-----------------------------------------------------------------------------
|
|
156
|
-
// dpiGen__allocate() [INTERNAL]
|
|
157
|
-
// Allocate memory for the specified type and initialize the base fields. The
|
|
158
|
-
// type specified is assumed to be valid. If the environment is specified, use
|
|
159
|
-
// it; otherwise, create a new one. No additional initialization is performed.
|
|
160
|
-
//-----------------------------------------------------------------------------
|
|
161
|
-
int dpiGen__allocate(dpiHandleTypeNum typeNum, dpiEnv *env, void **handle,
|
|
162
|
-
dpiError *error)
|
|
163
|
-
{
|
|
164
|
-
const dpiTypeDef *typeDef;
|
|
165
|
-
dpiBaseType *value;
|
|
166
|
-
|
|
167
|
-
typeDef = &dpiAllTypeDefs[typeNum - DPI_HTYPE_NONE - 1];
|
|
168
|
-
if (dpiUtils__allocateMemory(1, typeDef->size, 1, "allocate handle",
|
|
169
|
-
(void**) &value, error) < 0)
|
|
170
|
-
return DPI_FAILURE;
|
|
171
|
-
value->typeDef = typeDef;
|
|
172
|
-
value->checkInt = typeDef->checkInt;
|
|
173
|
-
value->refCount = 1;
|
|
174
|
-
if (!env && typeNum != DPI_HTYPE_CONTEXT) {
|
|
175
|
-
if (dpiUtils__allocateMemory(1, sizeof(dpiEnv), 1, "allocate env",
|
|
176
|
-
(void**) &env, error) < 0) {
|
|
177
|
-
dpiUtils__freeMemory(value);
|
|
178
|
-
return DPI_FAILURE;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
value->env = env;
|
|
182
|
-
if (dpiDebugLevel & DPI_DEBUG_LEVEL_REFS)
|
|
183
|
-
dpiDebug__print("ref %p (%s) -> 1 [NEW]\n", value, typeDef->name);
|
|
184
|
-
|
|
185
|
-
*handle = value;
|
|
186
|
-
return DPI_SUCCESS;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
//-----------------------------------------------------------------------------
|
|
191
|
-
// dpiGen__checkHandle() [INTERNAL]
|
|
192
|
-
// Check that the specific handle is valid, that it matches the type
|
|
193
|
-
// requested and that the check integer is still in place.
|
|
194
|
-
//-----------------------------------------------------------------------------
|
|
195
|
-
int dpiGen__checkHandle(const void *ptr, dpiHandleTypeNum typeNum,
|
|
196
|
-
const char *action, dpiError *error)
|
|
197
|
-
{
|
|
198
|
-
dpiBaseType *value = (dpiBaseType*) ptr;
|
|
199
|
-
const dpiTypeDef *typeDef;
|
|
200
|
-
|
|
201
|
-
typeDef = &dpiAllTypeDefs[typeNum - DPI_HTYPE_NONE - 1];
|
|
202
|
-
if (!ptr || value->typeDef != typeDef ||
|
|
203
|
-
value->checkInt != typeDef->checkInt)
|
|
204
|
-
return dpiError__set(error, action, DPI_ERR_INVALID_HANDLE,
|
|
205
|
-
typeDef->name);
|
|
206
|
-
return DPI_SUCCESS;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
//-----------------------------------------------------------------------------
|
|
211
|
-
// dpiGen__endPublicFn() [INTERNAL]
|
|
212
|
-
// This method should be the last call made in any public method using an
|
|
213
|
-
// ODPI-C handle (other than dpiContext which is handled differently).
|
|
214
|
-
//-----------------------------------------------------------------------------
|
|
215
|
-
int dpiGen__endPublicFn(const void *ptr, int returnValue, dpiError *error)
|
|
216
|
-
{
|
|
217
|
-
if (dpiDebugLevel & DPI_DEBUG_LEVEL_FNS)
|
|
218
|
-
dpiDebug__print("fn end %s(%p) -> %d\n", error->buffer->fnName, ptr,
|
|
219
|
-
returnValue);
|
|
220
|
-
if (error->handle)
|
|
221
|
-
dpiHandlePool__release(error->env->errorHandles, error->handle, error);
|
|
222
|
-
|
|
223
|
-
return returnValue;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
//-----------------------------------------------------------------------------
|
|
228
|
-
// dpiGen__release() [INTERNAL]
|
|
229
|
-
// Release a reference to the specified handle. If the reference count
|
|
230
|
-
// reaches zero, the resources associated with the handle are released and
|
|
231
|
-
// the memory associated with the handle is freed. Any internal references
|
|
232
|
-
// held to other handles are also released.
|
|
233
|
-
//-----------------------------------------------------------------------------
|
|
234
|
-
int dpiGen__release(void *ptr, dpiHandleTypeNum typeNum, const char *fnName)
|
|
235
|
-
{
|
|
236
|
-
dpiError error;
|
|
237
|
-
|
|
238
|
-
if (dpiGen__startPublicFn(ptr, typeNum, fnName, 1, &error) < 0)
|
|
239
|
-
return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error);
|
|
240
|
-
dpiGen__setRefCount(ptr, &error, -1);
|
|
241
|
-
return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
//-----------------------------------------------------------------------------
|
|
246
|
-
// dpiGen__setRefCount() [INTERNAL]
|
|
247
|
-
// Increase or decrease the reference count by the given amount. The handle
|
|
248
|
-
// is assumed to be valid at this point. If the environment is in threaded
|
|
249
|
-
// mode, acquire the mutex first before making any adjustments to the reference
|
|
250
|
-
// count. If the operation sets the reference count to zero, release all
|
|
251
|
-
// resources and free the memory associated with the structure.
|
|
252
|
-
//-----------------------------------------------------------------------------
|
|
253
|
-
void dpiGen__setRefCount(void *ptr, dpiError *error, int increment)
|
|
254
|
-
{
|
|
255
|
-
dpiBaseType *value = (dpiBaseType*) ptr;
|
|
256
|
-
unsigned localRefCount;
|
|
257
|
-
|
|
258
|
-
// if threaded need to protect modification of the refCount with a mutex;
|
|
259
|
-
// also ensure that if the reference count reaches zero that it is
|
|
260
|
-
// immediately marked invalid in order to avoid race conditions
|
|
261
|
-
if (value->env->threaded)
|
|
262
|
-
dpiMutex__acquire(value->env->mutex);
|
|
263
|
-
value->refCount += increment;
|
|
264
|
-
localRefCount = value->refCount;
|
|
265
|
-
if (localRefCount == 0)
|
|
266
|
-
dpiUtils__clearMemory(&value->checkInt, sizeof(value->checkInt));
|
|
267
|
-
if (value->env->threaded)
|
|
268
|
-
dpiMutex__release(value->env->mutex);
|
|
269
|
-
|
|
270
|
-
// reference count debugging
|
|
271
|
-
if (dpiDebugLevel & DPI_DEBUG_LEVEL_REFS)
|
|
272
|
-
dpiDebug__print("ref %p (%s) -> %d\n", ptr, value->typeDef->name,
|
|
273
|
-
localRefCount);
|
|
274
|
-
|
|
275
|
-
// if the refCount has reached zero, call the free routine
|
|
276
|
-
if (localRefCount == 0)
|
|
277
|
-
(*value->typeDef->freeProc)(value, error);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
//-----------------------------------------------------------------------------
|
|
282
|
-
// dpiGen__startPublicFn() [INTERNAL]
|
|
283
|
-
// This method should be the first call made in any public method using an
|
|
284
|
-
// ODPI-C handle (other than dpiContext which is handled differently). The
|
|
285
|
-
// handle is checked for validity and an error handle is acquired for use in
|
|
286
|
-
// all subsequent calls.
|
|
287
|
-
//-----------------------------------------------------------------------------
|
|
288
|
-
int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum,
|
|
289
|
-
const char *fnName, int needErrorHandle, dpiError *error)
|
|
290
|
-
{
|
|
291
|
-
dpiBaseType *value = (dpiBaseType*) ptr;
|
|
292
|
-
|
|
293
|
-
if (dpiDebugLevel & DPI_DEBUG_LEVEL_FNS)
|
|
294
|
-
dpiDebug__print("fn start %s(%p)\n", fnName, ptr);
|
|
295
|
-
if (dpiGlobal__initError(fnName, error) < 0)
|
|
296
|
-
return DPI_FAILURE;
|
|
297
|
-
if (dpiGen__checkHandle(ptr, typeNum, "check main handle", error) < 0)
|
|
298
|
-
return DPI_FAILURE;
|
|
299
|
-
if (needErrorHandle && dpiEnv__initError(value->env, error) < 0)
|
|
300
|
-
return DPI_FAILURE;
|
|
301
|
-
return DPI_SUCCESS;
|
|
302
|
-
}
|
|
303
|
-
|
package/odpi/src/dpiGlobal.c
DELETED
|
@@ -1,292 +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
|
-
// dpiGlobal.c
|
|
14
|
-
// Global environment used for managing errors in a thread safe manner as
|
|
15
|
-
// well as for looking up encodings.
|
|
16
|
-
//-----------------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
#include "dpiImpl.h"
|
|
19
|
-
|
|
20
|
-
// cross platform way of defining an initializer that runs at application
|
|
21
|
-
// startup (similar to what is done for the constructor calls for static C++
|
|
22
|
-
// objects)
|
|
23
|
-
#if defined(_MSC_VER)
|
|
24
|
-
#pragma section(".CRT$XCU", read)
|
|
25
|
-
#define DPI_INITIALIZER_HELPER(f, p) \
|
|
26
|
-
static void f(void); \
|
|
27
|
-
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
|
28
|
-
__pragma(comment(linker,"/include:" p #f "_")) \
|
|
29
|
-
static void f(void)
|
|
30
|
-
#ifdef _WIN64
|
|
31
|
-
#define DPI_INITIALIZER(f) DPI_INITIALIZER_HELPER(f, "")
|
|
32
|
-
#else
|
|
33
|
-
#define DPI_INITIALIZER(f) DPI_INITIALIZER_HELPER(f, "_")
|
|
34
|
-
#endif
|
|
35
|
-
#else
|
|
36
|
-
#define DPI_INITIALIZER(f) \
|
|
37
|
-
static void f(void) __attribute__((constructor)); \
|
|
38
|
-
static void f(void)
|
|
39
|
-
#endif
|
|
40
|
-
|
|
41
|
-
// a global OCI environment is used for managing error buffers in a thread-safe
|
|
42
|
-
// manner; each thread is given its own error buffer; OCI error handles,
|
|
43
|
-
// though, must be created within the OCI environment created for use by
|
|
44
|
-
// standalone connections and session pools
|
|
45
|
-
static void *dpiGlobalEnvHandle = NULL;
|
|
46
|
-
static void *dpiGlobalErrorHandle = NULL;
|
|
47
|
-
static void *dpiGlobalThreadKey = NULL;
|
|
48
|
-
static dpiErrorBuffer dpiGlobalErrorBuffer;
|
|
49
|
-
static int dpiGlobalInitialized = 0;
|
|
50
|
-
|
|
51
|
-
// a global mutex is used to ensure that only one thread is used to perform
|
|
52
|
-
// initialization of ODPI-C
|
|
53
|
-
static dpiMutexType dpiGlobalMutex;
|
|
54
|
-
|
|
55
|
-
//-----------------------------------------------------------------------------
|
|
56
|
-
// dpiGlobal__extendedInitialize() [INTERNAL]
|
|
57
|
-
// Create the global environment used for managing error buffers in a
|
|
58
|
-
// thread-safe manner. This environment is solely used for implementing thread
|
|
59
|
-
// local storage for the error buffers and for looking up encodings given an
|
|
60
|
-
// IANA or Oracle character set name.
|
|
61
|
-
//-----------------------------------------------------------------------------
|
|
62
|
-
static int dpiGlobal__extendedInitialize(dpiError *error)
|
|
63
|
-
{
|
|
64
|
-
int status;
|
|
65
|
-
|
|
66
|
-
// create threaded OCI environment for storing error buffers and for
|
|
67
|
-
// looking up character sets; use character set AL32UTF8 solely to avoid
|
|
68
|
-
// the overhead of processing the environment variables; no error messages
|
|
69
|
-
// from this environment are ever used (ODPI-C specific error messages are
|
|
70
|
-
// used)
|
|
71
|
-
if (dpiOci__envNlsCreate(&dpiGlobalEnvHandle, DPI_OCI_THREADED,
|
|
72
|
-
DPI_CHARSET_ID_UTF8, DPI_CHARSET_ID_UTF8, error) < 0)
|
|
73
|
-
return DPI_FAILURE;
|
|
74
|
-
|
|
75
|
-
// create global error handle
|
|
76
|
-
if (dpiOci__handleAlloc(dpiGlobalEnvHandle, &dpiGlobalErrorHandle,
|
|
77
|
-
DPI_OCI_HTYPE_ERROR, "create global error", error) < 0) {
|
|
78
|
-
dpiOci__handleFree(dpiGlobalEnvHandle, DPI_OCI_HTYPE_ENV);
|
|
79
|
-
return DPI_FAILURE;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// create global thread key
|
|
83
|
-
status = dpiOci__threadKeyInit(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
84
|
-
&dpiGlobalThreadKey, (void*) dpiUtils__freeMemory, error);
|
|
85
|
-
if (status < 0) {
|
|
86
|
-
dpiOci__handleFree(dpiGlobalEnvHandle, DPI_OCI_HTYPE_ENV);
|
|
87
|
-
return DPI_FAILURE;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// mark library as fully initialized
|
|
91
|
-
dpiGlobalInitialized = 1;
|
|
92
|
-
|
|
93
|
-
return DPI_SUCCESS;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
//-----------------------------------------------------------------------------
|
|
98
|
-
// dpiGlobal__finalize() [INTERNAL]
|
|
99
|
-
// Called when the process terminates and ensures that everything is cleaned
|
|
100
|
-
// up.
|
|
101
|
-
//-----------------------------------------------------------------------------
|
|
102
|
-
static void dpiGlobal__finalize(void)
|
|
103
|
-
{
|
|
104
|
-
void *errorBuffer = NULL;
|
|
105
|
-
dpiError error;
|
|
106
|
-
|
|
107
|
-
dpiMutex__acquire(dpiGlobalMutex);
|
|
108
|
-
dpiGlobalInitialized = 0;
|
|
109
|
-
error.buffer = &dpiGlobalErrorBuffer;
|
|
110
|
-
if (dpiGlobalThreadKey) {
|
|
111
|
-
dpiOci__threadKeyGet(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
112
|
-
dpiGlobalThreadKey, &errorBuffer, &error);
|
|
113
|
-
if (errorBuffer) {
|
|
114
|
-
dpiOci__threadKeySet(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
115
|
-
dpiGlobalThreadKey, NULL, &error);
|
|
116
|
-
dpiUtils__freeMemory(errorBuffer);
|
|
117
|
-
}
|
|
118
|
-
dpiOci__threadKeyDestroy(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
119
|
-
&dpiGlobalThreadKey, &error);
|
|
120
|
-
dpiGlobalThreadKey = NULL;
|
|
121
|
-
}
|
|
122
|
-
if (dpiGlobalEnvHandle) {
|
|
123
|
-
dpiOci__handleFree(dpiGlobalEnvHandle, DPI_OCI_HTYPE_ENV);
|
|
124
|
-
dpiGlobalEnvHandle = NULL;
|
|
125
|
-
}
|
|
126
|
-
dpiMutex__release(dpiGlobalMutex);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
//-----------------------------------------------------------------------------
|
|
131
|
-
// dpiGlobal__initError() [INTERNAL]
|
|
132
|
-
// Get the thread local error structure for use in all other functions. If
|
|
133
|
-
// an error structure cannot be determined for some reason, the global error
|
|
134
|
-
// buffer structure is returned instead.
|
|
135
|
-
//-----------------------------------------------------------------------------
|
|
136
|
-
int dpiGlobal__initError(const char *fnName, dpiError *error)
|
|
137
|
-
{
|
|
138
|
-
dpiErrorBuffer *tempErrorBuffer;
|
|
139
|
-
|
|
140
|
-
// initialize error buffer output to global error buffer structure; this is
|
|
141
|
-
// the value that is used if an error takes place before the thread local
|
|
142
|
-
// error structure can be returned
|
|
143
|
-
error->handle = NULL;
|
|
144
|
-
error->buffer = &dpiGlobalErrorBuffer;
|
|
145
|
-
if (fnName)
|
|
146
|
-
error->buffer->fnName = fnName;
|
|
147
|
-
|
|
148
|
-
// initialize global environment, if necessary
|
|
149
|
-
// this should only ever be done once by the first thread to execute this
|
|
150
|
-
if (!dpiGlobalInitialized) {
|
|
151
|
-
dpiMutex__acquire(dpiGlobalMutex);
|
|
152
|
-
if (!dpiGlobalInitialized)
|
|
153
|
-
dpiGlobal__extendedInitialize(error);
|
|
154
|
-
dpiMutex__release(dpiGlobalMutex);
|
|
155
|
-
if (!dpiGlobalInitialized)
|
|
156
|
-
return DPI_FAILURE;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// look up the error buffer specific to this thread
|
|
160
|
-
if (dpiOci__threadKeyGet(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
161
|
-
dpiGlobalThreadKey, (void**) &tempErrorBuffer, error) < 0)
|
|
162
|
-
return DPI_FAILURE;
|
|
163
|
-
|
|
164
|
-
// if NULL, key has never been set for this thread, allocate new error
|
|
165
|
-
// and set it
|
|
166
|
-
if (!tempErrorBuffer) {
|
|
167
|
-
if (dpiUtils__allocateMemory(1, sizeof(dpiErrorBuffer), 1,
|
|
168
|
-
"allocate error buffer", (void**) &tempErrorBuffer, error) < 0)
|
|
169
|
-
return DPI_FAILURE;
|
|
170
|
-
if (dpiOci__threadKeySet(dpiGlobalEnvHandle, dpiGlobalErrorHandle,
|
|
171
|
-
dpiGlobalThreadKey, tempErrorBuffer, error) < 0) {
|
|
172
|
-
dpiUtils__freeMemory(tempErrorBuffer);
|
|
173
|
-
return DPI_FAILURE;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// if a function name has been specified, clear error
|
|
178
|
-
// the only time a function name is not specified is for
|
|
179
|
-
// dpiContext_getError() when the error information is being retrieved
|
|
180
|
-
if (fnName) {
|
|
181
|
-
tempErrorBuffer->code = 0;
|
|
182
|
-
tempErrorBuffer->offset = 0;
|
|
183
|
-
tempErrorBuffer->errorNum = (dpiErrorNum) 0;
|
|
184
|
-
tempErrorBuffer->isRecoverable = 0;
|
|
185
|
-
tempErrorBuffer->messageLength = 0;
|
|
186
|
-
tempErrorBuffer->fnName = fnName;
|
|
187
|
-
tempErrorBuffer->action = "start";
|
|
188
|
-
strcpy(tempErrorBuffer->encoding, DPI_CHARSET_NAME_UTF8);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
error->buffer = tempErrorBuffer;
|
|
192
|
-
return DPI_SUCCESS;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
//-----------------------------------------------------------------------------
|
|
197
|
-
// dpiGlobal__initialize() [INTERNAL]
|
|
198
|
-
// Initialization function that runs at process startup or when the library
|
|
199
|
-
// is first loaded. Some operating systems have limits on what can be run in
|
|
200
|
-
// this function, so most work is done in the dpiGlobal__extendedInitialize()
|
|
201
|
-
// function that runs when the first call to dpiContext_create() is made.
|
|
202
|
-
//-----------------------------------------------------------------------------
|
|
203
|
-
DPI_INITIALIZER(dpiGlobal__initialize)
|
|
204
|
-
{
|
|
205
|
-
memset(&dpiGlobalErrorBuffer, 0, sizeof(dpiGlobalErrorBuffer));
|
|
206
|
-
strcpy(dpiGlobalErrorBuffer.encoding, DPI_CHARSET_NAME_UTF8);
|
|
207
|
-
dpiMutex__initialize(dpiGlobalMutex);
|
|
208
|
-
dpiDebug__initialize();
|
|
209
|
-
atexit(dpiGlobal__finalize);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
//-----------------------------------------------------------------------------
|
|
214
|
-
// dpiGlobal__lookupCharSet() [INTERNAL]
|
|
215
|
-
// Lookup the character set id that can be used in the call to
|
|
216
|
-
// OCINlsEnvCreate().
|
|
217
|
-
//-----------------------------------------------------------------------------
|
|
218
|
-
int dpiGlobal__lookupCharSet(const char *name, uint16_t *charsetId,
|
|
219
|
-
dpiError *error)
|
|
220
|
-
{
|
|
221
|
-
char oraCharsetName[DPI_OCI_NLS_MAXBUFSZ];
|
|
222
|
-
|
|
223
|
-
// check for well-known encodings first
|
|
224
|
-
if (strcmp(name, DPI_CHARSET_NAME_UTF8) == 0)
|
|
225
|
-
*charsetId = DPI_CHARSET_ID_UTF8;
|
|
226
|
-
else if (strcmp(name, DPI_CHARSET_NAME_UTF16) == 0)
|
|
227
|
-
*charsetId = DPI_CHARSET_ID_UTF16;
|
|
228
|
-
else if (strcmp(name, DPI_CHARSET_NAME_ASCII) == 0)
|
|
229
|
-
*charsetId = DPI_CHARSET_ID_ASCII;
|
|
230
|
-
else if (strcmp(name, DPI_CHARSET_NAME_UTF16LE) == 0 ||
|
|
231
|
-
strcmp(name, DPI_CHARSET_NAME_UTF16BE) == 0)
|
|
232
|
-
return dpiError__set(error, "check encoding", DPI_ERR_NOT_SUPPORTED);
|
|
233
|
-
|
|
234
|
-
// perform lookup; check for the Oracle character set name first and if
|
|
235
|
-
// that fails, lookup using the IANA character set name
|
|
236
|
-
else {
|
|
237
|
-
if (dpiOci__nlsCharSetNameToId(dpiGlobalEnvHandle, name, charsetId,
|
|
238
|
-
error) < 0)
|
|
239
|
-
return DPI_FAILURE;
|
|
240
|
-
if (!*charsetId) {
|
|
241
|
-
if (dpiOci__nlsNameMap(dpiGlobalEnvHandle, oraCharsetName,
|
|
242
|
-
sizeof(oraCharsetName), name, DPI_OCI_NLS_CS_IANA_TO_ORA,
|
|
243
|
-
error) < 0)
|
|
244
|
-
return dpiError__set(error, "lookup charset",
|
|
245
|
-
DPI_ERR_INVALID_CHARSET, name);
|
|
246
|
-
dpiOci__nlsCharSetNameToId(dpiGlobalEnvHandle, oraCharsetName,
|
|
247
|
-
charsetId, error);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return DPI_SUCCESS;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
//-----------------------------------------------------------------------------
|
|
256
|
-
// dpiGlobal__lookupEncoding() [INTERNAL]
|
|
257
|
-
// Get the IANA character set name (encoding) given the Oracle character set
|
|
258
|
-
// id.
|
|
259
|
-
//-----------------------------------------------------------------------------
|
|
260
|
-
int dpiGlobal__lookupEncoding(uint16_t charsetId, char *encoding,
|
|
261
|
-
dpiError *error)
|
|
262
|
-
{
|
|
263
|
-
char oracleName[DPI_OCI_NLS_MAXBUFSZ];
|
|
264
|
-
|
|
265
|
-
// check for well-known encodings first
|
|
266
|
-
switch (charsetId) {
|
|
267
|
-
case DPI_CHARSET_ID_UTF8:
|
|
268
|
-
strcpy(encoding, DPI_CHARSET_NAME_UTF8);
|
|
269
|
-
return DPI_SUCCESS;
|
|
270
|
-
case DPI_CHARSET_ID_UTF16:
|
|
271
|
-
strcpy(encoding, DPI_CHARSET_NAME_UTF16);
|
|
272
|
-
return DPI_SUCCESS;
|
|
273
|
-
case DPI_CHARSET_ID_ASCII:
|
|
274
|
-
strcpy(encoding, DPI_CHARSET_NAME_ASCII);
|
|
275
|
-
return DPI_SUCCESS;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// get character set name
|
|
279
|
-
if (dpiOci__nlsCharSetIdToName(dpiGlobalEnvHandle, oracleName,
|
|
280
|
-
sizeof(oracleName), charsetId, error) < 0)
|
|
281
|
-
return dpiError__set(error, "lookup Oracle character set name",
|
|
282
|
-
DPI_ERR_INVALID_CHARSET_ID, charsetId);
|
|
283
|
-
|
|
284
|
-
// get IANA character set name
|
|
285
|
-
if (dpiOci__nlsNameMap(dpiGlobalEnvHandle, encoding, DPI_OCI_NLS_MAXBUFSZ,
|
|
286
|
-
oracleName, DPI_OCI_NLS_CS_ORA_TO_IANA, error) < 0)
|
|
287
|
-
return dpiError__set(error, "lookup IANA name",
|
|
288
|
-
DPI_ERR_INVALID_CHARSET_ID, charsetId);
|
|
289
|
-
|
|
290
|
-
return DPI_SUCCESS;
|
|
291
|
-
}
|
|
292
|
-
|