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/src/lib/index.ts
CHANGED
|
@@ -9,6 +9,9 @@ export interface Client {
|
|
|
9
9
|
/** Creates a database. */
|
|
10
10
|
createDatabase(uri: string, options?: CreateDatabaseOptions): Promise<Attachment>;
|
|
11
11
|
|
|
12
|
+
/** True if the client has not been disposed. */
|
|
13
|
+
readonly isValid: boolean;
|
|
14
|
+
|
|
12
15
|
/** Default connect options. */
|
|
13
16
|
defaultConnectOptions?: ConnectOptions;
|
|
14
17
|
|
|
@@ -87,6 +90,11 @@ export interface FetchOptions {
|
|
|
87
90
|
fetchSize?: number;
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
/** CreateBlobOptions interface. */
|
|
94
|
+
export interface CreateBlobOptions {
|
|
95
|
+
type?: 'SEGMENTED' | 'STREAM';
|
|
96
|
+
}
|
|
97
|
+
|
|
90
98
|
/** Attachment interface. */
|
|
91
99
|
export interface Attachment {
|
|
92
100
|
/** Disconnects this attachment. */
|
|
@@ -96,7 +104,7 @@ export interface Attachment {
|
|
|
96
104
|
dropDatabase(): Promise<void>;
|
|
97
105
|
|
|
98
106
|
/** Creates a blob and return its stream. */
|
|
99
|
-
createBlob(transaction: Transaction): Promise<BlobStream>;
|
|
107
|
+
createBlob(transaction: Transaction, options?: CreateBlobOptions): Promise<BlobStream>;
|
|
100
108
|
|
|
101
109
|
/** Opens a blob's stream. */
|
|
102
110
|
openBlob(transaction: Transaction, blob: Blob): Promise<BlobStream>;
|
|
@@ -121,13 +129,33 @@ export interface Attachment {
|
|
|
121
129
|
}): Promise<void>;
|
|
122
130
|
|
|
123
131
|
/** Executes a statement that returns a single record as [col1, col2, ..., colN]. */
|
|
124
|
-
|
|
132
|
+
executeSingleton(transaction: Transaction, sqlStmt: string, parameters?: any[],
|
|
125
133
|
options?: {
|
|
126
134
|
prepareOptions?: PrepareOptions,
|
|
127
135
|
executeOptions?: ExecuteOptions
|
|
128
136
|
}): Promise<any[]>;
|
|
129
137
|
|
|
130
138
|
/** Executes a statement that returns a single record as an object. */
|
|
139
|
+
executeSingletonAsObject<T extends object>(transaction: Transaction, sqlStmt: string, parameters?: any[],
|
|
140
|
+
options?: {
|
|
141
|
+
prepareOptions?: PrepareOptions,
|
|
142
|
+
executeOptions?: ExecuteOptions
|
|
143
|
+
}): Promise<T>;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Executes a statement that returns a single record as [col1, col2, ..., colN].
|
|
147
|
+
* @deprecated since version 2.4.0 and will be removed in next major version. Replaced by executeSingleton.
|
|
148
|
+
*/
|
|
149
|
+
executeReturning(transaction: Transaction, sqlStmt: string, parameters?: any[],
|
|
150
|
+
options?: {
|
|
151
|
+
prepareOptions?: PrepareOptions,
|
|
152
|
+
executeOptions?: ExecuteOptions
|
|
153
|
+
}): Promise<any[]>;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Executes a statement that returns a single record as an object.
|
|
157
|
+
* @deprecated since version 2.4.0 and will be removed in next major version. Replaced by executeSingletonAsObject.
|
|
158
|
+
*/
|
|
131
159
|
executeReturningAsObject<T extends object>(transaction: Transaction, sqlStmt: string, parameters?: any[],
|
|
132
160
|
options?: {
|
|
133
161
|
prepareOptions?: PrepareOptions,
|
|
@@ -143,6 +171,9 @@ export interface Attachment {
|
|
|
143
171
|
|
|
144
172
|
queueEvents(names: string[], callBack: (counters: [string, number][]) => Promise<void>): Promise<Events>;
|
|
145
173
|
|
|
174
|
+
/** True if the attachment is connected. */
|
|
175
|
+
readonly isValid: boolean;
|
|
176
|
+
|
|
146
177
|
/** Default transaction options. */
|
|
147
178
|
defaultTransactionOptions?: TransactionOptions;
|
|
148
179
|
|
|
@@ -172,6 +203,9 @@ export interface Transaction {
|
|
|
172
203
|
|
|
173
204
|
/** Rollbacks and maintains this transaction object for subsequent work. */
|
|
174
205
|
rollbackRetaining(): Promise<void>;
|
|
206
|
+
|
|
207
|
+
/** True if the transaction is active. */
|
|
208
|
+
readonly isValid: boolean;
|
|
175
209
|
}
|
|
176
210
|
|
|
177
211
|
/** Statement interface. */
|
|
@@ -186,9 +220,21 @@ export interface Statement {
|
|
|
186
220
|
execute(transaction: Transaction, parameters?: any[], options?: ExecuteOptions): Promise<void>;
|
|
187
221
|
|
|
188
222
|
/** Executes a statement that returns a single record as [col1, col2, ..., colN]. */
|
|
189
|
-
|
|
223
|
+
executeSingleton(transaction: Transaction, parameters?: any[], executeOptions?: ExecuteOptions): Promise<any[]>;
|
|
190
224
|
|
|
191
225
|
/** Executes a statement that returns a single record as an object. */
|
|
226
|
+
executeSingletonAsObject<T extends object>(transaction: Transaction, parameters?: any[], executeOptions?: ExecuteOptions): Promise<T>;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Executes a statement that returns a single record as [col1, col2, ..., colN].
|
|
230
|
+
* @deprecated since version 2.4.0 and will be removed in next major version. Replaced by executeSingleton.
|
|
231
|
+
*/
|
|
232
|
+
executeReturning(transaction: Transaction, parameters?: any[], executeOptions?: ExecuteOptions): Promise<any[]>;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Executes a statement that returns a single record as an object.
|
|
236
|
+
* @deprecated since version 2.4.0 and will be removed in next major version. Replaced by executeSingletonAsObject.
|
|
237
|
+
*/
|
|
192
238
|
executeReturningAsObject<T extends object>(transaction: Transaction, parameters?: any[],
|
|
193
239
|
options?: ExecuteOptions): Promise<T>;
|
|
194
240
|
|
|
@@ -202,6 +248,11 @@ export interface Statement {
|
|
|
202
248
|
*/
|
|
203
249
|
setCursorName(cursorName: string): Promise<void>;
|
|
204
250
|
|
|
251
|
+
getExecPathText(): Promise<string | undefined>;
|
|
252
|
+
|
|
253
|
+
/** True if the statement has not been disposed. */
|
|
254
|
+
readonly isValid: boolean;
|
|
255
|
+
|
|
205
256
|
/** Gets the query's result columns labels. Returns empty array for queries without result. */
|
|
206
257
|
readonly columnLabels: Promise<string[]>;
|
|
207
258
|
|
|
@@ -242,12 +293,18 @@ export interface ResultSet {
|
|
|
242
293
|
*/
|
|
243
294
|
fetchAsObject<T extends object>(options?: FetchOptions): Promise<T[]>;
|
|
244
295
|
|
|
296
|
+
/** True if the ResultSet is open. */
|
|
297
|
+
readonly isValid: boolean;
|
|
298
|
+
|
|
245
299
|
/** Default result set's fetch options. */
|
|
246
300
|
defaultFetchOptions?: FetchOptions;
|
|
247
301
|
}
|
|
248
302
|
|
|
249
303
|
export interface Events {
|
|
250
304
|
cancel(): Promise<void>;
|
|
305
|
+
|
|
306
|
+
/** True if the events' attachment is valid. */
|
|
307
|
+
readonly isValid: boolean;
|
|
251
308
|
}
|
|
252
309
|
|
|
253
310
|
/** Blob class. */
|
|
@@ -262,6 +319,17 @@ export class Blob {
|
|
|
262
319
|
this.attachment = attachment;
|
|
263
320
|
this.id.set(id);
|
|
264
321
|
}
|
|
322
|
+
|
|
323
|
+
/** True if the blob's attachment is valid. */
|
|
324
|
+
get isValid(): boolean {
|
|
325
|
+
return this.attachment.isValid;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export const enum BlobSeekWhence {
|
|
330
|
+
START = 0,
|
|
331
|
+
CURRENT = 1,
|
|
332
|
+
END = 2
|
|
265
333
|
}
|
|
266
334
|
|
|
267
335
|
/** BlobStream class. */
|
|
@@ -282,6 +350,9 @@ export abstract class BlobStream {
|
|
|
282
350
|
/** Cancels the blob's creation. */
|
|
283
351
|
abstract cancel(): Promise<void>;
|
|
284
352
|
|
|
353
|
+
/** Seeks into the blob stream and return the new position. */
|
|
354
|
+
abstract seek(offset: number, whence?: BlobSeekWhence): Promise<number>;
|
|
355
|
+
|
|
285
356
|
/**
|
|
286
357
|
* Reads data from the blob and return the number of bytes read or -1 for end-of-stream.
|
|
287
358
|
* The number of bytes read may be less than the buffer' size while more data to be read exists.
|
|
@@ -290,6 +361,9 @@ export abstract class BlobStream {
|
|
|
290
361
|
|
|
291
362
|
/** Writes data to the blob. */
|
|
292
363
|
abstract write(buffer: Buffer): Promise<void>;
|
|
364
|
+
|
|
365
|
+
/** True if the blob stream is open. */
|
|
366
|
+
abstract get isValid(): boolean;
|
|
293
367
|
}
|
|
294
368
|
|
|
295
369
|
/** TIME WITH TIME ZONE and TIMESTAMP WITH TIME ZONE to be sent as parameter */
|
package/src/test/tests.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Blob,
|
|
3
|
+
BlobSeekWhence,
|
|
3
4
|
Client,
|
|
4
5
|
TransactionIsolation,
|
|
5
6
|
ZonedDate,
|
|
@@ -74,6 +75,8 @@ export function runCommonTests(client: Client) {
|
|
|
74
75
|
|
|
75
76
|
|
|
76
77
|
beforeAll(() => {
|
|
78
|
+
expect(client.isValid).toBeTruthy();
|
|
79
|
+
|
|
77
80
|
if (isLocal() && !testConfig.tmpDir) {
|
|
78
81
|
testConfig.tmpDir = tmp.mkdirSync().path.toString();
|
|
79
82
|
|
|
@@ -99,6 +102,8 @@ export function runCommonTests(client: Client) {
|
|
|
99
102
|
afterAll(async () => {
|
|
100
103
|
await client.dispose();
|
|
101
104
|
|
|
105
|
+
expect(client.isValid).toBeFalsy();
|
|
106
|
+
|
|
102
107
|
if (isLocal())
|
|
103
108
|
fs.rmdirSync(testConfig.tmpDir!);
|
|
104
109
|
});
|
|
@@ -114,8 +119,14 @@ export function runCommonTests(client: Client) {
|
|
|
114
119
|
const attachment1 = await client.createDatabase(filename);
|
|
115
120
|
const attachment2 = await client.connect(filename);
|
|
116
121
|
|
|
122
|
+
expect(attachment1.isValid).toBeTruthy();
|
|
123
|
+
expect(attachment2.isValid).toBeTruthy();
|
|
124
|
+
|
|
117
125
|
await attachment2.disconnect();
|
|
118
126
|
await attachment1.dropDatabase();
|
|
127
|
+
|
|
128
|
+
expect(attachment1.isValid).toBeFalsy();
|
|
129
|
+
expect(attachment2.isValid).toBeFalsy();
|
|
119
130
|
});
|
|
120
131
|
});
|
|
121
132
|
|
|
@@ -126,16 +137,22 @@ export function runCommonTests(client: Client) {
|
|
|
126
137
|
const isolationQuery = 'select rdb$get_context(\'SYSTEM\', \'ISOLATION_LEVEL\') from rdb$database';
|
|
127
138
|
|
|
128
139
|
const transaction1 = await attachment.startTransaction();
|
|
129
|
-
expect(
|
|
140
|
+
expect(transaction1.isValid).toBeTruthy()
|
|
141
|
+
expect((await attachment.executeSingleton(transaction1, isolationQuery))[0]).toBe('SNAPSHOT');
|
|
130
142
|
await transaction1.commit();
|
|
143
|
+
expect(transaction1.isValid).toBeFalsy()
|
|
131
144
|
|
|
132
145
|
const transaction2 = await attachment.startTransaction({ isolation: TransactionIsolation.READ_COMMITTED });
|
|
133
|
-
expect(
|
|
146
|
+
expect(transaction2.isValid).toBeTruthy()
|
|
147
|
+
expect((await attachment.executeSingleton(transaction2, isolationQuery))[0]).toBe('READ COMMITTED');
|
|
134
148
|
await transaction2.commit();
|
|
149
|
+
expect(transaction2.isValid).toBeFalsy()
|
|
135
150
|
|
|
136
151
|
const transaction3 = await attachment.startTransaction({ isolation: TransactionIsolation.CONSISTENCY });
|
|
137
|
-
expect(
|
|
152
|
+
expect(transaction3.isValid).toBeTruthy()
|
|
153
|
+
expect((await attachment.executeSingleton(transaction3, isolationQuery))[0]).toBe('CONSISTENCY');
|
|
138
154
|
await transaction3.commit();
|
|
155
|
+
expect(transaction3.isValid).toBeFalsy()
|
|
139
156
|
|
|
140
157
|
await attachment.dropDatabase();
|
|
141
158
|
});
|
|
@@ -145,7 +162,9 @@ export function runCommonTests(client: Client) {
|
|
|
145
162
|
const transaction = await attachment.startTransaction();
|
|
146
163
|
|
|
147
164
|
const statement = await attachment.prepare(transaction, 'create table t1 (n1 integer)');
|
|
165
|
+
expect(statement.isValid).toBeTruthy();
|
|
148
166
|
await statement.dispose();
|
|
167
|
+
expect(statement.isValid).toBeFalsy();
|
|
149
168
|
|
|
150
169
|
let error: Error | undefined;
|
|
151
170
|
try {
|
|
@@ -189,7 +208,39 @@ export function runCommonTests(client: Client) {
|
|
|
189
208
|
await transaction.commitRetaining();
|
|
190
209
|
|
|
191
210
|
const resultSet = await attachment.executeQuery(transaction, 'select n1 from t1');
|
|
211
|
+
expect(resultSet.isValid).toBeTruthy();
|
|
192
212
|
await resultSet.close();
|
|
213
|
+
expect(resultSet.isValid).toBeFalsy();
|
|
214
|
+
|
|
215
|
+
await transaction.commit();
|
|
216
|
+
await attachment.dropDatabase();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test('#executeSingleton()', async () => {
|
|
220
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingleton.fdb'));
|
|
221
|
+
const transaction = await attachment.startTransaction();
|
|
222
|
+
|
|
223
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
224
|
+
await transaction.commitRetaining();
|
|
225
|
+
|
|
226
|
+
const result = await attachment.executeSingleton(transaction, 'insert into t1 values (11) returning n1');
|
|
227
|
+
expect(result.length).toBe(1);
|
|
228
|
+
expect(result[0]).toBe(11);
|
|
229
|
+
|
|
230
|
+
await transaction.commit();
|
|
231
|
+
await attachment.dropDatabase();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('#executeSingletonAsObject()', async () => {
|
|
235
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingletonAsObject.fdb'));
|
|
236
|
+
const transaction = await attachment.startTransaction();
|
|
237
|
+
|
|
238
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
239
|
+
await transaction.commitRetaining();
|
|
240
|
+
|
|
241
|
+
const output = await attachment.executeSingletonAsObject<{ N1: number }>(transaction,
|
|
242
|
+
'insert into t1 values (11) returning n1');
|
|
243
|
+
expect(output.N1).toBe(11);
|
|
193
244
|
|
|
194
245
|
await transaction.commit();
|
|
195
246
|
await attachment.dropDatabase();
|
|
@@ -260,6 +311,7 @@ export function runCommonTests(client: Client) {
|
|
|
260
311
|
if (Array.from(eventsMap.values()).every(obj => obj.count >= obj.expected)) {
|
|
261
312
|
if (events) {
|
|
262
313
|
await events.cancel();
|
|
314
|
+
expect(events.isValid).toBeFalsy();
|
|
263
315
|
events = null!;
|
|
264
316
|
}
|
|
265
317
|
}
|
|
@@ -285,10 +337,12 @@ export function runCommonTests(client: Client) {
|
|
|
285
337
|
// Commit retaining to test internal event rescheduling
|
|
286
338
|
// after each handler dispatch.
|
|
287
339
|
await transaction.commitRetaining();
|
|
340
|
+
expect(transaction.isValid).toBeTruthy();
|
|
288
341
|
}
|
|
289
342
|
}
|
|
290
343
|
finally {
|
|
291
344
|
await transaction.commit();
|
|
345
|
+
expect(transaction.isValid).toBeFalsy();
|
|
292
346
|
}
|
|
293
347
|
|
|
294
348
|
await Promise.all(eventsObj.map(ev => ev.promise));
|
|
@@ -355,7 +409,9 @@ export function runCommonTests(client: Client) {
|
|
|
355
409
|
await statement2.execute(transaction, [null]);
|
|
356
410
|
await statement2.execute(transaction, [10]);
|
|
357
411
|
await statement2.execute(transaction, [100]);
|
|
412
|
+
expect(statement2.isValid).toBeTruthy();
|
|
358
413
|
await statement2.dispose();
|
|
414
|
+
expect(statement2.isValid).toBeFalsy();
|
|
359
415
|
|
|
360
416
|
const rs = await attachment.executeQuery(transaction,
|
|
361
417
|
`select sum(n1) || ', ' || count(n1) || ', ' || count(*) ret from t1`);
|
|
@@ -386,6 +442,26 @@ export function runCommonTests(client: Client) {
|
|
|
386
442
|
await attachment.dropDatabase();
|
|
387
443
|
});
|
|
388
444
|
|
|
445
|
+
test('#executeSingleton()', async () => {
|
|
446
|
+
const attachment = await client.createDatabase(getTempFile('Attachment-executeSingleton.fdb'));
|
|
447
|
+
const transaction = await attachment.startTransaction();
|
|
448
|
+
|
|
449
|
+
await attachment.execute(transaction, 'create table t1 (n1 integer)');
|
|
450
|
+
await transaction.commitRetaining();
|
|
451
|
+
|
|
452
|
+
const statement = await attachment.prepare(transaction, 'insert into t1 values (11) returning n1, n1 * 2');
|
|
453
|
+
|
|
454
|
+
const result = await statement.executeSingleton(transaction);
|
|
455
|
+
expect(result.length).toBe(2);
|
|
456
|
+
expect(result[0]).toBe(11);
|
|
457
|
+
expect(result[1]).toBe(11 * 2);
|
|
458
|
+
|
|
459
|
+
await statement.dispose();
|
|
460
|
+
|
|
461
|
+
await transaction.commit();
|
|
462
|
+
await attachment.dropDatabase();
|
|
463
|
+
});
|
|
464
|
+
|
|
389
465
|
test('#executeReturning()', async () => {
|
|
390
466
|
const attachment = await client.createDatabase(getTempFile('Attachment-executeReturning.fdb'));
|
|
391
467
|
const transaction = await attachment.startTransaction();
|
|
@@ -467,6 +543,7 @@ export function runCommonTests(client: Client) {
|
|
|
467
543
|
describe('ResultSet', () => {
|
|
468
544
|
test('#fetch()', async () => {
|
|
469
545
|
const attachment = await client.createDatabase(getTempFile('ResultSet-fetch.fdb'));
|
|
546
|
+
|
|
470
547
|
let transaction = await attachment.startTransaction();
|
|
471
548
|
|
|
472
549
|
const blobBuffer = Buffer.alloc(11, '12345678á9');
|
|
@@ -538,8 +615,11 @@ export function runCommonTests(client: Client) {
|
|
|
538
615
|
transaction = await attachment.startTransaction();
|
|
539
616
|
|
|
540
617
|
const blob = await attachment.createBlob(transaction);
|
|
618
|
+
expect(blob.isValid).toBeTruthy();
|
|
541
619
|
await blob.write(blobBuffer);
|
|
620
|
+
expect(blob.isValid).toBeTruthy();
|
|
542
621
|
await blob.close();
|
|
622
|
+
expect(blob.isValid).toBeFalsy();
|
|
543
623
|
|
|
544
624
|
parameters = [
|
|
545
625
|
-1,
|
|
@@ -667,6 +747,7 @@ export function runCommonTests(client: Client) {
|
|
|
667
747
|
|
|
668
748
|
for (const i = n + 2; n < i; ++n) {
|
|
669
749
|
const blob = columns[n] as Blob;
|
|
750
|
+
expect(blob.isValid).toBeTruthy();
|
|
670
751
|
const blobStream = await attachment.openBlob(transaction, blob);
|
|
671
752
|
const buffer = Buffer.alloc(await blobStream.length);
|
|
672
753
|
expect(await blobStream.read(buffer)).toBe(buffer.length);
|
|
@@ -805,5 +886,44 @@ export function runCommonTests(client: Client) {
|
|
|
805
886
|
await attachment.dropDatabase();
|
|
806
887
|
});
|
|
807
888
|
});
|
|
889
|
+
|
|
890
|
+
describe('BlobStream', () => {
|
|
891
|
+
test('#seek()', async () => {
|
|
892
|
+
const attachment = await client.createDatabase(getTempFile('BlobStream-seek.fdb'));
|
|
893
|
+
const transaction = await attachment.startTransaction();
|
|
894
|
+
|
|
895
|
+
await attachment.execute(transaction, 'create table t1 (b blob)');
|
|
896
|
+
await transaction.commitRetaining();
|
|
897
|
+
|
|
898
|
+
const blobStream = await attachment.createBlob(transaction, { type: 'STREAM' });
|
|
899
|
+
await blobStream.write(Buffer.alloc(10, '1234567890'));
|
|
900
|
+
await blobStream.close();
|
|
901
|
+
await attachment.execute(transaction, 'insert into t1 (b) values (?)', [blobStream.blob]);
|
|
902
|
+
|
|
903
|
+
const blob = (await attachment.executeSingleton(transaction, 'select b from t1'))[0] as Blob;
|
|
904
|
+
const readBlobStream = await attachment.openBlob(transaction, blob);
|
|
905
|
+
|
|
906
|
+
const buffer = Buffer.alloc(3);
|
|
907
|
+
|
|
908
|
+
expect(await readBlobStream.seek(2)).toBe(2);
|
|
909
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
910
|
+
expect(buffer.toString()).toBe('345');
|
|
911
|
+
|
|
912
|
+
expect(await readBlobStream.seek(-1, BlobSeekWhence.CURRENT)).toBe(4);
|
|
913
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
914
|
+
expect(buffer.toString()).toBe('567');
|
|
915
|
+
|
|
916
|
+
expect(await readBlobStream.seek(1, BlobSeekWhence.START)).toBe(1);
|
|
917
|
+
expect(await readBlobStream.read(buffer)).toBe(3);
|
|
918
|
+
expect(buffer.toString()).toBe('234');
|
|
919
|
+
|
|
920
|
+
expect(await readBlobStream.seek(-2, BlobSeekWhence.END)).toBe(8);
|
|
921
|
+
expect(await readBlobStream.read(buffer)).toBe(2);
|
|
922
|
+
expect(buffer.slice(0, 2).toString()).toBe('90');
|
|
923
|
+
|
|
924
|
+
await transaction.commit();
|
|
925
|
+
await attachment.dropDatabase();
|
|
926
|
+
});
|
|
927
|
+
});
|
|
808
928
|
});
|
|
809
929
|
}
|