Skip to content

Commit 0280ae3

Browse files
authored
Allow Statements to take advantage of QueryOptions (#236)
* Allow Statements to take advantage of QueryOptions, primarily creating a Cursor on statements * Make sure Cursors and Statements are cleaned up correctly in their destructors * Clean up error handling Signed-off-by: Mark Irish <mirish@ibm.com>
1 parent e6fff38 commit 0280ae3

File tree

15 files changed

+3792
-204
lines changed

15 files changed

+3792
-204
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ a.out
22
node_modules
33
deps
44
.idea
5-
core
5+
core*
66
*.env
77
.vscode
88
build*

lib/Connection.js

Lines changed: 128 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ const { Statement } = require('./Statement');
22
const { Cursor } = require('./Cursor');
33

44
class Connection {
5+
6+
CONNECTION_CLOSED_ERROR = 'Connection has already been closed!';
7+
58
/**
69
* An open connection to the database made through an ODBC driver
710
* @constructor
@@ -13,10 +16,18 @@ class Connection {
1316
}
1417

1518
get connected() {
19+
if (!this.odbcConnection)
20+
{
21+
return false;
22+
}
1623
return this.odbcConnection.connected;
1724
}
1825

1926
get autocommit() {
27+
if (!this.odbcConnection)
28+
{
29+
throw new Error(CONNECTION_CLOSED_ERROR);
30+
}
2031
return this.odbcConnection.autocommit;
2132
}
2233

@@ -85,6 +96,10 @@ class Connection {
8596
}
8697

8798
if (typeof callback !== 'function') {
99+
if (!this.odbcConnection)
100+
{
101+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
102+
}
88103
return new Promise((resolve, reject) => {
89104
this.odbcConnection.query(sql, parameters, options, (error, result) => {
90105
if (error) {
@@ -109,28 +124,32 @@ class Connection {
109124
});
110125
}
111126

112-
process.nextTick(() => {
113-
if (options &&
114-
(
115-
options.hasOwnProperty('fetchSize') ||
116-
options.hasOwnProperty('cursor')
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+
)
117136
)
118-
)
119-
{
120-
this.odbcConnection.query(sql, parameters, options, (error, result) => {
121-
if (error) {
122-
return callback(error);
123-
}
137+
{
138+
this.odbcConnection.query(sql, parameters, options, (error, result) => {
139+
if (error) {
140+
return callback(error);
141+
}
124142

125-
const cursor = new Cursor(result);
126-
return callback(error, cursor);
127-
});
128-
}
129-
else
130-
{
131-
this.odbcConnection.query(sql, parameters, options, callback);
132-
}
133-
})
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+
}
134153
}
135154

136155
/**
@@ -170,6 +189,10 @@ class Connection {
170189

171190
// promise...
172191
if (callback === undefined) {
192+
if (!this.odbcConnection)
193+
{
194+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
195+
}
173196
return new Promise((resolve, reject) => {
174197
this.odbcConnection.callProcedure(catalog, schema, name, parameters, (error, result) => {
175198
if (error) {
@@ -182,7 +205,11 @@ class Connection {
182205
}
183206

184207
// ...or callback
185-
return this.odbcConnection.callProcedure(catalog, schema, name, parameters, 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+
}
186213
}
187214

188215
// TODO: Write the documentation
@@ -198,6 +225,10 @@ class Connection {
198225

199226
// promise...
200227
if (callback === undefined) {
228+
if (!this.odbcConnection)
229+
{
230+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
231+
}
201232
return new Promise((resolve, reject) => {
202233
this.odbcConnection.createStatement((error, odbcStatement) => {
203234
if (error) {
@@ -212,12 +243,16 @@ class Connection {
212243

213244

214245
// ...or callback
215-
return this.odbcConnection.createStatement((error, odbcStatement) => {
216-
if (error) { return callback(error, null); }
217-
218-
const statement = new Statement(odbcStatement);
219-
return callback(null, statement);
220-
});
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+
}
221256
}
222257

223258
/** TODO:
@@ -234,25 +269,40 @@ class Connection {
234269

235270
// promise...
236271
if (callback === undefined) {
272+
if (!this.odbcConnection)
273+
{
274+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
275+
}
237276
return new Promise((resolve, reject) => {
238277
this.odbcConnection.close((error) => {
239278
if (error) {
240279
reject(error);
241280
} else {
281+
this.odbcConnection = null;
242282
resolve();
243283
}
244284
});
245285
});
246286
}
247287

248288
// ...or callback
249-
return this.odbcConnection.close(callback);
289+
return this.odbcConnection.close((error) => {
290+
if (!error)
291+
{
292+
this.odbcConnection = null;
293+
}
294+
return callback(error);
295+
});
250296
}
251297

252298
// TODO: Documentation
253299
columns(catalog, schema, table, type, callback = undefined) {
254300
// promise...
255301
if (callback === undefined) {
302+
if (!this.odbcConnection)
303+
{
304+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
305+
}
256306
return new Promise((resolve, reject) => {
257307
this.odbcConnection.columns(catalog, schema, table, type, (error, result) => {
258308
if (error) {
@@ -265,14 +315,21 @@ class Connection {
265315
}
266316

267317
// ...or callback
268-
this.odbcConnection.columns(catalog, schema, table, type, callback);
269-
return undefined;
318+
if (!this.odbcConnection) {
319+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
320+
} else {
321+
this.odbcConnection.columns(catalog, schema, table, type, callback);
322+
}
270323
}
271324

272325
// TODO: Documentation
273326
tables(catalog, schema, table, type, callback = undefined) {
274327
// promise...
275328
if (callback === undefined) {
329+
if (!this.odbcConnection)
330+
{
331+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
332+
}
276333
return new Promise((resolve, reject) => {
277334
this.odbcConnection.tables(catalog, schema, table, type, (error, result) => {
278335
if (error) {
@@ -285,14 +342,21 @@ class Connection {
285342
}
286343

287344
// ...or callback
288-
this.odbcConnection.tables(catalog, schema, table, type, callback);
289-
return undefined;
345+
if (!this.odbcConnection) {
346+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
347+
} else {
348+
this.odbcConnection.tables(catalog, schema, table, type, callback);
349+
}
290350
}
291351

292352
// TODO: Documentation
293353
setIsolationLevel(isolationLevel, callback = undefined) {
294354
// promise...
295355
if (callback === undefined) {
356+
if (!this.odbcConnection)
357+
{
358+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
359+
}
296360
return new Promise((resolve, reject) => {
297361
this.odbcConnection.setIsolationLevel(isolationLevel, (error) => {
298362
if (error) {
@@ -305,7 +369,11 @@ class Connection {
305369
}
306370

307371
// ...or callback
308-
return this.odbcConnection.setIsolationLevel(isolationLevel, callback);
372+
if (!this.odbcConnection) {
373+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
374+
} else {
375+
this.odbcConnection.setIsolationLevel(isolationLevel, callback);
376+
}
309377
}
310378

311379
/**
@@ -316,6 +384,10 @@ class Connection {
316384
beginTransaction(callback = undefined) {
317385
// promise...
318386
if (callback === undefined) {
387+
if (!this.odbcConnection)
388+
{
389+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
390+
}
319391
return new Promise((resolve, reject) => {
320392
this.odbcConnection.beginTransaction((error, result) => {
321393
if (error) {
@@ -328,7 +400,11 @@ class Connection {
328400
}
329401

330402
// ...or callback
331-
return this.odbcConnection.beginTransaction(callback);
403+
if (!this.odbcConnection) {
404+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
405+
} else {
406+
this.odbcConnection.beginTransaction(callback);
407+
}
332408
}
333409

334410
/**
@@ -337,6 +413,10 @@ class Connection {
337413
*/
338414
commit(callback = undefined) {
339415
if (callback === undefined) {
416+
if (!this.odbcConnection)
417+
{
418+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
419+
}
340420
return new Promise((resolve, reject) => {
341421
this.odbcConnection.commit((error) => {
342422
if (error) {
@@ -348,7 +428,11 @@ class Connection {
348428
});
349429
}
350430

351-
return this.odbcConnection.commit(callback);
431+
if (!this.odbcConnection) {
432+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
433+
} else {
434+
this.odbcConnection.commit(callback);
435+
}
352436
}
353437

354438
/**
@@ -357,6 +441,10 @@ class Connection {
357441
*/
358442
rollback(callback = undefined) {
359443
if (callback === undefined) {
444+
if (!this.odbcConnection)
445+
{
446+
throw new Error(Connection.CONNECTION_CLOSED_ERROR);
447+
}
360448
return new Promise((resolve, reject) => {
361449
this.odbcConnection.rollback((error) => {
362450
if (error) {
@@ -368,7 +456,11 @@ class Connection {
368456
});
369457
}
370458

371-
return this.odbcConnection.rollback(callback);
459+
if (!this.odbcConnection) {
460+
callback(new Error(Connection.CONNECTION_CLOSED_ERROR));
461+
} else {
462+
this.odbcConnection.rollback(callback);
463+
}
372464
}
373465
}
374466

0 commit comments

Comments
 (0)