@miatechnet/node-odbc 2.4.10-multiresult.1
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 +179 -0
- package/LICENSE +23 -0
- package/README.md +1314 -0
- package/binding.gyp +100 -0
- package/lib/Connection.js +521 -0
- package/lib/Cursor.js +92 -0
- package/lib/Pool.js +470 -0
- package/lib/Statement.js +207 -0
- package/lib/bindings/napi-v8/odbc.node +0 -0
- package/lib/odbc.d.ts +210 -0
- package/lib/odbc.js +56 -0
- package/package.json +69 -0
- package/src/dynodbc.cpp +189 -0
- package/src/dynodbc.h +383 -0
- package/src/odbc.cpp +850 -0
- package/src/odbc.h +362 -0
- package/src/odbc_connection.cpp +4312 -0
- package/src/odbc_connection.h +114 -0
- package/src/odbc_cursor.cpp +265 -0
- package/src/odbc_cursor.h +52 -0
- package/src/odbc_statement.cpp +610 -0
- package/src/odbc_statement.h +43 -0
package/binding.gyp
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
'targets' : [
|
|
3
|
+
{
|
|
4
|
+
'target_name' : 'odbc',
|
|
5
|
+
'sources' : [
|
|
6
|
+
'src/odbc.cpp',
|
|
7
|
+
'src/odbc_connection.cpp',
|
|
8
|
+
'src/odbc_statement.cpp',
|
|
9
|
+
'src/odbc_cursor.cpp',
|
|
10
|
+
'src/dynodbc.cpp'
|
|
11
|
+
],
|
|
12
|
+
'cflags' : ['-Wall', '-Wextra', '-Wno-unused-parameter', '-DNAPI_DISABLE_CPP_EXCEPTIONS'],
|
|
13
|
+
'include_dirs': [
|
|
14
|
+
'<!@(node -p "require(\'node-addon-api\').include")'
|
|
15
|
+
],
|
|
16
|
+
'defines' : [
|
|
17
|
+
'NAPI_VERSION=<(napi_build_version)'
|
|
18
|
+
],
|
|
19
|
+
'conditions' : [
|
|
20
|
+
[ 'OS == "linux"', {
|
|
21
|
+
'libraries' : [
|
|
22
|
+
'-lodbc'
|
|
23
|
+
],
|
|
24
|
+
'cflags' : [
|
|
25
|
+
'-g'
|
|
26
|
+
]
|
|
27
|
+
}],
|
|
28
|
+
[ 'OS == "mac"', {
|
|
29
|
+
'conditions': [
|
|
30
|
+
[ 'target_arch=="arm64"', {
|
|
31
|
+
'include_dirs': [
|
|
32
|
+
'/opt/homebrew/include'
|
|
33
|
+
],
|
|
34
|
+
'libraries' : [
|
|
35
|
+
'-L/opt/homebrew/lib',
|
|
36
|
+
'-lodbc'
|
|
37
|
+
],
|
|
38
|
+
}], ['target_arch=="x64"', {
|
|
39
|
+
'include_dirs': [
|
|
40
|
+
'/usr/local/include',
|
|
41
|
+
],
|
|
42
|
+
'libraries' : [
|
|
43
|
+
'-L/usr/local/lib',
|
|
44
|
+
'-lodbc'
|
|
45
|
+
],
|
|
46
|
+
}],
|
|
47
|
+
],
|
|
48
|
+
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
|
|
49
|
+
}],
|
|
50
|
+
[ 'OS == "freebsd"', {
|
|
51
|
+
'include_dirs': [
|
|
52
|
+
'/usr/local/include'
|
|
53
|
+
],
|
|
54
|
+
'libraries' : [
|
|
55
|
+
'-L/usr/local/lib',
|
|
56
|
+
'-lodbc'
|
|
57
|
+
],
|
|
58
|
+
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
|
|
59
|
+
}],
|
|
60
|
+
[ 'OS=="win"', {
|
|
61
|
+
'sources' : [
|
|
62
|
+
'src/odbc.cpp'
|
|
63
|
+
],
|
|
64
|
+
'libraries' : [
|
|
65
|
+
'-lodbccp32.lib'
|
|
66
|
+
],
|
|
67
|
+
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS', 'UNICODE' ]
|
|
68
|
+
}],
|
|
69
|
+
[ 'OS=="aix"', {
|
|
70
|
+
'variables': {
|
|
71
|
+
'os_name': '<!(uname -s)',
|
|
72
|
+
},
|
|
73
|
+
'conditions': [
|
|
74
|
+
[ '"<(os_name)"=="OS400"', {
|
|
75
|
+
'ldflags': [
|
|
76
|
+
'-Wl,-brtl,-blibpath:/QOpenSys/pkgs/lib,-lodbc'
|
|
77
|
+
],
|
|
78
|
+
'cflags' : ['-std=c++0x', '-DNAPI_DISABLE_CPP_EXCEPTIONS', '-Wall', '-Wextra', '-Wno-unused-parameter', '-I/QOpenSys/usr/include', '-I/QOpenSys/pkgs/include']
|
|
79
|
+
}]
|
|
80
|
+
]
|
|
81
|
+
}],
|
|
82
|
+
[ 'OS=="os400"', {
|
|
83
|
+
'ldflags': ['-Wl,-blibpath:/QOpenSys/pkgs/lib', '-lodbc'],
|
|
84
|
+
'cflags' : ['-std=c++0x', '-DNAPI_DISABLE_CPP_EXCEPTIONS', '-Wall', '-Wextra', '-Wno-unused-parameter', '-I/QOpenSys/usr/include', '-I/QOpenSys/pkgs/include']
|
|
85
|
+
}]
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"target_name": "action_after_build",
|
|
90
|
+
"type": "none",
|
|
91
|
+
"dependencies": [ "<(module_name)" ],
|
|
92
|
+
"copies": [
|
|
93
|
+
{
|
|
94
|
+
"files": [ "<(PRODUCT_DIR)/<(module_name).node" ],
|
|
95
|
+
"destination": "<(module_path)"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
const { Statement } = require('./Statement');
|
|
2
|
+
const { Cursor } = require('./Cursor');
|
|
3
|
+
|
|
4
|
+
class Connection {
|
|
5
|
+
|
|
6
|
+
CONNECTION_CLOSED_ERROR = 'Connection has already been closed!';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An open connection to the database made through an ODBC driver
|
|
10
|
+
* @constructor
|
|
11
|
+
* @param {string|object} connectionString - The connection string to connect using the DSN
|
|
12
|
+
* defined in odbc.ini, or an odbcConnection object
|
|
13
|
+
*/
|
|
14
|
+
constructor(odbcConnection) {
|
|
15
|
+
this.odbcConnection = odbcConnection;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get connected() {
|
|
19
|
+
if (!this.odbcConnection)
|
|
20
|
+
{
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return this.odbcConnection.connected;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get autocommit() {
|
|
27
|
+
if (!this.odbcConnection)
|
|
28
|
+
{
|
|
29
|
+
throw new Error(CONNECTION_CLOSED_ERROR);
|
|
30
|
+
}
|
|
31
|
+
return this.odbcConnection.autocommit;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// TODO: Write the documentation
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param {*} sql
|
|
38
|
+
* @param {*} params
|
|
39
|
+
* @param {*} cb
|
|
40
|
+
*/
|
|
41
|
+
query(sql, params, opts, cb) {
|
|
42
|
+
// accepted parameter signatures:
|
|
43
|
+
// sql
|
|
44
|
+
// sql, params
|
|
45
|
+
// sql, opts
|
|
46
|
+
// sql, params, opts
|
|
47
|
+
// sql, cb
|
|
48
|
+
// sql, params, cb
|
|
49
|
+
// sql, opts, cb
|
|
50
|
+
// sql, params, opts, cb
|
|
51
|
+
|
|
52
|
+
let callback = cb;
|
|
53
|
+
let parameters = params;
|
|
54
|
+
let options = opts;
|
|
55
|
+
|
|
56
|
+
// If callback is undefined, search for a function in another position
|
|
57
|
+
if (typeof callback === 'undefined')
|
|
58
|
+
{
|
|
59
|
+
if (typeof options === 'function')
|
|
60
|
+
{
|
|
61
|
+
callback = options;
|
|
62
|
+
options = undefined;
|
|
63
|
+
}
|
|
64
|
+
else if(typeof parameters === 'function')
|
|
65
|
+
{
|
|
66
|
+
callback = parameters;
|
|
67
|
+
options = undefined;
|
|
68
|
+
parameters = undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (typeof options === 'undefined')
|
|
73
|
+
{
|
|
74
|
+
if (typeof parameters === 'object' && parameters !== null && !Array.isArray(parameters))
|
|
75
|
+
{
|
|
76
|
+
options = parameters;
|
|
77
|
+
parameters = null;
|
|
78
|
+
} else {
|
|
79
|
+
options = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// if explicitly passing undefined into parameters, need to change to null
|
|
84
|
+
if (typeof parameters === 'undefined') {
|
|
85
|
+
parameters = null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (
|
|
89
|
+
typeof sql !== 'string' ||
|
|
90
|
+
(parameters !== null && !Array.isArray(parameters)) ||
|
|
91
|
+
(options !== null && typeof options !== 'object') ||
|
|
92
|
+
(typeof callback !== 'function' && typeof callback !== 'undefined')
|
|
93
|
+
)
|
|
94
|
+
{
|
|
95
|
+
throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.query({string}, {array}[optional], {object}[optional], {function}[optional]).');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof callback !== 'function') {
|
|
99
|
+
if (!this.odbcConnection)
|
|
100
|
+
{
|
|
101
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
102
|
+
}
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
this.odbcConnection.query(sql, parameters, options, (error, result) => {
|
|
105
|
+
if (error) {
|
|
106
|
+
reject(error);
|
|
107
|
+
} else {
|
|
108
|
+
if (options &&
|
|
109
|
+
(
|
|
110
|
+
options.hasOwnProperty('fetchSize') ||
|
|
111
|
+
options.hasOwnProperty('cursor')
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
{
|
|
115
|
+
const cursor = new Cursor(result);
|
|
116
|
+
resolve(cursor);
|
|
117
|
+
}
|
|
118
|
+
else
|
|
119
|
+
{
|
|
120
|
+
resolve(result);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!this.odbcConnection) {
|
|
128
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
129
|
+
} else {
|
|
130
|
+
process.nextTick(() => {
|
|
131
|
+
if (options &&
|
|
132
|
+
(
|
|
133
|
+
options.hasOwnProperty('fetchSize') ||
|
|
134
|
+
options.hasOwnProperty('cursor')
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
{
|
|
138
|
+
this.odbcConnection.query(sql, parameters, options, (error, result) => {
|
|
139
|
+
if (error) {
|
|
140
|
+
return callback(error);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const cursor = new Cursor(result);
|
|
144
|
+
return callback(error, cursor);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else
|
|
148
|
+
{
|
|
149
|
+
this.odbcConnection.query(sql, parameters, options, callback);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
*
|
|
157
|
+
* @param {string} name
|
|
158
|
+
* @param {Array} parameters
|
|
159
|
+
* @param {function} [cb]
|
|
160
|
+
*/
|
|
161
|
+
callProcedure(catalog, schema, name, params = undefined, cb = undefined) {
|
|
162
|
+
// name
|
|
163
|
+
// name, params
|
|
164
|
+
// name, cb
|
|
165
|
+
// name, params, cb
|
|
166
|
+
|
|
167
|
+
let callback = cb;
|
|
168
|
+
let parameters = params;
|
|
169
|
+
|
|
170
|
+
if (typeof callback === 'undefined') {
|
|
171
|
+
if (typeof parameters === 'function') {
|
|
172
|
+
callback = parameters;
|
|
173
|
+
parameters = null;
|
|
174
|
+
} else if (typeof parameters === 'undefined') {
|
|
175
|
+
parameters = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// if explicitly passing undefined into parameters, need to change to null
|
|
180
|
+
if (typeof parameters === 'undefined') {
|
|
181
|
+
parameters = null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (typeof name !== 'string'
|
|
185
|
+
|| (parameters !== null && !Array.isArray(parameters))
|
|
186
|
+
|| (typeof callback !== 'function' && typeof callback !== 'undefined')) {
|
|
187
|
+
throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.query({string}, {array}[optional], {function}[optional]).');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// promise...
|
|
191
|
+
if (callback === undefined) {
|
|
192
|
+
if (!this.odbcConnection)
|
|
193
|
+
{
|
|
194
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
195
|
+
}
|
|
196
|
+
return new Promise((resolve, reject) => {
|
|
197
|
+
this.odbcConnection.callProcedure(catalog, schema, name, parameters, (error, result) => {
|
|
198
|
+
if (error) {
|
|
199
|
+
reject(error);
|
|
200
|
+
} else {
|
|
201
|
+
resolve(result);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ...or callback
|
|
208
|
+
if (!this.odbcConnection) {
|
|
209
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
210
|
+
} else {
|
|
211
|
+
this.odbcConnection.callProcedure(catalog, schema, name, parameters, callback);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// TODO: Write the documentation
|
|
216
|
+
/**
|
|
217
|
+
*
|
|
218
|
+
* @param {*} callback
|
|
219
|
+
*/
|
|
220
|
+
createStatement(callback = undefined) {
|
|
221
|
+
// type-checking
|
|
222
|
+
if (typeof callback !== 'function' && typeof callback !== 'undefined') {
|
|
223
|
+
throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.createStatement({function}[optional]).');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// promise...
|
|
227
|
+
if (callback === undefined) {
|
|
228
|
+
if (!this.odbcConnection)
|
|
229
|
+
{
|
|
230
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
231
|
+
}
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
this.odbcConnection.createStatement((error, odbcStatement) => {
|
|
234
|
+
if (error) {
|
|
235
|
+
reject(error);
|
|
236
|
+
} else {
|
|
237
|
+
const statement = new Statement(odbcStatement);
|
|
238
|
+
resolve(statement);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
// ...or callback
|
|
246
|
+
if (!this.odbcConnection) {
|
|
247
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
248
|
+
} else {
|
|
249
|
+
this.odbcConnection.createStatement((error, odbcStatement) => {
|
|
250
|
+
if (error) { return callback(error, null); }
|
|
251
|
+
|
|
252
|
+
const statement = new Statement(odbcStatement);
|
|
253
|
+
callback(null, statement);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** TODO:
|
|
259
|
+
* Get the value of the passed attribute from the connection. Asynchronous, can be used either
|
|
260
|
+
* with a callback function or a Promise.
|
|
261
|
+
* @param {string} attribute - The title of the book.
|
|
262
|
+
* @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
|
|
263
|
+
*/
|
|
264
|
+
close(callback = undefined) {
|
|
265
|
+
// type-checking
|
|
266
|
+
if (typeof callback !== 'function' && typeof callback !== 'undefined') {
|
|
267
|
+
throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.close({function}[optional]).');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// promise...
|
|
271
|
+
if (callback === undefined) {
|
|
272
|
+
if (!this.odbcConnection)
|
|
273
|
+
{
|
|
274
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
275
|
+
}
|
|
276
|
+
return new Promise((resolve, reject) => {
|
|
277
|
+
this.odbcConnection.close((error) => {
|
|
278
|
+
if (error) {
|
|
279
|
+
reject(error);
|
|
280
|
+
} else {
|
|
281
|
+
this.odbcConnection = null;
|
|
282
|
+
resolve();
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ...or callback
|
|
289
|
+
return this.odbcConnection.close((error) => {
|
|
290
|
+
if (!error)
|
|
291
|
+
{
|
|
292
|
+
this.odbcConnection = null;
|
|
293
|
+
}
|
|
294
|
+
return callback(error);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// TODO: Documentation
|
|
299
|
+
primaryKeys(catalog, schema, table, callback = undefined) {
|
|
300
|
+
// promise...
|
|
301
|
+
if (callback === undefined) {
|
|
302
|
+
if (!this.odbcConnection)
|
|
303
|
+
{
|
|
304
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
305
|
+
}
|
|
306
|
+
return new Promise((resolve, reject) => {
|
|
307
|
+
this.odbcConnection.primaryKeys(catalog, schema, table, (error, result) => {
|
|
308
|
+
if (error) {
|
|
309
|
+
reject(error);
|
|
310
|
+
} else {
|
|
311
|
+
resolve(result);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ...or callback
|
|
318
|
+
if (!this.odbcConnection) {
|
|
319
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
320
|
+
} else {
|
|
321
|
+
this.odbcConnection.primaryKeys(catalog, schema, table, callback);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// TODO: Documentation
|
|
326
|
+
foreignKeys(catalog, schema, table, fkCatalog, fkSchema, fkTable, callback = undefined) {
|
|
327
|
+
// promise...
|
|
328
|
+
if (callback === undefined) {
|
|
329
|
+
if (!this.odbcConnection)
|
|
330
|
+
{
|
|
331
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
332
|
+
}
|
|
333
|
+
return new Promise((resolve, reject) => {
|
|
334
|
+
this.odbcConnection.foreignKeys(catalog, schema, table, fkCatalog, fkSchema, fkTable, (error, result) => {
|
|
335
|
+
if (error) {
|
|
336
|
+
reject(error);
|
|
337
|
+
} else {
|
|
338
|
+
resolve(result);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ...or callback
|
|
345
|
+
if (!this.odbcConnection) {
|
|
346
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
347
|
+
} else {
|
|
348
|
+
this.odbcConnection.foreignKeys(catalog, schema, table, fkCatalog, fkSchema, fkTable, callback);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// TODO: Documentation
|
|
353
|
+
columns(catalog, schema, table, type, callback = undefined) {
|
|
354
|
+
// promise...
|
|
355
|
+
if (callback === undefined) {
|
|
356
|
+
if (!this.odbcConnection)
|
|
357
|
+
{
|
|
358
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
359
|
+
}
|
|
360
|
+
return new Promise((resolve, reject) => {
|
|
361
|
+
this.odbcConnection.columns(catalog, schema, table, type, (error, result) => {
|
|
362
|
+
if (error) {
|
|
363
|
+
reject(error);
|
|
364
|
+
} else {
|
|
365
|
+
resolve(result);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ...or callback
|
|
372
|
+
if (!this.odbcConnection) {
|
|
373
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
374
|
+
} else {
|
|
375
|
+
this.odbcConnection.columns(catalog, schema, table, type, callback);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// TODO: Documentation
|
|
380
|
+
tables(catalog, schema, table, type, callback = undefined) {
|
|
381
|
+
// promise...
|
|
382
|
+
if (callback === undefined) {
|
|
383
|
+
if (!this.odbcConnection)
|
|
384
|
+
{
|
|
385
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
386
|
+
}
|
|
387
|
+
return new Promise((resolve, reject) => {
|
|
388
|
+
this.odbcConnection.tables(catalog, schema, table, type, (error, result) => {
|
|
389
|
+
if (error) {
|
|
390
|
+
reject(error);
|
|
391
|
+
} else {
|
|
392
|
+
resolve(result);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ...or callback
|
|
399
|
+
if (!this.odbcConnection) {
|
|
400
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
401
|
+
} else {
|
|
402
|
+
this.odbcConnection.tables(catalog, schema, table, type, callback);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// TODO: Documentation
|
|
407
|
+
setIsolationLevel(isolationLevel, callback = undefined) {
|
|
408
|
+
// promise...
|
|
409
|
+
if (callback === undefined) {
|
|
410
|
+
if (!this.odbcConnection)
|
|
411
|
+
{
|
|
412
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
413
|
+
}
|
|
414
|
+
return new Promise((resolve, reject) => {
|
|
415
|
+
this.odbcConnection.setIsolationLevel(isolationLevel, (error) => {
|
|
416
|
+
if (error) {
|
|
417
|
+
reject(error);
|
|
418
|
+
} else {
|
|
419
|
+
resolve();
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// ...or callback
|
|
426
|
+
if (!this.odbcConnection) {
|
|
427
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
428
|
+
} else {
|
|
429
|
+
this.odbcConnection.setIsolationLevel(isolationLevel, callback);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Begins a transaction, turning off auto-commit. Transaction is ended with commit() or
|
|
435
|
+
* rollback().
|
|
436
|
+
* @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
|
|
437
|
+
*/
|
|
438
|
+
beginTransaction(callback = undefined) {
|
|
439
|
+
// promise...
|
|
440
|
+
if (callback === undefined) {
|
|
441
|
+
if (!this.odbcConnection)
|
|
442
|
+
{
|
|
443
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
444
|
+
}
|
|
445
|
+
return new Promise((resolve, reject) => {
|
|
446
|
+
this.odbcConnection.beginTransaction((error, result) => {
|
|
447
|
+
if (error) {
|
|
448
|
+
reject(error);
|
|
449
|
+
} else {
|
|
450
|
+
resolve(result);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ...or callback
|
|
457
|
+
if (!this.odbcConnection) {
|
|
458
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
459
|
+
} else {
|
|
460
|
+
this.odbcConnection.beginTransaction(callback);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Asynchronously ends the transaction with a commit.
|
|
466
|
+
* @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
|
|
467
|
+
*/
|
|
468
|
+
commit(callback = undefined) {
|
|
469
|
+
if (callback === undefined) {
|
|
470
|
+
if (!this.odbcConnection)
|
|
471
|
+
{
|
|
472
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
473
|
+
}
|
|
474
|
+
return new Promise((resolve, reject) => {
|
|
475
|
+
this.odbcConnection.commit((error) => {
|
|
476
|
+
if (error) {
|
|
477
|
+
reject(error);
|
|
478
|
+
} else {
|
|
479
|
+
resolve();
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (!this.odbcConnection) {
|
|
486
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
487
|
+
} else {
|
|
488
|
+
this.odbcConnection.commit(callback);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Asynchronously ends the transaction with a rollback.
|
|
494
|
+
* @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
|
|
495
|
+
*/
|
|
496
|
+
rollback(callback = undefined) {
|
|
497
|
+
if (callback === undefined) {
|
|
498
|
+
if (!this.odbcConnection)
|
|
499
|
+
{
|
|
500
|
+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
|
|
501
|
+
}
|
|
502
|
+
return new Promise((resolve, reject) => {
|
|
503
|
+
this.odbcConnection.rollback((error) => {
|
|
504
|
+
if (error) {
|
|
505
|
+
reject(error);
|
|
506
|
+
} else {
|
|
507
|
+
resolve();
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (!this.odbcConnection) {
|
|
514
|
+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
|
|
515
|
+
} else {
|
|
516
|
+
this.odbcConnection.rollback(callback);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
module.exports.Connection = Connection;
|
package/lib/Cursor.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
class Cursor {
|
|
2
|
+
|
|
3
|
+
static CURSOR_CLOSED_ERROR = 'Cursor has already been closed!';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An cursor created following the execution of query that is ready to return a result set
|
|
7
|
+
* @constructor
|
|
8
|
+
* @param {object} odbcCursor - an odbcCursor object, defined in src/odbc_cursor.h/.cpp
|
|
9
|
+
*/
|
|
10
|
+
constructor(odbcCursor) {
|
|
11
|
+
this.odbcCursor = odbcCursor;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Return whether or not a call to SQLFetch has returned SQL_NO_DATA
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
get noData() {
|
|
20
|
+
if (!this.odbcCursor)
|
|
21
|
+
{
|
|
22
|
+
throw new Error(Cursor.CURSOR_CLOSED_ERROR);
|
|
23
|
+
}
|
|
24
|
+
return this.odbcCursor.noData;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Calls SQL_FETCH and returns the next result set
|
|
29
|
+
* @param {function} [cb] - The callback function to return an error and a result. If the callback is ommited, a Promise is returned.
|
|
30
|
+
* @returns {undefined|Promise}
|
|
31
|
+
*/
|
|
32
|
+
fetch(cb) {
|
|
33
|
+
|
|
34
|
+
let callback = cb;
|
|
35
|
+
|
|
36
|
+
if (typeof callback !== 'function') {
|
|
37
|
+
if (!this.odbcCursor) {
|
|
38
|
+
throw new Error(Cursor.CURSOR_CLOSED_ERROR);
|
|
39
|
+
}
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
this.odbcCursor.fetch((error, result) => {
|
|
42
|
+
if (error) {
|
|
43
|
+
reject(error);
|
|
44
|
+
} else {
|
|
45
|
+
resolve(result);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!this.odbcCursor) {
|
|
52
|
+
callback(new Error(Cursor.CURSOR_CLOSED_ERROR));
|
|
53
|
+
} else {
|
|
54
|
+
this.odbcCursor.fetch(callback);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Closes the cursor and the underlying SQLHSTMT, freeing all memory
|
|
60
|
+
* @param {function} [callback] - The callback function to return an error. If the callback is ommited, a Promise is returned.
|
|
61
|
+
* @returns {undefined|Promise}
|
|
62
|
+
*/
|
|
63
|
+
close(callback = undefined) {
|
|
64
|
+
|
|
65
|
+
// promise...
|
|
66
|
+
if (typeof callback !== 'function') {
|
|
67
|
+
if (!this.odbcCursor) {
|
|
68
|
+
throw new Error(Cursor.CURSOR_CLOSED_ERROR);
|
|
69
|
+
}
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
this.odbcCursor.close((error) => {
|
|
72
|
+
if (error) {
|
|
73
|
+
reject(error);
|
|
74
|
+
} else {
|
|
75
|
+
this.odbcCursor = null;
|
|
76
|
+
resolve();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ...or callback
|
|
83
|
+
this.odbcCursor.close((error) => {
|
|
84
|
+
if (!error) {
|
|
85
|
+
this.odbcCursor = null;
|
|
86
|
+
}
|
|
87
|
+
callback(error);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports.Cursor = Cursor;
|