node-firebird-driver 2.3.0 → 3.0.0
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 +14 -3
- package/dist/lib/impl/attachment.js +112 -138
- 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.d.ts +1 -0
- package/dist/lib/impl/client.js +24 -36
- package/dist/lib/impl/client.js.map +1 -1
- package/dist/lib/impl/events.d.ts +1 -0
- package/dist/lib/impl/events.js +9 -18
- package/dist/lib/impl/events.js.map +1 -1
- package/dist/lib/impl/fb-util.d.ts +34 -5
- package/dist/lib/impl/fb-util.js +82 -42
- 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.d.ts +1 -0
- package/dist/lib/impl/resultset.js +33 -46
- package/dist/lib/impl/resultset.js.map +1 -1
- package/dist/lib/impl/statement.d.ts +6 -0
- package/dist/lib/impl/statement.js +47 -57
- package/dist/lib/impl/statement.js.map +1 -1
- package/dist/lib/impl/transaction.d.ts +1 -0
- package/dist/lib/impl/transaction.js +20 -34
- package/dist/lib/impl/transaction.js.map +1 -1
- package/dist/lib/index.d.ts +57 -3
- package/dist/lib/index.js +4 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/test/tests.js +385 -301
- package/dist/test/tests.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/impl/attachment.ts +32 -9
- package/src/lib/impl/blob.ts +6 -1
- package/src/lib/impl/client.ts +5 -1
- package/src/lib/impl/events.ts +5 -1
- package/src/lib/impl/fb-util.ts +55 -0
- package/src/lib/impl/resultset.ts +5 -1
- package/src/lib/impl/statement.ts +21 -4
- package/src/lib/impl/transaction.ts +5 -1
- package/src/lib/index.ts +77 -3
- package/src/test/tests.ts +123 -3
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,15 +42,15 @@ 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;
|
|
60
50
|
}
|
|
61
51
|
jest.setTimeout(10000);
|
|
62
52
|
beforeAll(() => {
|
|
53
|
+
expect(client.isValid).toBeTruthy();
|
|
63
54
|
if (isLocal() && !testConfig.tmpDir) {
|
|
64
55
|
testConfig.tmpDir = tmp.mkdirSync().path.toString();
|
|
65
56
|
// Important for MacOS tests with non-embedded server.
|
|
@@ -69,50 +60,68 @@ function runCommonTests(client) {
|
|
|
69
60
|
password: testConfig.password,
|
|
70
61
|
username: testConfig.username
|
|
71
62
|
};
|
|
72
|
-
client.defaultCreateDatabaseOptions =
|
|
73
|
-
|
|
63
|
+
client.defaultCreateDatabaseOptions = {
|
|
64
|
+
forcedWrite: false,
|
|
65
|
+
...defaultOptions
|
|
66
|
+
};
|
|
67
|
+
client.defaultConnectOptions = {
|
|
68
|
+
...defaultOptions
|
|
69
|
+
};
|
|
74
70
|
});
|
|
75
|
-
afterAll(() =>
|
|
76
|
-
|
|
71
|
+
afterAll(async () => {
|
|
72
|
+
await client.dispose();
|
|
73
|
+
expect(client.isValid).toBeFalsy();
|
|
77
74
|
if (isLocal())
|
|
78
75
|
fs.rmdirSync(testConfig.tmpDir);
|
|
79
|
-
})
|
|
76
|
+
});
|
|
80
77
|
describe('Client', () => {
|
|
81
|
-
test('#createDatabase()', () =>
|
|
82
|
-
const attachment =
|
|
83
|
-
|
|
84
|
-
})
|
|
85
|
-
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 () => {
|
|
86
83
|
const filename = getTempFile('Client-connect.fdb');
|
|
87
|
-
const attachment1 =
|
|
88
|
-
const attachment2 =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
const attachment1 = await client.createDatabase(filename);
|
|
85
|
+
const attachment2 = await client.connect(filename);
|
|
86
|
+
expect(attachment1.isValid).toBeTruthy();
|
|
87
|
+
expect(attachment2.isValid).toBeTruthy();
|
|
88
|
+
await attachment2.disconnect();
|
|
89
|
+
await attachment1.dropDatabase();
|
|
90
|
+
expect(attachment1.isValid).toBeFalsy();
|
|
91
|
+
expect(attachment2.isValid).toBeFalsy();
|
|
92
|
+
});
|
|
92
93
|
});
|
|
93
94
|
describe('Attachment', () => {
|
|
94
|
-
test('#startTransaction()', () =>
|
|
95
|
-
const attachment =
|
|
95
|
+
test('#startTransaction()', async () => {
|
|
96
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-startTransaction.fdb'));
|
|
96
97
|
const isolationQuery = 'select rdb$get_context(\'SYSTEM\', \'ISOLATION_LEVEL\') from rdb$database';
|
|
97
|
-
const transaction1 =
|
|
98
|
-
expect(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
expect(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
expect((
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
98
|
+
const transaction1 = await attachment.startTransaction();
|
|
99
|
+
expect(transaction1.isValid).toBeTruthy();
|
|
100
|
+
expect((await attachment.executeSingleton(transaction1, isolationQuery))[0]).toBe('SNAPSHOT');
|
|
101
|
+
await transaction1.commit();
|
|
102
|
+
expect(transaction1.isValid).toBeFalsy();
|
|
103
|
+
const transaction2 = await attachment.startTransaction({ isolation: lib_1.TransactionIsolation.READ_COMMITTED });
|
|
104
|
+
expect(transaction2.isValid).toBeTruthy();
|
|
105
|
+
expect((await attachment.executeSingleton(transaction2, isolationQuery))[0]).toBe('READ COMMITTED');
|
|
106
|
+
await transaction2.commit();
|
|
107
|
+
expect(transaction2.isValid).toBeFalsy();
|
|
108
|
+
const transaction3 = await attachment.startTransaction({ isolation: lib_1.TransactionIsolation.CONSISTENCY });
|
|
109
|
+
expect(transaction3.isValid).toBeTruthy();
|
|
110
|
+
expect((await attachment.executeSingleton(transaction3, isolationQuery))[0]).toBe('CONSISTENCY');
|
|
111
|
+
await transaction3.commit();
|
|
112
|
+
expect(transaction3.isValid).toBeFalsy();
|
|
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)');
|
|
119
|
+
expect(statement.isValid).toBeTruthy();
|
|
120
|
+
await statement.dispose();
|
|
121
|
+
expect(statement.isValid).toBeFalsy();
|
|
113
122
|
let error;
|
|
114
123
|
try {
|
|
115
|
-
|
|
124
|
+
await attachment.prepare(transaction, 'create select t1 (n1 integer)');
|
|
116
125
|
}
|
|
117
126
|
catch (e) {
|
|
118
127
|
error = e;
|
|
@@ -122,52 +131,75 @@ function runCommonTests(client) {
|
|
|
122
131
|
'-select');
|
|
123
132
|
}
|
|
124
133
|
expect(error).toBeTruthy();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
134
|
+
await transaction.commit();
|
|
135
|
+
await attachment.dropDatabase();
|
|
136
|
+
});
|
|
128
137
|
//// TODO: #executeTransaction
|
|
129
|
-
test('#execute()', () =>
|
|
130
|
-
const attachment =
|
|
131
|
-
const transaction =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
})
|
|
138
|
-
test('#executeQuery()', () =>
|
|
139
|
-
const attachment =
|
|
140
|
-
const transaction =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const resultSet =
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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');
|
|
153
|
+
expect(resultSet.isValid).toBeTruthy();
|
|
154
|
+
await resultSet.close();
|
|
155
|
+
expect(resultSet.isValid).toBeFalsy();
|
|
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');
|
|
165
|
+
expect(result.length).toBe(1);
|
|
166
|
+
expect(result[0]).toBe(11);
|
|
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');
|
|
176
|
+
expect(output.N1).toBe(11);
|
|
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');
|
|
154
186
|
expect(result.length).toBe(1);
|
|
155
187
|
expect(result[0]).toBe(11);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
})
|
|
159
|
-
test('#executeReturningAsObject()', () =>
|
|
160
|
-
const attachment =
|
|
161
|
-
const transaction =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
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');
|
|
165
197
|
expect(output.N1).toBe(11);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
})
|
|
169
|
-
test('#queueEvents()', () =>
|
|
170
|
-
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'));
|
|
171
203
|
const eventNames = [
|
|
172
204
|
['EVENT1', 16],
|
|
173
205
|
['EVENT2', 8]
|
|
@@ -180,10 +212,10 @@ function runCommonTests(client) {
|
|
|
180
212
|
count: 0,
|
|
181
213
|
promise: new Promise(resolve => resolver = resolve)
|
|
182
214
|
};
|
|
183
|
-
return
|
|
215
|
+
return { ...obj, resolver };
|
|
184
216
|
});
|
|
185
217
|
const eventsMap = new Map(eventsObj.map(ev => [ev.name, ev]));
|
|
186
|
-
const eventHandler = (counters) =>
|
|
218
|
+
const eventHandler = async (counters) => {
|
|
187
219
|
counters.forEach(([name, count]) => {
|
|
188
220
|
const obj = eventsMap.get(name);
|
|
189
221
|
const newCount = obj.count + count;
|
|
@@ -193,18 +225,19 @@ function runCommonTests(client) {
|
|
|
193
225
|
});
|
|
194
226
|
if (Array.from(eventsMap.values()).every(obj => obj.count >= obj.expected)) {
|
|
195
227
|
if (events) {
|
|
196
|
-
|
|
228
|
+
await events.cancel();
|
|
229
|
+
expect(events.isValid).toBeFalsy();
|
|
197
230
|
events = null;
|
|
198
231
|
}
|
|
199
232
|
}
|
|
200
|
-
}
|
|
201
|
-
let events =
|
|
202
|
-
const transaction =
|
|
233
|
+
};
|
|
234
|
+
let events = await attachment.queueEvents(Array.from(eventsMap.keys()), eventHandler);
|
|
235
|
+
const transaction = await attachment.startTransaction();
|
|
203
236
|
try {
|
|
204
237
|
// Iterate more times than the neccessary so that
|
|
205
238
|
// eventHandler may have a chance to cancel the events.
|
|
206
239
|
for (let i = 0; i < 20; ++i) {
|
|
207
|
-
|
|
240
|
+
await attachment.execute(transaction, `
|
|
208
241
|
execute block as
|
|
209
242
|
begin
|
|
210
243
|
post_event 'EVENT1';
|
|
@@ -215,149 +248,167 @@ function runCommonTests(client) {
|
|
|
215
248
|
`);
|
|
216
249
|
// Commit retaining to test internal event rescheduling
|
|
217
250
|
// after each handler dispatch.
|
|
218
|
-
|
|
251
|
+
await transaction.commitRetaining();
|
|
252
|
+
expect(transaction.isValid).toBeTruthy();
|
|
219
253
|
}
|
|
220
254
|
}
|
|
221
255
|
finally {
|
|
222
|
-
|
|
256
|
+
await transaction.commit();
|
|
257
|
+
expect(transaction.isValid).toBeFalsy();
|
|
223
258
|
}
|
|
224
|
-
|
|
259
|
+
await Promise.all(eventsObj.map(ev => ev.promise));
|
|
225
260
|
if (events)
|
|
226
|
-
|
|
261
|
+
await events.cancel();
|
|
227
262
|
eventsObj.forEach(ev => expect(ev.count).toBeGreaterThanOrEqual(ev.expected));
|
|
228
|
-
|
|
229
|
-
})
|
|
263
|
+
await attachment.dropDatabase();
|
|
264
|
+
});
|
|
230
265
|
});
|
|
231
266
|
describe('Transaction', () => {
|
|
232
|
-
test('#commit()', () =>
|
|
233
|
-
const attachment =
|
|
234
|
-
const transaction =
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
})
|
|
238
|
-
test('#commitRetaining()', () =>
|
|
239
|
-
const attachment =
|
|
240
|
-
const transaction =
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
})
|
|
245
|
-
test('#rollback()', () =>
|
|
246
|
-
const attachment =
|
|
247
|
-
const transaction =
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
})
|
|
251
|
-
test('#rollbackRetaining()', () =>
|
|
252
|
-
const attachment =
|
|
253
|
-
const transaction =
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
})
|
|
258
|
-
test('transaction left opened', () =>
|
|
259
|
-
const attachment =
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
})
|
|
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
|
+
});
|
|
263
298
|
});
|
|
264
299
|
describe('Statement', () => {
|
|
265
|
-
test('#execute()', () =>
|
|
266
|
-
const attachment =
|
|
267
|
-
const transaction =
|
|
268
|
-
const statement1 =
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const statement2 =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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]);
|
|
312
|
+
expect(statement2.isValid).toBeTruthy();
|
|
313
|
+
await statement2.dispose();
|
|
314
|
+
expect(statement2.isValid).toBeFalsy();
|
|
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();
|
|
281
318
|
expect(ret[0].RET).toStrictEqual('111, 3, 4');
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
})
|
|
285
|
-
test('#executeQuery()', () =>
|
|
286
|
-
const attachment =
|
|
287
|
-
const transaction =
|
|
288
|
-
const statement1 =
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const statement2 =
|
|
293
|
-
const resultSet2 =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
})
|
|
299
|
-
test('#
|
|
300
|
-
const attachment =
|
|
301
|
-
const transaction =
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const statement =
|
|
305
|
-
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);
|
|
343
|
+
expect(result.length).toBe(2);
|
|
344
|
+
expect(result[0]).toBe(11);
|
|
345
|
+
expect(result[1]).toBe(11 * 2);
|
|
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);
|
|
306
357
|
expect(result.length).toBe(2);
|
|
307
358
|
expect(result[0]).toBe(11);
|
|
308
359
|
expect(result[1]).toBe(11 * 2);
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
})
|
|
313
|
-
test('#columnLabels()', () =>
|
|
314
|
-
const attachment =
|
|
315
|
-
const transaction =
|
|
316
|
-
const statement1 =
|
|
317
|
-
expect(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const statement2 =
|
|
322
|
-
expect(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
})
|
|
327
|
-
test('#hasResultSet()', () =>
|
|
328
|
-
const attachment =
|
|
329
|
-
const transaction =
|
|
330
|
-
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)');
|
|
331
382
|
expect(statement1.hasResultSet).toBe(false);
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
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)');
|
|
336
387
|
expect(statement2.hasResultSet).toBe(false);
|
|
337
|
-
|
|
338
|
-
const statement3 =
|
|
388
|
+
await statement2.dispose();
|
|
389
|
+
const statement3 = await attachment.prepare(transaction, 'insert into t1 values (1) returning *');
|
|
339
390
|
expect(statement3.hasResultSet).toBe(false);
|
|
340
|
-
|
|
341
|
-
const statement4 =
|
|
391
|
+
await statement3.dispose();
|
|
392
|
+
const statement4 = await attachment.prepare(transaction, 'execute block as begin end');
|
|
342
393
|
expect(statement4.hasResultSet).toBe(false);
|
|
343
|
-
|
|
344
|
-
const statement5 =
|
|
394
|
+
await statement4.dispose();
|
|
395
|
+
const statement5 = await attachment.prepare(transaction, 'select * from t1');
|
|
345
396
|
expect(statement5.hasResultSet).toBe(true);
|
|
346
|
-
|
|
347
|
-
const statement6 =
|
|
397
|
+
await statement5.dispose();
|
|
398
|
+
const statement6 = await attachment.prepare(transaction, 'execute block returns (n integer) as begin suspend; end');
|
|
348
399
|
expect(statement6.hasResultSet).toBe(true);
|
|
349
|
-
|
|
350
|
-
const statement7 =
|
|
400
|
+
await statement6.dispose();
|
|
401
|
+
const statement7 = await attachment.prepare(transaction, 'execute block returns (n integer) as begin end');
|
|
351
402
|
expect(statement7.hasResultSet).toBe(true);
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
})
|
|
403
|
+
await statement7.dispose();
|
|
404
|
+
await transaction.commit();
|
|
405
|
+
await attachment.dropDatabase();
|
|
406
|
+
});
|
|
356
407
|
});
|
|
357
408
|
describe('ResultSet', () => {
|
|
358
|
-
test('#fetch()', () =>
|
|
359
|
-
const attachment =
|
|
360
|
-
let transaction =
|
|
409
|
+
test('#fetch()', async () => {
|
|
410
|
+
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch.fdb'));
|
|
411
|
+
let transaction = await attachment.startTransaction();
|
|
361
412
|
const blobBuffer = Buffer.alloc(11, '12345678á9');
|
|
362
413
|
const fields = [
|
|
363
414
|
{ name: 'x_short', type: 'numeric(2)', valToStr: (v) => v },
|
|
@@ -403,20 +454,23 @@ function runCommonTests(client) {
|
|
|
403
454
|
{ name: 'x_blob1', type: 'blob', valToStr: (v) => `'${v.toString()}'` },
|
|
404
455
|
{ name: 'x_blob2', type: 'blob', valToStr: () => `'${blobBuffer.toString()}'` }
|
|
405
456
|
];
|
|
406
|
-
const statement1 =
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
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();
|
|
410
461
|
const recordCount = 5;
|
|
411
462
|
let parameters;
|
|
412
463
|
{ // scope
|
|
413
|
-
const statement2a =
|
|
464
|
+
const statement2a = await attachment.prepare(transaction, `insert into t1 (${fields.map(f => f.name).join(', ')}) values (${fields.map(() => '?').join(', ')})`);
|
|
414
465
|
// Test execution in a new transaction, after the one used in prepare was committed.
|
|
415
|
-
|
|
416
|
-
transaction =
|
|
417
|
-
const blob =
|
|
418
|
-
|
|
419
|
-
|
|
466
|
+
await transaction.commit();
|
|
467
|
+
transaction = await attachment.startTransaction();
|
|
468
|
+
const blob = await attachment.createBlob(transaction);
|
|
469
|
+
expect(blob.isValid).toBeTruthy();
|
|
470
|
+
await blob.write(blobBuffer);
|
|
471
|
+
expect(blob.isValid).toBeTruthy();
|
|
472
|
+
await blob.close();
|
|
473
|
+
expect(blob.isValid).toBeFalsy();
|
|
420
474
|
parameters = [
|
|
421
475
|
-1,
|
|
422
476
|
-2,
|
|
@@ -452,18 +506,18 @@ function runCommonTests(client) {
|
|
|
452
506
|
blob
|
|
453
507
|
];
|
|
454
508
|
for (let i = 0; i < recordCount; ++i)
|
|
455
|
-
|
|
456
|
-
|
|
509
|
+
await statement2a.execute(transaction, parameters);
|
|
510
|
+
await statement2a.dispose();
|
|
457
511
|
}
|
|
458
512
|
{ // scope
|
|
459
|
-
const statement2b =
|
|
513
|
+
const statement2b = await attachment.prepare(transaction, `insert into t1 (${fields.map(f => f.name).join(', ')}) ` +
|
|
460
514
|
`values (${parameters.map((val, index) => fields[index].valToStr(val)).join(', ')})`);
|
|
461
515
|
for (let i = 0; i < recordCount; ++i)
|
|
462
|
-
|
|
463
|
-
|
|
516
|
+
await statement2b.execute(transaction);
|
|
517
|
+
await statement2b.dispose();
|
|
464
518
|
}
|
|
465
|
-
|
|
466
|
-
const statement3 =
|
|
519
|
+
await transaction.commitRetaining();
|
|
520
|
+
const statement3 = await attachment.prepare(transaction, `select x_short,
|
|
467
521
|
x_int,
|
|
468
522
|
x_int_scale,
|
|
469
523
|
x_bigint,
|
|
@@ -496,8 +550,8 @@ function runCommonTests(client) {
|
|
|
496
550
|
x_blob1,
|
|
497
551
|
x_blob2
|
|
498
552
|
from t1`);
|
|
499
|
-
const resultSet3 =
|
|
500
|
-
const data =
|
|
553
|
+
const resultSet3 = await statement3.executeQuery(transaction);
|
|
554
|
+
const data = await resultSet3.fetch();
|
|
501
555
|
expect(data.length).toBe(recordCount * 2);
|
|
502
556
|
for (const columns of data) {
|
|
503
557
|
let n = 0;
|
|
@@ -533,39 +587,40 @@ function runCommonTests(client) {
|
|
|
533
587
|
expect(columns[n++]).toBeNull();
|
|
534
588
|
for (const i = n + 2; n < i; ++n) {
|
|
535
589
|
const blob = columns[n];
|
|
536
|
-
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
expect(
|
|
540
|
-
|
|
590
|
+
expect(blob.isValid).toBeTruthy();
|
|
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();
|
|
541
596
|
expect(buffer.toString()).toBe('12345678á9');
|
|
542
597
|
}
|
|
543
598
|
expect(columns.length).toBe(n);
|
|
544
599
|
}
|
|
545
|
-
expect((
|
|
546
|
-
expect((
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
})
|
|
552
|
-
test('#fetchAsObject()', () =>
|
|
553
|
-
const attachment =
|
|
554
|
-
const transaction =
|
|
555
|
-
const resultSet =
|
|
556
|
-
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();
|
|
557
612
|
expect(output[0].A).toBe(1);
|
|
558
613
|
expect(output[0].B).toBe(2);
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
})
|
|
563
|
-
test('#fetch() with fetchSize', () =>
|
|
564
|
-
const attachment =
|
|
565
|
-
const transaction =
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
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, `
|
|
569
624
|
execute block
|
|
570
625
|
as
|
|
571
626
|
declare n integer = 0;
|
|
@@ -577,24 +632,24 @@ function runCommonTests(client) {
|
|
|
577
632
|
end
|
|
578
633
|
end
|
|
579
634
|
`);
|
|
580
|
-
const rs =
|
|
635
|
+
const rs = await attachment.executeQuery(transaction, 'select n1 from t1 order by n1');
|
|
581
636
|
rs.defaultFetchOptions = { fetchSize: 5 };
|
|
582
|
-
expect((
|
|
583
|
-
expect((
|
|
584
|
-
expect((
|
|
585
|
-
expect((
|
|
586
|
-
expect((
|
|
587
|
-
expect((
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
})
|
|
592
|
-
test('#fetch() with fetchSize and exception', () =>
|
|
593
|
-
const attachment =
|
|
594
|
-
const transaction =
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
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, `
|
|
598
653
|
execute block returns (n integer)
|
|
599
654
|
as
|
|
600
655
|
begin
|
|
@@ -608,38 +663,67 @@ function runCommonTests(client) {
|
|
|
608
663
|
end
|
|
609
664
|
`);
|
|
610
665
|
rs.defaultFetchOptions = { fetchSize: 5 };
|
|
611
|
-
expect((
|
|
666
|
+
expect((await rs.fetch()).length).toBe(2);
|
|
612
667
|
expect(rs.fetch()).rejects.toBeTruthy();
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
})
|
|
617
|
-
test('#fetch() with large blob', () =>
|
|
618
|
-
const attachment =
|
|
619
|
-
let transaction =
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
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();
|
|
623
678
|
const buffer = Buffer.from('123'.repeat(60000));
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
transaction =
|
|
627
|
-
const resultSet =
|
|
628
|
-
const result =
|
|
629
|
-
const readStream =
|
|
630
|
-
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;
|
|
631
686
|
const resultBuffer = Buffer.alloc(blobLength);
|
|
632
687
|
let size = 0;
|
|
633
688
|
let n;
|
|
634
|
-
while (size < blobLength && (n =
|
|
689
|
+
while (size < blobLength && (n = await readStream.read(resultBuffer.slice(size))) > 0)
|
|
635
690
|
size += n;
|
|
636
|
-
|
|
691
|
+
await readStream.close();
|
|
637
692
|
expect(resultBuffer.toString().length).toEqual(buffer.toString().length);
|
|
638
693
|
expect(resultBuffer.toString()).toEqual(buffer.toString());
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
})
|
|
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, 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, 0 /* BlobSeekWhence.START */)).toBe(1);
|
|
719
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
720
|
+
expect(buffer.toString()).toBe('234');
|
|
721
|
+
expect(await readBlobStream.seek(-2, 2 /* 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
|
+
});
|
|
643
727
|
});
|
|
644
728
|
});
|
|
645
729
|
}
|