node-firebird-driver 2.4.0 → 3.0.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/dist/lib/impl/attachment.d.ts +3 -3
- package/dist/lib/impl/attachment.js +107 -148
- package/dist/lib/impl/attachment.js.map +1 -1
- package/dist/lib/impl/blob.d.ts +3 -1
- package/dist/lib/impl/blob.js +11 -25
- package/dist/lib/impl/blob.js.map +1 -1
- package/dist/lib/impl/client.js +20 -35
- package/dist/lib/impl/client.js.map +1 -1
- package/dist/lib/impl/events.js +5 -17
- package/dist/lib/impl/events.js.map +1 -1
- package/dist/lib/impl/fb-util.d.ts +21 -5
- package/dist/lib/impl/fb-util.js +49 -24
- package/dist/lib/impl/fb-util.js.map +1 -1
- package/dist/lib/impl/index.js +5 -1
- package/dist/lib/impl/index.js.map +1 -1
- package/dist/lib/impl/resultset.js +29 -45
- package/dist/lib/impl/resultset.js.map +1 -1
- package/dist/lib/impl/statement.js +39 -64
- package/dist/lib/impl/statement.js.map +1 -1
- package/dist/lib/impl/transaction.js +16 -33
- package/dist/lib/impl/transaction.js.map +1 -1
- package/dist/lib/index.d.ts +12 -1
- package/dist/lib/index.js +7 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/test/tests.js +354 -330
- package/dist/test/tests.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/impl/attachment.ts +4 -3
- package/src/lib/impl/blob.ts +6 -1
- package/src/lib/impl/fb-util.ts +40 -0
- package/src/lib/index.ts +15 -1
- package/src/test/tests.ts +40 -0
package/dist/test/tests.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.runCommonTests = void 0;
|
|
13
4
|
const lib_1 = require("../lib");
|
|
@@ -51,9 +42,8 @@ function runCommonTests(client) {
|
|
|
51
42
|
testConfig.host == '127.0.0.1';
|
|
52
43
|
}
|
|
53
44
|
function getTempFile(name) {
|
|
54
|
-
var _a;
|
|
55
45
|
const database = `${testConfig.tmpDir}/${name}`;
|
|
56
|
-
return (
|
|
46
|
+
return (testConfig.host ?? '') +
|
|
57
47
|
(testConfig.host && testConfig.port ? `/${testConfig.port}` : '') +
|
|
58
48
|
(testConfig.host ? ':' : '') +
|
|
59
49
|
database;
|
|
@@ -70,63 +60,68 @@ function runCommonTests(client) {
|
|
|
70
60
|
password: testConfig.password,
|
|
71
61
|
username: testConfig.username
|
|
72
62
|
};
|
|
73
|
-
client.defaultCreateDatabaseOptions =
|
|
74
|
-
|
|
63
|
+
client.defaultCreateDatabaseOptions = {
|
|
64
|
+
forcedWrite: false,
|
|
65
|
+
...defaultOptions
|
|
66
|
+
};
|
|
67
|
+
client.defaultConnectOptions = {
|
|
68
|
+
...defaultOptions
|
|
69
|
+
};
|
|
75
70
|
});
|
|
76
|
-
afterAll(() =>
|
|
77
|
-
|
|
71
|
+
afterAll(async () => {
|
|
72
|
+
await client.dispose();
|
|
78
73
|
expect(client.isValid).toBeFalsy();
|
|
79
74
|
if (isLocal())
|
|
80
75
|
fs.rmdirSync(testConfig.tmpDir);
|
|
81
|
-
})
|
|
76
|
+
});
|
|
82
77
|
describe('Client', () => {
|
|
83
|
-
test('#createDatabase()', () =>
|
|
84
|
-
const attachment =
|
|
85
|
-
|
|
86
|
-
})
|
|
87
|
-
test('#connect()', () =>
|
|
78
|
+
test('#createDatabase()', async () => {
|
|
79
|
+
const attachment = await client.createDatabase(getTempFile('Client-createDatabase.fdb'));
|
|
80
|
+
await attachment.dropDatabase();
|
|
81
|
+
});
|
|
82
|
+
test('#connect()', async () => {
|
|
88
83
|
const filename = getTempFile('Client-connect.fdb');
|
|
89
|
-
const attachment1 =
|
|
90
|
-
const attachment2 =
|
|
84
|
+
const attachment1 = await client.createDatabase(filename);
|
|
85
|
+
const attachment2 = await client.connect(filename);
|
|
91
86
|
expect(attachment1.isValid).toBeTruthy();
|
|
92
87
|
expect(attachment2.isValid).toBeTruthy();
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
await attachment2.disconnect();
|
|
89
|
+
await attachment1.dropDatabase();
|
|
95
90
|
expect(attachment1.isValid).toBeFalsy();
|
|
96
91
|
expect(attachment2.isValid).toBeFalsy();
|
|
97
|
-
})
|
|
92
|
+
});
|
|
98
93
|
});
|
|
99
94
|
describe('Attachment', () => {
|
|
100
|
-
test('#startTransaction()', () =>
|
|
101
|
-
const attachment =
|
|
95
|
+
test('#startTransaction()', async () => {
|
|
96
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-startTransaction.fdb'));
|
|
102
97
|
const isolationQuery = 'select rdb$get_context(\'SYSTEM\', \'ISOLATION_LEVEL\') from rdb$database';
|
|
103
|
-
const transaction1 =
|
|
98
|
+
const transaction1 = await attachment.startTransaction();
|
|
104
99
|
expect(transaction1.isValid).toBeTruthy();
|
|
105
|
-
expect((
|
|
106
|
-
|
|
100
|
+
expect((await attachment.executeSingleton(transaction1, isolationQuery))[0]).toBe('SNAPSHOT');
|
|
101
|
+
await transaction1.commit();
|
|
107
102
|
expect(transaction1.isValid).toBeFalsy();
|
|
108
|
-
const transaction2 =
|
|
103
|
+
const transaction2 = await attachment.startTransaction({ isolation: lib_1.TransactionIsolation.READ_COMMITTED });
|
|
109
104
|
expect(transaction2.isValid).toBeTruthy();
|
|
110
|
-
expect((
|
|
111
|
-
|
|
105
|
+
expect((await attachment.executeSingleton(transaction2, isolationQuery))[0]).toBe('READ COMMITTED');
|
|
106
|
+
await transaction2.commit();
|
|
112
107
|
expect(transaction2.isValid).toBeFalsy();
|
|
113
|
-
const transaction3 =
|
|
108
|
+
const transaction3 = await attachment.startTransaction({ isolation: lib_1.TransactionIsolation.CONSISTENCY });
|
|
114
109
|
expect(transaction3.isValid).toBeTruthy();
|
|
115
|
-
expect((
|
|
116
|
-
|
|
110
|
+
expect((await attachment.executeSingleton(transaction3, isolationQuery))[0]).toBe('CONSISTENCY');
|
|
111
|
+
await transaction3.commit();
|
|
117
112
|
expect(transaction3.isValid).toBeFalsy();
|
|
118
|
-
|
|
119
|
-
})
|
|
120
|
-
test('#prepare()', () =>
|
|
121
|
-
const attachment =
|
|
122
|
-
const transaction =
|
|
123
|
-
const statement =
|
|
113
|
+
await attachment.dropDatabase();
|
|
114
|
+
});
|
|
115
|
+
test('#prepare()', async () => {
|
|
116
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-prepare.fdb'));
|
|
117
|
+
const transaction = await attachment.startTransaction();
|
|
118
|
+
const statement = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
124
119
|
expect(statement.isValid).toBeTruthy();
|
|
125
|
-
|
|
120
|
+
await statement.dispose();
|
|
126
121
|
expect(statement.isValid).toBeFalsy();
|
|
127
122
|
let error;
|
|
128
123
|
try {
|
|
129
|
-
|
|
124
|
+
await attachment.prepare(transaction, 'create select t1 (n1 integer)');
|
|
130
125
|
}
|
|
131
126
|
catch (e) {
|
|
132
127
|
error = e;
|
|
@@ -136,75 +131,75 @@ function runCommonTests(client) {
|
|
|
136
131
|
'-select');
|
|
137
132
|
}
|
|
138
133
|
expect(error).toBeTruthy();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
})
|
|
134
|
+
await transaction.commit();
|
|
135
|
+
await attachment.dropDatabase();
|
|
136
|
+
});
|
|
142
137
|
//// TODO: #executeTransaction
|
|
143
|
-
test('#execute()', () =>
|
|
144
|
-
const attachment =
|
|
145
|
-
const transaction =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
})
|
|
152
|
-
test('#executeQuery()', () =>
|
|
153
|
-
const attachment =
|
|
154
|
-
const transaction =
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const resultSet =
|
|
138
|
+
test('#execute()', async () => {
|
|
139
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-execute.fdb'));
|
|
140
|
+
const transaction = await attachment.startTransaction();
|
|
141
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
142
|
+
await transaction.commitRetaining();
|
|
143
|
+
await attachment.execute(transaction, 'insert into t1 (n1) values (1)');
|
|
144
|
+
await transaction.commit();
|
|
145
|
+
await attachment.dropDatabase();
|
|
146
|
+
});
|
|
147
|
+
test('#executeQuery()', async () => {
|
|
148
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeQuery.fdb'));
|
|
149
|
+
const transaction = await attachment.startTransaction();
|
|
150
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
151
|
+
await transaction.commitRetaining();
|
|
152
|
+
const resultSet = await attachment.executeQuery(transaction, 'select n1 from t1');
|
|
158
153
|
expect(resultSet.isValid).toBeTruthy();
|
|
159
|
-
|
|
154
|
+
await resultSet.close();
|
|
160
155
|
expect(resultSet.isValid).toBeFalsy();
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
})
|
|
164
|
-
test('#executeSingleton()', () =>
|
|
165
|
-
const attachment =
|
|
166
|
-
const transaction =
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const result =
|
|
156
|
+
await transaction.commit();
|
|
157
|
+
await attachment.dropDatabase();
|
|
158
|
+
});
|
|
159
|
+
test('#executeSingleton()', async () => {
|
|
160
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingleton.fdb'));
|
|
161
|
+
const transaction = await attachment.startTransaction();
|
|
162
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
163
|
+
await transaction.commitRetaining();
|
|
164
|
+
const result = await attachment.executeSingleton(transaction, 'insert into t1 values (11) returning n1');
|
|
170
165
|
expect(result.length).toBe(1);
|
|
171
166
|
expect(result[0]).toBe(11);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
})
|
|
175
|
-
test('#executeSingletonAsObject()', () =>
|
|
176
|
-
const attachment =
|
|
177
|
-
const transaction =
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const output =
|
|
167
|
+
await transaction.commit();
|
|
168
|
+
await attachment.dropDatabase();
|
|
169
|
+
});
|
|
170
|
+
test('#executeSingletonAsObject()', async () => {
|
|
171
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingletonAsObject.fdb'));
|
|
172
|
+
const transaction = await attachment.startTransaction();
|
|
173
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
174
|
+
await transaction.commitRetaining();
|
|
175
|
+
const output = await attachment.executeSingletonAsObject(transaction, 'insert into t1 values (11) returning n1');
|
|
181
176
|
expect(output.N1).toBe(11);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
})
|
|
185
|
-
test('#executeReturning()', () =>
|
|
186
|
-
const attachment =
|
|
187
|
-
const transaction =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const result =
|
|
177
|
+
await transaction.commit();
|
|
178
|
+
await attachment.dropDatabase();
|
|
179
|
+
});
|
|
180
|
+
test('#executeReturning()', async () => {
|
|
181
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeReturning.fdb'));
|
|
182
|
+
const transaction = await attachment.startTransaction();
|
|
183
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
184
|
+
await transaction.commitRetaining();
|
|
185
|
+
const result = await attachment.executeReturning(transaction, 'insert into t1 values (11) returning n1');
|
|
191
186
|
expect(result.length).toBe(1);
|
|
192
187
|
expect(result[0]).toBe(11);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
})
|
|
196
|
-
test('#executeReturningAsObject()', () =>
|
|
197
|
-
const attachment =
|
|
198
|
-
const transaction =
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const output =
|
|
188
|
+
await transaction.commit();
|
|
189
|
+
await attachment.dropDatabase();
|
|
190
|
+
});
|
|
191
|
+
test('#executeReturningAsObject()', async () => {
|
|
192
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeReturningAsObject.fdb'));
|
|
193
|
+
const transaction = await attachment.startTransaction();
|
|
194
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
195
|
+
await transaction.commitRetaining();
|
|
196
|
+
const output = await attachment.executeReturningAsObject(transaction, 'insert into t1 values (11) returning n1');
|
|
202
197
|
expect(output.N1).toBe(11);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
})
|
|
206
|
-
test('#queueEvents()', () =>
|
|
207
|
-
const attachment =
|
|
198
|
+
await transaction.commit();
|
|
199
|
+
await attachment.dropDatabase();
|
|
200
|
+
});
|
|
201
|
+
test('#queueEvents()', async () => {
|
|
202
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-queueEvents.fdb'));
|
|
208
203
|
const eventNames = [
|
|
209
204
|
['EVENT1', 16],
|
|
210
205
|
['EVENT2', 8]
|
|
@@ -217,10 +212,10 @@ function runCommonTests(client) {
|
|
|
217
212
|
count: 0,
|
|
218
213
|
promise: new Promise(resolve => resolver = resolve)
|
|
219
214
|
};
|
|
220
|
-
return
|
|
215
|
+
return { ...obj, resolver };
|
|
221
216
|
});
|
|
222
217
|
const eventsMap = new Map(eventsObj.map(ev => [ev.name, ev]));
|
|
223
|
-
const eventHandler = (counters) =>
|
|
218
|
+
const eventHandler = async (counters) => {
|
|
224
219
|
counters.forEach(([name, count]) => {
|
|
225
220
|
const obj = eventsMap.get(name);
|
|
226
221
|
const newCount = obj.count + count;
|
|
@@ -230,19 +225,19 @@ function runCommonTests(client) {
|
|
|
230
225
|
});
|
|
231
226
|
if (Array.from(eventsMap.values()).every(obj => obj.count >= obj.expected)) {
|
|
232
227
|
if (events) {
|
|
233
|
-
|
|
228
|
+
await events.cancel();
|
|
234
229
|
expect(events.isValid).toBeFalsy();
|
|
235
230
|
events = null;
|
|
236
231
|
}
|
|
237
232
|
}
|
|
238
|
-
}
|
|
239
|
-
let events =
|
|
240
|
-
const transaction =
|
|
233
|
+
};
|
|
234
|
+
let events = await attachment.queueEvents(Array.from(eventsMap.keys()), eventHandler);
|
|
235
|
+
const transaction = await attachment.startTransaction();
|
|
241
236
|
try {
|
|
242
237
|
// Iterate more times than the neccessary so that
|
|
243
238
|
// eventHandler may have a chance to cancel the events.
|
|
244
239
|
for (let i = 0; i < 20; ++i) {
|
|
245
|
-
|
|
240
|
+
await attachment.execute(transaction, `
|
|
246
241
|
execute block as
|
|
247
242
|
begin
|
|
248
243
|
post_event 'EVENT1';
|
|
@@ -253,167 +248,167 @@ function runCommonTests(client) {
|
|
|
253
248
|
`);
|
|
254
249
|
// Commit retaining to test internal event rescheduling
|
|
255
250
|
// after each handler dispatch.
|
|
256
|
-
|
|
251
|
+
await transaction.commitRetaining();
|
|
257
252
|
expect(transaction.isValid).toBeTruthy();
|
|
258
253
|
}
|
|
259
254
|
}
|
|
260
255
|
finally {
|
|
261
|
-
|
|
256
|
+
await transaction.commit();
|
|
262
257
|
expect(transaction.isValid).toBeFalsy();
|
|
263
258
|
}
|
|
264
|
-
|
|
259
|
+
await Promise.all(eventsObj.map(ev => ev.promise));
|
|
265
260
|
if (events)
|
|
266
|
-
|
|
261
|
+
await events.cancel();
|
|
267
262
|
eventsObj.forEach(ev => expect(ev.count).toBeGreaterThanOrEqual(ev.expected));
|
|
268
|
-
|
|
269
|
-
})
|
|
263
|
+
await attachment.dropDatabase();
|
|
264
|
+
});
|
|
270
265
|
});
|
|
271
266
|
describe('Transaction', () => {
|
|
272
|
-
test('#commit()', () =>
|
|
273
|
-
const attachment =
|
|
274
|
-
const transaction =
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
})
|
|
278
|
-
test('#commitRetaining()', () =>
|
|
279
|
-
const attachment =
|
|
280
|
-
const transaction =
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
})
|
|
285
|
-
test('#rollback()', () =>
|
|
286
|
-
const attachment =
|
|
287
|
-
const transaction =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
})
|
|
291
|
-
test('#rollbackRetaining()', () =>
|
|
292
|
-
const attachment =
|
|
293
|
-
const transaction =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
})
|
|
298
|
-
test('transaction left opened', () =>
|
|
299
|
-
const attachment =
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
})
|
|
267
|
+
test('#commit()', async () => {
|
|
268
|
+
const attachment = await client.createDatabase(getTempFile('Transaction-commit.fdb'));
|
|
269
|
+
const transaction = await attachment.startTransaction();
|
|
270
|
+
await transaction.commit();
|
|
271
|
+
await attachment.dropDatabase();
|
|
272
|
+
});
|
|
273
|
+
test('#commitRetaining()', async () => {
|
|
274
|
+
const attachment = await client.createDatabase(getTempFile('Transaction-commitRetaining.fdb'));
|
|
275
|
+
const transaction = await attachment.startTransaction();
|
|
276
|
+
await transaction.commitRetaining();
|
|
277
|
+
await transaction.commit();
|
|
278
|
+
await attachment.dropDatabase();
|
|
279
|
+
});
|
|
280
|
+
test('#rollback()', async () => {
|
|
281
|
+
const attachment = await client.createDatabase(getTempFile('Transaction-rollback.fdb'));
|
|
282
|
+
const transaction = await attachment.startTransaction();
|
|
283
|
+
await transaction.rollback();
|
|
284
|
+
await attachment.dropDatabase();
|
|
285
|
+
});
|
|
286
|
+
test('#rollbackRetaining()', async () => {
|
|
287
|
+
const attachment = await client.createDatabase(getTempFile('Transaction-rollbackRetaining.fdb'));
|
|
288
|
+
const transaction = await attachment.startTransaction();
|
|
289
|
+
await transaction.rollbackRetaining();
|
|
290
|
+
await transaction.rollback();
|
|
291
|
+
await attachment.dropDatabase();
|
|
292
|
+
});
|
|
293
|
+
test('transaction left opened', async () => {
|
|
294
|
+
const attachment = await client.createDatabase(getTempFile('Transaction-left-opened.fdb'));
|
|
295
|
+
await attachment.startTransaction();
|
|
296
|
+
await attachment.dropDatabase();
|
|
297
|
+
});
|
|
303
298
|
});
|
|
304
299
|
describe('Statement', () => {
|
|
305
|
-
test('#execute()', () =>
|
|
306
|
-
const attachment =
|
|
307
|
-
const transaction =
|
|
308
|
-
const statement1 =
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const statement2 =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
300
|
+
test('#execute()', async () => {
|
|
301
|
+
const attachment = await client.createDatabase(getTempFile('Statement-execute.fdb'));
|
|
302
|
+
const transaction = await attachment.startTransaction();
|
|
303
|
+
const statement1 = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
304
|
+
await statement1.execute(transaction);
|
|
305
|
+
await statement1.dispose();
|
|
306
|
+
await transaction.commitRetaining();
|
|
307
|
+
const statement2 = await attachment.prepare(transaction, 'insert into t1 (n1) values (?)');
|
|
308
|
+
await statement2.execute(transaction, [1]);
|
|
309
|
+
await statement2.execute(transaction, [null]);
|
|
310
|
+
await statement2.execute(transaction, [10]);
|
|
311
|
+
await statement2.execute(transaction, [100]);
|
|
317
312
|
expect(statement2.isValid).toBeTruthy();
|
|
318
|
-
|
|
313
|
+
await statement2.dispose();
|
|
319
314
|
expect(statement2.isValid).toBeFalsy();
|
|
320
|
-
const rs =
|
|
321
|
-
const ret =
|
|
322
|
-
|
|
315
|
+
const rs = await attachment.executeQuery(transaction, `select sum(n1) || ', ' || count(n1) || ', ' || count(*) ret from t1`);
|
|
316
|
+
const ret = await rs.fetchAsObject();
|
|
317
|
+
await rs.close();
|
|
323
318
|
expect(ret[0].RET).toStrictEqual('111, 3, 4');
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
})
|
|
327
|
-
test('#executeQuery()', () =>
|
|
328
|
-
const attachment =
|
|
329
|
-
const transaction =
|
|
330
|
-
const statement1 =
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const statement2 =
|
|
335
|
-
const resultSet2 =
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
})
|
|
341
|
-
test('#executeSingleton()', () =>
|
|
342
|
-
const attachment =
|
|
343
|
-
const transaction =
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const statement =
|
|
347
|
-
const result =
|
|
319
|
+
await transaction.commit();
|
|
320
|
+
await attachment.dropDatabase();
|
|
321
|
+
});
|
|
322
|
+
test('#executeQuery()', async () => {
|
|
323
|
+
const attachment = await client.createDatabase(getTempFile('Statement-executeQuery.fdb'));
|
|
324
|
+
const transaction = await attachment.startTransaction();
|
|
325
|
+
const statement1 = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
326
|
+
await statement1.execute(transaction);
|
|
327
|
+
await statement1.dispose();
|
|
328
|
+
await transaction.commitRetaining();
|
|
329
|
+
const statement2 = await attachment.prepare(transaction, 'select n1 from t1');
|
|
330
|
+
const resultSet2 = await statement2.executeQuery(transaction);
|
|
331
|
+
await resultSet2.close();
|
|
332
|
+
await statement2.dispose();
|
|
333
|
+
await transaction.commit();
|
|
334
|
+
await attachment.dropDatabase();
|
|
335
|
+
});
|
|
336
|
+
test('#executeSingleton()', async () => {
|
|
337
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingleton.fdb'));
|
|
338
|
+
const transaction = await attachment.startTransaction();
|
|
339
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
340
|
+
await transaction.commitRetaining();
|
|
341
|
+
const statement = await attachment.prepare(transaction, 'insert into t1 values (11) returning n1, n1 * 2');
|
|
342
|
+
const result = await statement.executeSingleton(transaction);
|
|
348
343
|
expect(result.length).toBe(2);
|
|
349
344
|
expect(result[0]).toBe(11);
|
|
350
345
|
expect(result[1]).toBe(11 * 2);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
})
|
|
355
|
-
test('#executeReturning()', () =>
|
|
356
|
-
const attachment =
|
|
357
|
-
const transaction =
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const statement =
|
|
361
|
-
const result =
|
|
346
|
+
await statement.dispose();
|
|
347
|
+
await transaction.commit();
|
|
348
|
+
await attachment.dropDatabase();
|
|
349
|
+
});
|
|
350
|
+
test('#executeReturning()', async () => {
|
|
351
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeReturning.fdb'));
|
|
352
|
+
const transaction = await attachment.startTransaction();
|
|
353
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
354
|
+
await transaction.commitRetaining();
|
|
355
|
+
const statement = await attachment.prepare(transaction, 'insert into t1 values (11) returning n1, n1 * 2');
|
|
356
|
+
const result = await statement.executeReturning(transaction);
|
|
362
357
|
expect(result.length).toBe(2);
|
|
363
358
|
expect(result[0]).toBe(11);
|
|
364
359
|
expect(result[1]).toBe(11 * 2);
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
})
|
|
369
|
-
test('#columnLabels()', () =>
|
|
370
|
-
const attachment =
|
|
371
|
-
const transaction =
|
|
372
|
-
const statement1 =
|
|
373
|
-
expect(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const statement2 =
|
|
378
|
-
expect(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
})
|
|
383
|
-
test('#hasResultSet()', () =>
|
|
384
|
-
const attachment =
|
|
385
|
-
const transaction =
|
|
386
|
-
const statement1 =
|
|
360
|
+
await statement.dispose();
|
|
361
|
+
await transaction.commit();
|
|
362
|
+
await attachment.dropDatabase();
|
|
363
|
+
});
|
|
364
|
+
test('#columnLabels()', async () => {
|
|
365
|
+
const attachment = await client.createDatabase(getTempFile('Statement-columnLabels.fdb'));
|
|
366
|
+
const transaction = await attachment.startTransaction();
|
|
367
|
+
const statement1 = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
368
|
+
expect(await statement1.columnLabels).toStrictEqual([]);
|
|
369
|
+
await statement1.execute(transaction);
|
|
370
|
+
await statement1.dispose();
|
|
371
|
+
await transaction.commitRetaining();
|
|
372
|
+
const statement2 = await attachment.prepare(transaction, 'select n1, n1 x from t1');
|
|
373
|
+
expect(await statement2.columnLabels).toStrictEqual(['N1', 'X']);
|
|
374
|
+
await statement2.dispose();
|
|
375
|
+
await transaction.commit();
|
|
376
|
+
await attachment.dropDatabase();
|
|
377
|
+
});
|
|
378
|
+
test('#hasResultSet()', async () => {
|
|
379
|
+
const attachment = await client.createDatabase(getTempFile('Statement-hasResultSet.fdb'));
|
|
380
|
+
const transaction = await attachment.startTransaction();
|
|
381
|
+
const statement1 = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
387
382
|
expect(statement1.hasResultSet).toBe(false);
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const statement2 =
|
|
383
|
+
await statement1.execute(transaction);
|
|
384
|
+
await statement1.dispose();
|
|
385
|
+
await transaction.commitRetaining();
|
|
386
|
+
const statement2 = await attachment.prepare(transaction, 'insert into t1 values (1)');
|
|
392
387
|
expect(statement2.hasResultSet).toBe(false);
|
|
393
|
-
|
|
394
|
-
const statement3 =
|
|
388
|
+
await statement2.dispose();
|
|
389
|
+
const statement3 = await attachment.prepare(transaction, 'insert into t1 values (1) returning *');
|
|
395
390
|
expect(statement3.hasResultSet).toBe(false);
|
|
396
|
-
|
|
397
|
-
const statement4 =
|
|
391
|
+
await statement3.dispose();
|
|
392
|
+
const statement4 = await attachment.prepare(transaction, 'execute block as begin end');
|
|
398
393
|
expect(statement4.hasResultSet).toBe(false);
|
|
399
|
-
|
|
400
|
-
const statement5 =
|
|
394
|
+
await statement4.dispose();
|
|
395
|
+
const statement5 = await attachment.prepare(transaction, 'select * from t1');
|
|
401
396
|
expect(statement5.hasResultSet).toBe(true);
|
|
402
|
-
|
|
403
|
-
const statement6 =
|
|
397
|
+
await statement5.dispose();
|
|
398
|
+
const statement6 = await attachment.prepare(transaction, 'execute block returns (n integer) as begin suspend; end');
|
|
404
399
|
expect(statement6.hasResultSet).toBe(true);
|
|
405
|
-
|
|
406
|
-
const statement7 =
|
|
400
|
+
await statement6.dispose();
|
|
401
|
+
const statement7 = await attachment.prepare(transaction, 'execute block returns (n integer) as begin end');
|
|
407
402
|
expect(statement7.hasResultSet).toBe(true);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
})
|
|
403
|
+
await statement7.dispose();
|
|
404
|
+
await transaction.commit();
|
|
405
|
+
await attachment.dropDatabase();
|
|
406
|
+
});
|
|
412
407
|
});
|
|
413
408
|
describe('ResultSet', () => {
|
|
414
|
-
test('#fetch()', () =>
|
|
415
|
-
const attachment =
|
|
416
|
-
let transaction =
|
|
409
|
+
test('#fetch()', async () => {
|
|
410
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch.fdb'));
|
|
411
|
+
let transaction = await attachment.startTransaction();
|
|
417
412
|
const blobBuffer = Buffer.alloc(11, '12345678á9');
|
|
418
413
|
const fields = [
|
|
419
414
|
{ name: 'x_short', type: 'numeric(2)', valToStr: (v) => v },
|
|
@@ -459,22 +454,22 @@ function runCommonTests(client) {
|
|
|
459
454
|
{ name: 'x_blob1', type: 'blob', valToStr: (v) => `'${v.toString()}'` },
|
|
460
455
|
{ name: 'x_blob2', type: 'blob', valToStr: () => `'${blobBuffer.toString()}'` }
|
|
461
456
|
];
|
|
462
|
-
const statement1 =
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
457
|
+
const statement1 = await attachment.prepare(transaction, `create table t1 (${fields.map(f => `${f.name} ${f.type}`).join(', ')})`);
|
|
458
|
+
await statement1.execute(transaction);
|
|
459
|
+
await statement1.dispose();
|
|
460
|
+
await transaction.commitRetaining();
|
|
466
461
|
const recordCount = 5;
|
|
467
462
|
let parameters;
|
|
468
463
|
{ // scope
|
|
469
|
-
const statement2a =
|
|
464
|
+
const statement2a = await attachment.prepare(transaction, `insert into t1 (${fields.map(f => f.name).join(', ')}) values (${fields.map(() => '?').join(', ')})`);
|
|
470
465
|
// Test execution in a new transaction, after the one used in prepare was committed.
|
|
471
|
-
|
|
472
|
-
transaction =
|
|
473
|
-
const blob =
|
|
466
|
+
await transaction.commit();
|
|
467
|
+
transaction = await attachment.startTransaction();
|
|
468
|
+
const blob = await attachment.createBlob(transaction);
|
|
474
469
|
expect(blob.isValid).toBeTruthy();
|
|
475
|
-
|
|
470
|
+
await blob.write(blobBuffer);
|
|
476
471
|
expect(blob.isValid).toBeTruthy();
|
|
477
|
-
|
|
472
|
+
await blob.close();
|
|
478
473
|
expect(blob.isValid).toBeFalsy();
|
|
479
474
|
parameters = [
|
|
480
475
|
-1,
|
|
@@ -511,18 +506,18 @@ function runCommonTests(client) {
|
|
|
511
506
|
blob
|
|
512
507
|
];
|
|
513
508
|
for (let i = 0; i < recordCount; ++i)
|
|
514
|
-
|
|
515
|
-
|
|
509
|
+
await statement2a.execute(transaction, parameters);
|
|
510
|
+
await statement2a.dispose();
|
|
516
511
|
}
|
|
517
512
|
{ // scope
|
|
518
|
-
const statement2b =
|
|
513
|
+
const statement2b = await attachment.prepare(transaction, `insert into t1 (${fields.map(f => f.name).join(', ')}) ` +
|
|
519
514
|
`values (${parameters.map((val, index) => fields[index].valToStr(val)).join(', ')})`);
|
|
520
515
|
for (let i = 0; i < recordCount; ++i)
|
|
521
|
-
|
|
522
|
-
|
|
516
|
+
await statement2b.execute(transaction);
|
|
517
|
+
await statement2b.dispose();
|
|
523
518
|
}
|
|
524
|
-
|
|
525
|
-
const statement3 =
|
|
519
|
+
await transaction.commitRetaining();
|
|
520
|
+
const statement3 = await attachment.prepare(transaction, `select x_short,
|
|
526
521
|
x_int,
|
|
527
522
|
x_int_scale,
|
|
528
523
|
x_bigint,
|
|
@@ -555,8 +550,8 @@ function runCommonTests(client) {
|
|
|
555
550
|
x_blob1,
|
|
556
551
|
x_blob2
|
|
557
552
|
from t1`);
|
|
558
|
-
const resultSet3 =
|
|
559
|
-
const data =
|
|
553
|
+
const resultSet3 = await statement3.executeQuery(transaction);
|
|
554
|
+
const data = await resultSet3.fetch();
|
|
560
555
|
expect(data.length).toBe(recordCount * 2);
|
|
561
556
|
for (const columns of data) {
|
|
562
557
|
let n = 0;
|
|
@@ -593,39 +588,39 @@ function runCommonTests(client) {
|
|
|
593
588
|
for (const i = n + 2; n < i; ++n) {
|
|
594
589
|
const blob = columns[n];
|
|
595
590
|
expect(blob.isValid).toBeTruthy();
|
|
596
|
-
const blobStream =
|
|
597
|
-
const buffer = Buffer.alloc(
|
|
598
|
-
expect(
|
|
599
|
-
expect(
|
|
600
|
-
|
|
591
|
+
const blobStream = await attachment.openBlob(transaction, blob);
|
|
592
|
+
const buffer = Buffer.alloc(await blobStream.length);
|
|
593
|
+
expect(await blobStream.read(buffer)).toBe(buffer.length);
|
|
594
|
+
expect(await blobStream.read(buffer)).toBe(-1);
|
|
595
|
+
await blobStream.close();
|
|
601
596
|
expect(buffer.toString()).toBe('12345678á9');
|
|
602
597
|
}
|
|
603
598
|
expect(columns.length).toBe(n);
|
|
604
599
|
}
|
|
605
|
-
expect((
|
|
606
|
-
expect((
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
})
|
|
612
|
-
test('#fetchAsObject()', () =>
|
|
613
|
-
const attachment =
|
|
614
|
-
const transaction =
|
|
615
|
-
const resultSet =
|
|
616
|
-
const output =
|
|
600
|
+
expect((await resultSet3.fetch()).length).toBe(0);
|
|
601
|
+
expect((await resultSet3.fetch()).length).toBe(0);
|
|
602
|
+
await resultSet3.close();
|
|
603
|
+
await statement3.dispose();
|
|
604
|
+
await transaction.commit();
|
|
605
|
+
await attachment.dropDatabase();
|
|
606
|
+
});
|
|
607
|
+
test('#fetchAsObject()', async () => {
|
|
608
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetchAsObject.fdb'));
|
|
609
|
+
const transaction = await attachment.startTransaction();
|
|
610
|
+
const resultSet = await attachment.executeQuery(transaction, 'select 1 as a, 2 as b from rdb$database');
|
|
611
|
+
const output = await resultSet.fetchAsObject();
|
|
617
612
|
expect(output[0].A).toBe(1);
|
|
618
613
|
expect(output[0].B).toBe(2);
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
})
|
|
623
|
-
test('#fetch() with fetchSize', () =>
|
|
624
|
-
const attachment =
|
|
625
|
-
const transaction =
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
614
|
+
await resultSet.close();
|
|
615
|
+
await transaction.commit();
|
|
616
|
+
await attachment.dropDatabase();
|
|
617
|
+
});
|
|
618
|
+
test('#fetch() with fetchSize', async () => {
|
|
619
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch-with-fetchSize.fdb'));
|
|
620
|
+
const transaction = await attachment.startTransaction();
|
|
621
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
622
|
+
await transaction.commitRetaining();
|
|
623
|
+
await attachment.execute(transaction, `
|
|
629
624
|
execute block
|
|
630
625
|
as
|
|
631
626
|
declare n integer = 0;
|
|
@@ -637,24 +632,24 @@ function runCommonTests(client) {
|
|
|
637
632
|
end
|
|
638
633
|
end
|
|
639
634
|
`);
|
|
640
|
-
const rs =
|
|
635
|
+
const rs = await attachment.executeQuery(transaction, 'select n1 from t1 order by n1');
|
|
641
636
|
rs.defaultFetchOptions = { fetchSize: 5 };
|
|
642
|
-
expect((
|
|
643
|
-
expect((
|
|
644
|
-
expect((
|
|
645
|
-
expect((
|
|
646
|
-
expect((
|
|
647
|
-
expect((
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
})
|
|
652
|
-
test('#fetch() with fetchSize and exception', () =>
|
|
653
|
-
const attachment =
|
|
654
|
-
const transaction =
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
const rs =
|
|
637
|
+
expect((await rs.fetch()).length).toBe(5);
|
|
638
|
+
expect((await rs.fetch({ fetchSize: 2 })).length).toBe(2);
|
|
639
|
+
expect((await rs.fetch()).length).toBe(5);
|
|
640
|
+
expect((await rs.fetch({ fetchSize: 36 })).length).toBe(36);
|
|
641
|
+
expect((await rs.fetch()).length).toBe(2);
|
|
642
|
+
expect((await rs.fetch()).length).toBe(0);
|
|
643
|
+
await rs.close();
|
|
644
|
+
await transaction.commit();
|
|
645
|
+
await attachment.dropDatabase();
|
|
646
|
+
});
|
|
647
|
+
test('#fetch() with fetchSize and exception', async () => {
|
|
648
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch-with-fetchSize.fdb'));
|
|
649
|
+
const transaction = await attachment.startTransaction();
|
|
650
|
+
await attachment.execute(transaction, 'create exception e1 \'e1\'');
|
|
651
|
+
await transaction.commitRetaining();
|
|
652
|
+
const rs = await attachment.executeQuery(transaction, `
|
|
658
653
|
execute block returns (n integer)
|
|
659
654
|
as
|
|
660
655
|
begin
|
|
@@ -668,38 +663,67 @@ function runCommonTests(client) {
|
|
|
668
663
|
end
|
|
669
664
|
`);
|
|
670
665
|
rs.defaultFetchOptions = { fetchSize: 5 };
|
|
671
|
-
expect((
|
|
666
|
+
expect((await rs.fetch()).length).toBe(2);
|
|
672
667
|
expect(rs.fetch()).rejects.toBeTruthy();
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
})
|
|
677
|
-
test('#fetch() with large blob', () =>
|
|
678
|
-
const attachment =
|
|
679
|
-
let transaction =
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
transaction =
|
|
668
|
+
await rs.close();
|
|
669
|
+
await transaction.commit();
|
|
670
|
+
await attachment.dropDatabase();
|
|
671
|
+
});
|
|
672
|
+
test('#fetch() with large blob', async () => {
|
|
673
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch-with-large-blob.fdb'));
|
|
674
|
+
let transaction = await attachment.startTransaction();
|
|
675
|
+
await attachment.execute(transaction, `create table t1 (x_blob blob)`);
|
|
676
|
+
await transaction.commit();
|
|
677
|
+
transaction = await attachment.startTransaction();
|
|
683
678
|
const buffer = Buffer.from('123'.repeat(60000));
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
transaction =
|
|
687
|
-
const resultSet =
|
|
688
|
-
const result =
|
|
689
|
-
const readStream =
|
|
690
|
-
const blobLength =
|
|
679
|
+
await attachment.execute(transaction, `insert into t1 (x_blob) values (?)`, [buffer]);
|
|
680
|
+
await transaction.commit();
|
|
681
|
+
transaction = await attachment.startTransaction();
|
|
682
|
+
const resultSet = await attachment.executeQuery(transaction, `select x_blob from t1`);
|
|
683
|
+
const result = await resultSet.fetch();
|
|
684
|
+
const readStream = await attachment.openBlob(transaction, result[0][0]);
|
|
685
|
+
const blobLength = await readStream.length;
|
|
691
686
|
const resultBuffer = Buffer.alloc(blobLength);
|
|
692
687
|
let size = 0;
|
|
693
688
|
let n;
|
|
694
|
-
while (size < blobLength && (n =
|
|
689
|
+
while (size < blobLength && (n = await readStream.read(resultBuffer.slice(size))) > 0)
|
|
695
690
|
size += n;
|
|
696
|
-
|
|
691
|
+
await readStream.close();
|
|
697
692
|
expect(resultBuffer.toString().length).toEqual(buffer.toString().length);
|
|
698
693
|
expect(resultBuffer.toString()).toEqual(buffer.toString());
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
})
|
|
694
|
+
await resultSet.close();
|
|
695
|
+
await transaction.commit();
|
|
696
|
+
await attachment.dropDatabase();
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
describe('BlobStream', () => {
|
|
700
|
+
test('#seek()', async () => {
|
|
701
|
+
const attachment = await client.createDatabase(getTempFile('BlobStream-seek.fdb'));
|
|
702
|
+
const transaction = await attachment.startTransaction();
|
|
703
|
+
await attachment.execute(transaction, 'create table t1 (b blob)');
|
|
704
|
+
await transaction.commitRetaining();
|
|
705
|
+
const blobStream = await attachment.createBlob(transaction, { type: 'STREAM' });
|
|
706
|
+
await blobStream.write(Buffer.alloc(10, '1234567890'));
|
|
707
|
+
await blobStream.close();
|
|
708
|
+
await attachment.execute(transaction, 'insert into t1 (b) values (?)', [blobStream.blob]);
|
|
709
|
+
const blob = (await attachment.executeSingleton(transaction, 'select b from t1'))[0];
|
|
710
|
+
const readBlobStream = await attachment.openBlob(transaction, blob);
|
|
711
|
+
const buffer = Buffer.alloc(3);
|
|
712
|
+
expect(await readBlobStream.seek(2)).toBe(2);
|
|
713
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
714
|
+
expect(buffer.toString()).toBe('345');
|
|
715
|
+
expect(await readBlobStream.seek(-1, lib_1.BlobSeekWhence.CURRENT)).toBe(4);
|
|
716
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
717
|
+
expect(buffer.toString()).toBe('567');
|
|
718
|
+
expect(await readBlobStream.seek(1, lib_1.BlobSeekWhence.START)).toBe(1);
|
|
719
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
720
|
+
expect(buffer.toString()).toBe('234');
|
|
721
|
+
expect(await readBlobStream.seek(-2, lib_1.BlobSeekWhence.END)).toBe(8);
|
|
722
|
+
expect(await readBlobStream.read(buffer)).toBe(2);
|
|
723
|
+
expect(buffer.slice(0, 2).toString()).toBe('90');
|
|
724
|
+
await transaction.commit();
|
|
725
|
+
await attachment.dropDatabase();
|
|
726
|
+
});
|
|
703
727
|
});
|
|
704
728
|
});
|
|
705
729
|
}
|