firebird-wasm 0.2.0 → 0.4.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/CHANGELOG.md +199 -0
- package/README.md +4 -1
- package/dist/.tsbuildinfo.build +1 -1
- package/dist/browser/engine-transport.d.ts +63 -5
- package/dist/browser/engine-transport.d.ts.map +1 -1
- package/dist/browser/engine-transport.js +290 -8
- package/dist/browser/engine-transport.js.map +1 -1
- package/dist/browser/firebird-browser.d.ts +252 -7
- package/dist/browser/firebird-browser.d.ts.map +1 -1
- package/dist/browser/firebird-browser.js +373 -20
- package/dist/browser/firebird-browser.js.map +1 -1
- package/dist/browser/index.d.ts +8 -2
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +19 -3
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/opfs-fs.d.ts +72 -0
- package/dist/browser/opfs-fs.d.ts.map +1 -0
- package/dist/browser/opfs-fs.js +249 -0
- package/dist/browser/opfs-fs.js.map +1 -0
- package/dist/browser/params.d.ts +30 -3
- package/dist/browser/params.d.ts.map +1 -1
- package/dist/browser/params.js +97 -22
- package/dist/browser/params.js.map +1 -1
- package/dist/browser/shared-transport.d.ts +9 -2
- package/dist/browser/shared-transport.d.ts.map +1 -1
- package/dist/browser/shared-transport.js +33 -2
- package/dist/browser/shared-transport.js.map +1 -1
- package/dist/browser/statement-types.d.ts +18 -0
- package/dist/browser/statement-types.d.ts.map +1 -0
- package/dist/browser/statement-types.js +39 -0
- package/dist/browser/statement-types.js.map +1 -0
- package/dist/browser/value-types.d.ts +173 -0
- package/dist/browser/value-types.d.ts.map +1 -0
- package/dist/browser/value-types.js +222 -0
- package/dist/browser/value-types.js.map +1 -0
- package/dist/browser/worker-entry.d.ts.map +1 -1
- package/dist/browser/worker-entry.js +38 -1
- package/dist/browser/worker-entry.js.map +1 -1
- package/dist/browser/worker-protocol.d.ts +1 -1
- package/dist/browser/worker-protocol.d.ts.map +1 -1
- package/dist/browser/worker-transport.d.ts +9 -2
- package/dist/browser/worker-transport.d.ts.map +1 -1
- package/dist/browser/worker-transport.js +29 -2
- package/dist/browser/worker-transport.js.map +1 -1
- package/dist/firebird.d.ts +69 -5
- package/dist/firebird.d.ts.map +1 -1
- package/dist/firebird.js +187 -49
- package/dist/firebird.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/sql-tag.d.ts +184 -0
- package/dist/sql-tag.d.ts.map +1 -0
- package/dist/sql-tag.js +287 -0
- package/dist/sql-tag.js.map +1 -0
- package/dist/statement-types.d.ts +23 -0
- package/dist/statement-types.d.ts.map +1 -0
- package/dist/statement-types.js +44 -0
- package/dist/statement-types.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wasm/firebird-embedded.js +1 -1
- package/dist/wasm/firebird-embedded.wasm +0 -0
- package/dist/wasm-loader.d.ts +44 -2
- package/dist/wasm-loader.d.ts.map +1 -1
- package/dist/wasm-loader.js.map +1 -1
- package/package.json +3 -2
|
@@ -25,6 +25,36 @@
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.serveEngine = serveEngine;
|
|
27
27
|
const engine_transport_1 = require("./engine-transport");
|
|
28
|
+
/**
|
|
29
|
+
* Every distinct ArrayBuffer behind a Uint8Array in a query result.
|
|
30
|
+
*
|
|
31
|
+
* Only query results are walked, and only one level into each row: a value is
|
|
32
|
+
* either a blob or it is not, and scanning arbitrary structures on every reply
|
|
33
|
+
* would cost more than the transfer saves.
|
|
34
|
+
*
|
|
35
|
+
* De-duplicated because transferring the same buffer twice throws
|
|
36
|
+
* DataCloneError, and two rows can hold views on one buffer if the same blob
|
|
37
|
+
* appeared twice.
|
|
38
|
+
*/
|
|
39
|
+
function collectBlobBuffers(result) {
|
|
40
|
+
if (typeof result !== 'object' || result === null)
|
|
41
|
+
return [];
|
|
42
|
+
const rows = result.rows;
|
|
43
|
+
if (!Array.isArray(rows))
|
|
44
|
+
return [];
|
|
45
|
+
const buffers = new Set();
|
|
46
|
+
for (const row of rows) {
|
|
47
|
+
if (typeof row !== 'object' || row === null)
|
|
48
|
+
continue;
|
|
49
|
+
// Rows are arrays in rowMode 'array' and plain objects otherwise;
|
|
50
|
+
// Object.values covers both.
|
|
51
|
+
for (const value of Object.values(row)) {
|
|
52
|
+
if (value instanceof Uint8Array)
|
|
53
|
+
buffers.add(value.buffer);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return [...buffers];
|
|
57
|
+
}
|
|
28
58
|
/**
|
|
29
59
|
* Wire a transport up to a Worker scope.
|
|
30
60
|
*
|
|
@@ -35,7 +65,14 @@ function serveEngine(scope, transport) {
|
|
|
35
65
|
const reply = (response) => {
|
|
36
66
|
// Transfer the buffer for readFile rather than copying it: a database
|
|
37
67
|
// image is measured in megabytes and this runs on every persist.
|
|
38
|
-
|
|
68
|
+
//
|
|
69
|
+
// The same applies to binary BLOBs coming back from a query, which arrive
|
|
70
|
+
// as Uint8Arrays inside the rows. Structured cloning would copy every one
|
|
71
|
+
// of them across the boundary — the cost a base64 string could never avoid
|
|
72
|
+
// and the reason the side channel is worth having at all.
|
|
73
|
+
const transfer = response.result instanceof Uint8Array
|
|
74
|
+
? [response.result.buffer]
|
|
75
|
+
: collectBlobBuffers(response.result);
|
|
39
76
|
scope.postMessage(response, transfer);
|
|
40
77
|
};
|
|
41
78
|
scope.addEventListener('message', (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/browser/worker-entry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;
|
|
1
|
+
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/browser/worker-entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { Row, QueryResult } from '../types';
|
|
9
9
|
import type { EngineHandle } from './engine-transport';
|
|
10
10
|
/** Operations the Worker understands. One per EngineTransport method. */
|
|
11
|
-
export type EngineOp = 'init' | 'createDatabase' | 'attachDatabase' | 'detachDatabase' | 'execute' | 'query' | 'startTransaction' | 'commit' | 'rollback' | 'mkdir' | 'exists' | 'readFile' | 'writeFile';
|
|
11
|
+
export type EngineOp = 'init' | 'createDatabase' | 'attachDatabase' | 'detachDatabase' | 'execute' | 'executeBatch' | 'query' | 'describe' | 'startTransaction' | 'commit' | 'rollback' | 'mkdir' | 'exists' | 'readFile' | 'writeFile' | 'unlink' | 'mountOpfs' | 'eventsSubscribe' | 'eventsPoll' | 'eventsCancel';
|
|
12
12
|
/** A call from the main thread to the Worker. */
|
|
13
13
|
export interface EngineRequest {
|
|
14
14
|
id: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-protocol.d.ts","sourceRoot":"","sources":["../../src/browser/worker-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,OAAO,GACP,kBAAkB,GAClB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-protocol.d.ts","sourceRoot":"","sources":["../../src/browser/worker-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,cAAc,GACd,OAAO,GACP,UAAU,GACV,kBAAkB,GAClB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,GACX,QAAQ,GACR,WAAW,GACX,iBAAiB,GACjB,YAAY,GACZ,cAAc,CAAC;AAEnB,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,yBAAyB;IACzB,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAChF;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,CAAC,CAAC,CAAC;IACP,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* The Worker also owns Emscripten's filesystem, which is why the filesystem
|
|
10
10
|
* operations are part of the transport rather than being done by the caller.
|
|
11
11
|
*/
|
|
12
|
-
import type { Row, QueryResult, QueryParams, TransactionOptions } from '../types';
|
|
12
|
+
import type { Row, QueryResult, QueryDescription, QueryParams, RowMode, TransactionOptions } from '../types';
|
|
13
13
|
import type { EngineHandle, EngineTransport } from './engine-transport';
|
|
14
14
|
/** Options accepted by {@link WorkerTransport}. */
|
|
15
15
|
export interface WorkerTransportOptions {
|
|
@@ -50,7 +50,9 @@ export declare class WorkerTransport implements EngineTransport {
|
|
|
50
50
|
attachDatabase(path: string): Promise<EngineHandle>;
|
|
51
51
|
detachDatabase(dbHandle: EngineHandle): Promise<void>;
|
|
52
52
|
execute(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<number>;
|
|
53
|
-
|
|
53
|
+
executeBatch(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, rows: QueryParams[]): Promise<number>;
|
|
54
|
+
query<T = Row>(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams, rowMode?: RowMode, binaryBlobs?: boolean): Promise<QueryResult<T>>;
|
|
55
|
+
describe(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string): Promise<QueryDescription>;
|
|
54
56
|
startTransaction(dbHandle: EngineHandle, options?: TransactionOptions): Promise<EngineHandle>;
|
|
55
57
|
commit(txHandle: EngineHandle): Promise<void>;
|
|
56
58
|
rollback(txHandle: EngineHandle): Promise<void>;
|
|
@@ -58,6 +60,11 @@ export declare class WorkerTransport implements EngineTransport {
|
|
|
58
60
|
exists(path: string): Promise<boolean>;
|
|
59
61
|
readFile(path: string): Promise<Uint8Array>;
|
|
60
62
|
writeFile(path: string, data: Uint8Array): Promise<void>;
|
|
63
|
+
unlink(path: string): Promise<void>;
|
|
64
|
+
eventsSubscribe(dbHandle: EngineHandle, names: string[]): Promise<number>;
|
|
65
|
+
eventsPoll(subscription: number): Promise<Record<string, number>>;
|
|
66
|
+
eventsCancel(subscription: number): Promise<void>;
|
|
67
|
+
mountOpfs(dbName: string): Promise<string>;
|
|
61
68
|
dispose(): Promise<void>;
|
|
62
69
|
}
|
|
63
70
|
//# sourceMappingURL=worker-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -98,8 +98,19 @@ class WorkerTransport {
|
|
|
98
98
|
execute(dbHandle, txHandle, sql, params = []) {
|
|
99
99
|
return this.call('execute', dbHandle, txHandle, sql, params);
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
return this.call('
|
|
101
|
+
executeBatch(dbHandle, txHandle, sql, rows) {
|
|
102
|
+
return this.call('executeBatch', dbHandle, txHandle, sql, rows);
|
|
103
|
+
}
|
|
104
|
+
query(dbHandle, txHandle, sql, params = [], rowMode = 'object', binaryBlobs = false) {
|
|
105
|
+
// Decoding happens on the far side, so both of these have to travel with
|
|
106
|
+
// the call rather than being applied to what comes back. They are a string
|
|
107
|
+
// and a boolean, so they survive structured cloning like the rest of the
|
|
108
|
+
// arguments — and the Uint8Arrays that come back from a side-channelled
|
|
109
|
+
// BLOB survive it too, which is what made this placement possible.
|
|
110
|
+
return this.call('query', dbHandle, txHandle, sql, params, rowMode, binaryBlobs);
|
|
111
|
+
}
|
|
112
|
+
describe(dbHandle, txHandle, sql) {
|
|
113
|
+
return this.call('describe', dbHandle, txHandle, sql);
|
|
103
114
|
}
|
|
104
115
|
startTransaction(dbHandle, options = {}) {
|
|
105
116
|
// Plain data, so it survives structured cloning to the Worker as-is.
|
|
@@ -123,6 +134,22 @@ class WorkerTransport {
|
|
|
123
134
|
writeFile(path, data) {
|
|
124
135
|
return this.call('writeFile', path, data);
|
|
125
136
|
}
|
|
137
|
+
unlink(path) {
|
|
138
|
+
return this.call('unlink', path);
|
|
139
|
+
}
|
|
140
|
+
eventsSubscribe(dbHandle, names) {
|
|
141
|
+
return this.call('eventsSubscribe', dbHandle, names);
|
|
142
|
+
}
|
|
143
|
+
eventsPoll(subscription) {
|
|
144
|
+
return this.call('eventsPoll', subscription);
|
|
145
|
+
}
|
|
146
|
+
eventsCancel(subscription) {
|
|
147
|
+
return this.call('eventsCancel', subscription);
|
|
148
|
+
}
|
|
149
|
+
mountOpfs(dbName) {
|
|
150
|
+
// The mount happens on the far side; only the resulting path comes back.
|
|
151
|
+
return this.call('mountOpfs', dbName);
|
|
152
|
+
}
|
|
126
153
|
async dispose() {
|
|
127
154
|
this.worker.removeEventListener('message', this.onMessage);
|
|
128
155
|
this.worker.removeEventListener('error', this.onError);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-transport.js","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;
|
|
1
|
+
{"version":3,"file":"worker-transport.js","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/firebird.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { Attachment, Transaction } from 'node-firebird-driver';
|
|
2
|
-
import type { FirebirdLiteOptions, QueryResult, Row, QueryParams, TransactionOptions } from './types';
|
|
2
|
+
import type { ArrayRow, FirebirdLiteOptions, QueryDescription, QueryResult, QueryOptions, Row, QueryParams, RowMode, TransactionOptions } from './types';
|
|
3
|
+
import type { SqlFragment } from './sql-tag';
|
|
4
|
+
/** `QueryOptions` with the array mode pinned, for the overloads below. */
|
|
5
|
+
type ArrayModeOptions = QueryOptions & {
|
|
6
|
+
rowMode: 'array';
|
|
7
|
+
};
|
|
3
8
|
/**
|
|
4
9
|
* FirebirdLite – a PGlite-style wrapper around Firebird Embedded.
|
|
5
10
|
*
|
|
@@ -32,15 +37,53 @@ export declare class FirebirdLite {
|
|
|
32
37
|
* Execute a DDL or DML statement that does not return rows.
|
|
33
38
|
*
|
|
34
39
|
* The statement is executed in its own auto-committed transaction.
|
|
40
|
+
*
|
|
41
|
+
* Accepts a `` sql`…` `` fragment in place of a string, in which case its
|
|
42
|
+
* values are bound rather than interpolated.
|
|
43
|
+
*/
|
|
44
|
+
exec(sql: string | SqlFragment, params?: QueryParams): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Execute one statement once per row of parameters: a batch, prepared once
|
|
47
|
+
* and executed per row in one transaction, all or nothing. The same call
|
|
48
|
+
* as the browser backend's.
|
|
35
49
|
*/
|
|
36
|
-
|
|
50
|
+
execBatch(sql: string, rows: QueryParams[]): Promise<void>;
|
|
37
51
|
/**
|
|
38
52
|
* Execute a (parameterised) SQL statement and return the result rows.
|
|
39
53
|
*
|
|
40
54
|
* For SELECT queries the rows are returned as plain objects keyed by the
|
|
41
55
|
* (upper-cased) column name, mirroring the PGlite convention.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* await db.query('SELECT * FROM items WHERE id = ?', [id]);
|
|
59
|
+
* await db.query(sql`SELECT * FROM items WHERE id = ${id}`);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
query(sql: SqlFragment, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
|
|
63
|
+
query(sql: string | SqlFragment, params: QueryParams | undefined, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
|
|
64
|
+
query<T extends Row = Row>(sql: SqlFragment, options?: QueryOptions): Promise<QueryResult<T>>;
|
|
65
|
+
query<T extends Row = Row>(sql: string, params?: QueryParams, options?: QueryOptions): Promise<QueryResult<T>>;
|
|
66
|
+
query<T extends Row = Row>(sql: string | SqlFragment, params?: QueryParams, options?: QueryOptions): Promise<QueryResult<T>>;
|
|
67
|
+
/**
|
|
68
|
+
* Describe a statement's shape without running it.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* const shape = await db.describeQuery('SELECT id, name FROM items WHERE id = ?');
|
|
72
|
+
* // shape.fields → [{ name: 'ID' }, { name: 'NAME' }]
|
|
73
|
+
* // shape.statementType → 'SELECT'
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* The statement is prepared and disposed, so nothing runs: describing an
|
|
77
|
+
* `INSERT` inserts nothing.
|
|
78
|
+
*
|
|
79
|
+
* **`params` is `undefined` here.** The native driver exposes no input
|
|
80
|
+
* metadata — `Statement` offers `columnLabels`, `hasResultSet` and `type`
|
|
81
|
+
* and nothing about `?` placeholders — and an empty array would claim the
|
|
82
|
+
* statement takes none. `fields` carries names only, for the same reason
|
|
83
|
+
* `FieldInfo` does everywhere on this backend. The WASM backend reports both
|
|
84
|
+
* in full.
|
|
42
85
|
*/
|
|
43
|
-
|
|
86
|
+
describeQuery(sql: string | SqlFragment): Promise<QueryDescription>;
|
|
44
87
|
/**
|
|
45
88
|
* Run a function inside an explicit transaction.
|
|
46
89
|
*
|
|
@@ -60,14 +103,35 @@ export declare class FirebirdLite {
|
|
|
60
103
|
export declare class FirebirdTransaction {
|
|
61
104
|
private readonly attachment;
|
|
62
105
|
private readonly transaction;
|
|
106
|
+
private finished;
|
|
63
107
|
constructor(attachment: Attachment, transaction: Transaction);
|
|
108
|
+
/** Whether this transaction has already been rolled back. */
|
|
109
|
+
get isFinished(): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Roll this transaction back and stop.
|
|
112
|
+
*
|
|
113
|
+
* The enclosing `transaction()` will not commit afterwards. Use this to
|
|
114
|
+
* abandon a transaction deliberately, rather than throwing an error you do
|
|
115
|
+
* not mean — throwing also rolls back, but it propagates to the caller.
|
|
116
|
+
*/
|
|
117
|
+
rollback(): Promise<void>;
|
|
118
|
+
private assertUsable;
|
|
64
119
|
/**
|
|
65
120
|
* Execute a DDL or DML statement inside this transaction.
|
|
66
121
|
*/
|
|
67
|
-
exec(sql: string, params?: QueryParams): Promise<void>;
|
|
122
|
+
exec(sql: string | SqlFragment, params?: QueryParams): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Execute one statement once per row of parameters inside this
|
|
125
|
+
* transaction: prepared once, executed per row.
|
|
126
|
+
*/
|
|
127
|
+
execBatch(sql: string, rows: QueryParams[]): Promise<void>;
|
|
68
128
|
/**
|
|
69
129
|
* Execute a SELECT statement inside this transaction and return rows.
|
|
70
130
|
*/
|
|
71
|
-
query
|
|
131
|
+
query(sql: string | SqlFragment, params: QueryParams | undefined, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
|
|
132
|
+
query<T extends Row = Row>(sql: string | SqlFragment, params?: QueryParams, options?: {
|
|
133
|
+
rowMode?: RowMode;
|
|
134
|
+
}): Promise<QueryResult<T>>;
|
|
72
135
|
}
|
|
136
|
+
export {};
|
|
73
137
|
//# sourceMappingURL=firebird.d.ts.map
|
package/dist/firebird.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firebird.d.ts","sourceRoot":"","sources":["../src/firebird.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,UAAU,EACV,WAAW,EAEZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EACX,GAAG,EACH,WAAW,EACX,kBAAkB,EAEnB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"firebird.d.ts","sourceRoot":"","sources":["../src/firebird.ts"],"names":[],"mappings":"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"}
|
package/dist/firebird.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FirebirdTransaction = exports.FirebirdLite = void 0;
|
|
4
4
|
const node_firebird_driver_native_1 = require("node-firebird-driver-native");
|
|
5
5
|
const node_firebird_driver_1 = require("node-firebird-driver");
|
|
6
|
+
const statement_types_1 = require("./statement-types");
|
|
7
|
+
const sql_tag_1 = require("./sql-tag");
|
|
6
8
|
/**
|
|
7
9
|
* FirebirdLite – a PGlite-style wrapper around Firebird Embedded.
|
|
8
10
|
*
|
|
@@ -54,14 +56,72 @@ class FirebirdLite {
|
|
|
54
56
|
* Execute a DDL or DML statement that does not return rows.
|
|
55
57
|
*
|
|
56
58
|
* The statement is executed in its own auto-committed transaction.
|
|
59
|
+
*
|
|
60
|
+
* Accepts a `` sql`…` `` fragment in place of a string, in which case its
|
|
61
|
+
* values are bound rather than interpolated.
|
|
62
|
+
*/
|
|
63
|
+
async exec(sql, params = []) {
|
|
64
|
+
// Delegated rather than reimplemented: "parameters present → prepare,
|
|
65
|
+
// execute, dispose; otherwise execute directly" is a rule that belongs in
|
|
66
|
+
// one place, and `transaction()` already wraps it in the commit-or-roll-
|
|
67
|
+
// back this needs. Two copies would drift the first time either grows a
|
|
68
|
+
// case.
|
|
69
|
+
await this.transaction((tx) => tx.exec(sql, params));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Execute one statement once per row of parameters: a batch, prepared once
|
|
73
|
+
* and executed per row in one transaction, all or nothing. The same call
|
|
74
|
+
* as the browser backend's.
|
|
57
75
|
*/
|
|
58
|
-
async
|
|
76
|
+
async execBatch(sql, rows) {
|
|
77
|
+
await this.transaction((tx) => tx.execBatch(sql, rows));
|
|
78
|
+
}
|
|
79
|
+
async query(sql, paramsOrOptions = [], maybeOptions = {}) {
|
|
59
80
|
await this.ensureReady();
|
|
81
|
+
const { statement, options } = (0, sql_tag_1.resolveQueryCall)(sql, paramsOrOptions, maybeOptions);
|
|
82
|
+
const rowMode = options.rowMode ?? 'object';
|
|
60
83
|
const attachment = this.attachment;
|
|
61
|
-
const
|
|
84
|
+
const txOptions = buildTransactionOptions(options);
|
|
85
|
+
const transaction = await attachment.startTransaction(txOptions);
|
|
62
86
|
try {
|
|
63
|
-
await attachment.
|
|
87
|
+
const stmt = await attachment.prepare(transaction, statement.sql);
|
|
88
|
+
let rows;
|
|
89
|
+
let fields;
|
|
90
|
+
// Disposed in `finally`, not after the fetch: a statement that throws on
|
|
91
|
+
// execute — a lock conflict, an overflow, a wrong parameter count — would
|
|
92
|
+
// otherwise leak its handle, and the retry loop such failures are usually
|
|
93
|
+
// wrapped in leaks one per attempt until the attachment refuses more.
|
|
94
|
+
try {
|
|
95
|
+
const columnLabels = await stmt.columnLabels;
|
|
96
|
+
fields = columnLabels.map((label) => ({ name: label.toUpperCase() }));
|
|
97
|
+
if (stmt.hasResultSet) {
|
|
98
|
+
const resultSet = await stmt.executeQuery(transaction, statement.params);
|
|
99
|
+
// Same reasoning one level down: a failing fetch must still close.
|
|
100
|
+
try {
|
|
101
|
+
const rawRows = await resultSet.fetch();
|
|
102
|
+
// The driver already hands back positional rows, so array mode is
|
|
103
|
+
// the shape that costs nothing — object mode is the one that
|
|
104
|
+
// builds.
|
|
105
|
+
rows = (rowMode === 'array'
|
|
106
|
+
? rawRows
|
|
107
|
+
: rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]]))));
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await resultSet.close().catch(() => undefined);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await stmt.execute(transaction, statement.params);
|
|
115
|
+
rows = [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
await stmt.dispose().catch(() => undefined);
|
|
120
|
+
}
|
|
121
|
+
// After the statement is disposed, as before — the commit is the last
|
|
122
|
+
// thing that happens on the success path.
|
|
64
123
|
await transaction.commit();
|
|
124
|
+
return { rows, fields };
|
|
65
125
|
}
|
|
66
126
|
catch (err) {
|
|
67
127
|
await transaction.rollback().catch(() => undefined);
|
|
@@ -69,40 +129,49 @@ class FirebirdLite {
|
|
|
69
129
|
}
|
|
70
130
|
}
|
|
71
131
|
/**
|
|
72
|
-
*
|
|
132
|
+
* Describe a statement's shape without running it.
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* const shape = await db.describeQuery('SELECT id, name FROM items WHERE id = ?');
|
|
136
|
+
* // shape.fields → [{ name: 'ID' }, { name: 'NAME' }]
|
|
137
|
+
* // shape.statementType → 'SELECT'
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* The statement is prepared and disposed, so nothing runs: describing an
|
|
141
|
+
* `INSERT` inserts nothing.
|
|
73
142
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
143
|
+
* **`params` is `undefined` here.** The native driver exposes no input
|
|
144
|
+
* metadata — `Statement` offers `columnLabels`, `hasResultSet` and `type`
|
|
145
|
+
* and nothing about `?` placeholders — and an empty array would claim the
|
|
146
|
+
* statement takes none. `fields` carries names only, for the same reason
|
|
147
|
+
* `FieldInfo` does everywhere on this backend. The WASM backend reports both
|
|
148
|
+
* in full.
|
|
76
149
|
*/
|
|
77
|
-
async
|
|
150
|
+
async describeQuery(sql) {
|
|
78
151
|
await this.ensureReady();
|
|
79
152
|
const attachment = this.attachment;
|
|
80
|
-
const
|
|
81
|
-
const transaction = await attachment.startTransaction(
|
|
153
|
+
const text = (0, sql_tag_1.toStatement)(sql).sql;
|
|
154
|
+
const transaction = await attachment.startTransaction();
|
|
82
155
|
try {
|
|
83
|
-
const stmt = await attachment.prepare(transaction,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
rows = rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]])));
|
|
156
|
+
const stmt = await attachment.prepare(transaction, text);
|
|
157
|
+
try {
|
|
158
|
+
const columnLabels = await stmt.columnLabels;
|
|
159
|
+
const type = await stmt.type;
|
|
160
|
+
return {
|
|
161
|
+
params: undefined,
|
|
162
|
+
fields: columnLabels.map((label) => ({ name: label.toUpperCase() })),
|
|
163
|
+
statementType: (0, statement_types_1.statementKind)(type),
|
|
164
|
+
hasResultSet: stmt.hasResultSet,
|
|
165
|
+
};
|
|
94
166
|
}
|
|
95
|
-
|
|
96
|
-
await stmt.
|
|
97
|
-
rows = [];
|
|
167
|
+
finally {
|
|
168
|
+
await stmt.dispose().catch(() => undefined);
|
|
98
169
|
}
|
|
99
|
-
await stmt.dispose();
|
|
100
|
-
await transaction.commit();
|
|
101
|
-
return { rows, fields };
|
|
102
170
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
171
|
+
finally {
|
|
172
|
+
// Nothing ran, so there is nothing to commit — but the transaction still
|
|
173
|
+
// has to be finished.
|
|
174
|
+
await transaction.commit().catch(() => undefined);
|
|
106
175
|
}
|
|
107
176
|
}
|
|
108
177
|
/**
|
|
@@ -117,15 +186,24 @@ class FirebirdLite {
|
|
|
117
186
|
const txOptions = buildTransactionOptions(options);
|
|
118
187
|
const transaction = await attachment.startTransaction(txOptions);
|
|
119
188
|
const tx = new FirebirdTransaction(attachment, transaction);
|
|
189
|
+
let result;
|
|
120
190
|
try {
|
|
121
|
-
|
|
122
|
-
await transaction.commit();
|
|
123
|
-
return result;
|
|
191
|
+
result = await fn(tx);
|
|
124
192
|
}
|
|
125
193
|
catch (err) {
|
|
126
|
-
|
|
194
|
+
// The callback may have rolled back before throwing; rolling back twice
|
|
195
|
+
// targets a transaction the driver has already finished with.
|
|
196
|
+
if (!tx.isFinished) {
|
|
197
|
+
await transaction.rollback().catch(() => undefined);
|
|
198
|
+
}
|
|
127
199
|
throw err;
|
|
128
200
|
}
|
|
201
|
+
// A callback that rolled back deliberately must not then be committed.
|
|
202
|
+
if (tx.isFinished) {
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
await transaction.commit();
|
|
206
|
+
return result;
|
|
129
207
|
}
|
|
130
208
|
/**
|
|
131
209
|
* Close the database connection and release all resources.
|
|
@@ -153,39 +231,99 @@ class FirebirdTransaction {
|
|
|
153
231
|
constructor(attachment, transaction) {
|
|
154
232
|
this.attachment = attachment;
|
|
155
233
|
this.transaction = transaction;
|
|
234
|
+
this.finished = false;
|
|
235
|
+
}
|
|
236
|
+
/** Whether this transaction has already been rolled back. */
|
|
237
|
+
get isFinished() {
|
|
238
|
+
return this.finished;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Roll this transaction back and stop.
|
|
242
|
+
*
|
|
243
|
+
* The enclosing `transaction()` will not commit afterwards. Use this to
|
|
244
|
+
* abandon a transaction deliberately, rather than throwing an error you do
|
|
245
|
+
* not mean — throwing also rolls back, but it propagates to the caller.
|
|
246
|
+
*/
|
|
247
|
+
async rollback() {
|
|
248
|
+
if (this.finished)
|
|
249
|
+
return;
|
|
250
|
+
this.finished = true;
|
|
251
|
+
await this.transaction.rollback();
|
|
252
|
+
}
|
|
253
|
+
assertUsable() {
|
|
254
|
+
if (this.finished) {
|
|
255
|
+
throw new Error('Transaction has already been rolled back');
|
|
256
|
+
}
|
|
156
257
|
}
|
|
157
258
|
/**
|
|
158
259
|
* Execute a DDL or DML statement inside this transaction.
|
|
159
260
|
*/
|
|
160
261
|
async exec(sql, params = []) {
|
|
161
|
-
|
|
162
|
-
|
|
262
|
+
this.assertUsable();
|
|
263
|
+
const statement = (0, sql_tag_1.toStatement)(sql, params);
|
|
264
|
+
if (statement.params.length > 0) {
|
|
265
|
+
const stmt = await this.attachment.prepare(this.transaction, statement.sql);
|
|
163
266
|
try {
|
|
164
|
-
await stmt.execute(this.transaction, params);
|
|
267
|
+
await stmt.execute(this.transaction, statement.params);
|
|
165
268
|
}
|
|
166
269
|
finally {
|
|
167
270
|
await stmt.dispose().catch(() => undefined);
|
|
168
271
|
}
|
|
169
272
|
}
|
|
170
273
|
else {
|
|
171
|
-
await this.attachment.execute(this.transaction, sql);
|
|
274
|
+
await this.attachment.execute(this.transaction, statement.sql);
|
|
172
275
|
}
|
|
173
276
|
}
|
|
174
277
|
/**
|
|
175
|
-
* Execute
|
|
278
|
+
* Execute one statement once per row of parameters inside this
|
|
279
|
+
* transaction: prepared once, executed per row.
|
|
176
280
|
*/
|
|
177
|
-
async
|
|
281
|
+
async execBatch(sql, rows) {
|
|
282
|
+
this.assertUsable();
|
|
283
|
+
if (!Array.isArray(rows)) {
|
|
284
|
+
throw new TypeError('execBatch takes an array of parameter rows');
|
|
285
|
+
}
|
|
286
|
+
if (rows.length === 0)
|
|
287
|
+
return;
|
|
178
288
|
const stmt = await this.attachment.prepare(this.transaction, sql);
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
289
|
+
try {
|
|
290
|
+
for (const row of rows) {
|
|
291
|
+
await stmt.execute(this.transaction, row);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
await stmt.dispose().catch(() => undefined);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async query(sql, params = [], options = {}) {
|
|
299
|
+
this.assertUsable();
|
|
300
|
+
const statement = (0, sql_tag_1.toStatement)(sql, params);
|
|
301
|
+
const rowMode = options.rowMode ?? 'object';
|
|
302
|
+
const stmt = await this.attachment.prepare(this.transaction, statement.sql);
|
|
303
|
+
// Same leak as FirebirdLite.query had: a statement or result set that
|
|
304
|
+
// throws must still be released. More so here, because a transaction
|
|
305
|
+
// callback that catches its own errors goes on using the same attachment.
|
|
306
|
+
try {
|
|
307
|
+
const columnLabels = await stmt.columnLabels;
|
|
308
|
+
const fields = columnLabels.map((label) => ({
|
|
309
|
+
name: label.toUpperCase(),
|
|
310
|
+
}));
|
|
311
|
+
const resultSet = await stmt.executeQuery(this.transaction, statement.params);
|
|
312
|
+
let rawRows;
|
|
313
|
+
try {
|
|
314
|
+
rawRows = await resultSet.fetch();
|
|
315
|
+
}
|
|
316
|
+
finally {
|
|
317
|
+
await resultSet.close().catch(() => undefined);
|
|
318
|
+
}
|
|
319
|
+
const rows = (rowMode === 'array'
|
|
320
|
+
? rawRows
|
|
321
|
+
: rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]]))));
|
|
322
|
+
return { rows, fields };
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
await stmt.dispose().catch(() => undefined);
|
|
326
|
+
}
|
|
189
327
|
}
|
|
190
328
|
}
|
|
191
329
|
exports.FirebirdTransaction = FirebirdTransaction;
|