@miatechnet/node-odbc 2.4.10-multiresult.1 → 2.4.13
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 +178 -178
- package/LICENSE +23 -23
- package/README.md +1314 -1314
- package/binding.gyp +100 -100
- package/lib/Connection.js +521 -521
- package/lib/Cursor.js +92 -92
- package/lib/Pool.js +470 -470
- package/lib/Statement.js +207 -207
- package/lib/odbc.d.ts +210 -210
- package/lib/odbc.js +56 -56
- package/package.json +69 -69
- package/src/dynodbc.cpp +189 -189
- package/src/dynodbc.h +383 -383
- package/src/odbc.cpp +850 -850
- package/src/odbc.h +362 -362
- package/src/odbc_connection.cpp +4312 -4312
- package/src/odbc_connection.h +114 -114
- package/src/odbc_cursor.cpp +265 -265
- package/src/odbc_cursor.h +52 -52
- package/src/odbc_statement.cpp +610 -610
- package/src/odbc_statement.h +43 -43
- package/lib/bindings/napi-v8/odbc.node +0 -0
package/lib/Connection.js
CHANGED
|
@@ -1,521 +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;
|
|
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;
|