node-firebird 2.8.1 → 2.10.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/README.md +268 -7
- package/lib/index.d.ts +17 -9
- package/lib/index.js +42 -3
- package/lib/named-params.d.ts +42 -0
- package/lib/named-params.js +133 -0
- package/lib/pool.js +1 -1
- package/lib/srp.d.ts +3 -3
- package/lib/types.d.ts +185 -25
- package/lib/uri.d.ts +57 -0
- package/lib/uri.js +193 -0
- package/lib/wire/connection.d.ts +92 -59
- package/lib/wire/connection.js +286 -55
- package/lib/wire/const.d.ts +9 -1
- package/lib/wire/const.js +21 -9
- package/lib/wire/database.d.ts +51 -26
- package/lib/wire/database.js +26 -8
- package/lib/wire/eventConnection.js +5 -3
- package/lib/wire/query-stream.d.ts +18 -0
- package/lib/wire/query-stream.js +73 -0
- package/lib/wire/serialize.d.ts +18 -2
- package/lib/wire/serialize.js +7 -0
- package/lib/wire/service.d.ts +42 -0
- package/lib/wire/service.js +145 -0
- package/lib/wire/socket.d.ts +3 -1
- package/lib/wire/socket.js +5 -2
- package/lib/wire/statement.d.ts +40 -20
- package/lib/wire/statement.js +26 -6
- package/lib/wire/transaction.d.ts +32 -18
- package/lib/wire/transaction.js +50 -8
- package/lib/wire/wire-types.d.ts +116 -0
- package/lib/wire/wire-types.js +10 -0
- package/lib/wire/xsqlvar.d.ts +18 -18
- package/package.json +1 -1
- package/src/index.ts +54 -15
- package/src/messages.ts +1 -1
- package/src/named-params.ts +145 -0
- package/src/pool.ts +1 -1
- package/src/srp.ts +6 -6
- package/src/types.ts +183 -25
- package/src/unix-crypt.ts +9 -9
- package/src/uri.ts +204 -0
- package/src/wire/connection.ts +481 -234
- package/src/wire/const.ts +21 -9
- package/src/wire/database.ts +75 -43
- package/src/wire/eventConnection.ts +8 -5
- package/src/wire/query-stream.ts +80 -0
- package/src/wire/serialize.ts +29 -0
- package/src/wire/service.ts +188 -6
- package/src/wire/socket.ts +17 -8
- package/src/wire/statement.ts +68 -31
- package/src/wire/transaction.ts +85 -33
- package/src/wire/wire-types.ts +127 -0
- package/src/wire/xsqlvar.ts +9 -7
package/lib/srp.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare function clientSeed(a?: bigint): KeyPair;
|
|
|
22
22
|
* @param b BigInt Server private key.
|
|
23
23
|
* @returns {{private: BigInt, public: BigInt}}
|
|
24
24
|
*/
|
|
25
|
-
export declare function serverSeed(user: string, password: string, salt: Buffer, b?: bigint | string, hashAlgo?: string): KeyPair;
|
|
25
|
+
export declare function serverSeed(user: string, password: string, salt: Buffer | string, b?: bigint | string, hashAlgo?: string): KeyPair;
|
|
26
26
|
/**
|
|
27
27
|
* Server session secret.
|
|
28
28
|
*
|
|
@@ -34,11 +34,11 @@ export declare function serverSeed(user: string, password: string, salt: Buffer,
|
|
|
34
34
|
* @param b BigInt Server private key.
|
|
35
35
|
* @returns {BigInt}
|
|
36
36
|
*/
|
|
37
|
-
export declare function serverSession(user: string, password: string, salt: Buffer, A: bigint, B: bigint, b: bigint, hashAlgo?: string): bigint;
|
|
37
|
+
export declare function serverSession(user: string, password: string, salt: Buffer | string, A: bigint, B: bigint, b: bigint, hashAlgo?: string): bigint;
|
|
38
38
|
/**
|
|
39
39
|
* M = H(H(N) xor H(g), H(I), s, A, B, K)
|
|
40
40
|
*/
|
|
41
|
-
export declare function clientProof(user: string, password: string, salt: Buffer, A: bigint, B: bigint, a: bigint, hashAlgo?: string): ClientProof;
|
|
41
|
+
export declare function clientProof(user: string, password: string, salt: Buffer | string, A: bigint, B: bigint, a: bigint, hashAlgo?: string): ClientProof;
|
|
42
42
|
/**
|
|
43
43
|
* Pad hex string.
|
|
44
44
|
*/
|
package/lib/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Readable } from 'stream';
|
|
1
2
|
export type DatabaseCallback = (err: any, db: Database) => void;
|
|
2
3
|
export type TransactionCallback = (err: any, transaction: Transaction) => void;
|
|
3
4
|
export type QueryCallback = (err: any, result: any[]) => void;
|
|
@@ -90,9 +91,21 @@ export type BatchOptions = {
|
|
|
90
91
|
/** Rows per op_batch_msg packet (default 500). */
|
|
91
92
|
chunkSize?: number;
|
|
92
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* Positional query parameters (array), or — when named placeholders are
|
|
96
|
+
* enabled via the `namedPlaceholders` connection/query option — values by
|
|
97
|
+
* placeholder name.
|
|
98
|
+
*/
|
|
99
|
+
export type QueryParams = any[] | Record<string, any>;
|
|
93
100
|
export type QueryOptions = {
|
|
94
101
|
timeout?: number;
|
|
95
102
|
scrollable?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Per-query override of the `namedPlaceholders` connection option
|
|
105
|
+
* (e.g. disable it for one EXECUTE BLOCK statement whose body uses
|
|
106
|
+
* `:variable` PSQL references).
|
|
107
|
+
*/
|
|
108
|
+
namedPlaceholders?: boolean;
|
|
96
109
|
/**
|
|
97
110
|
* Abort the query when the signal fires (Firebird 2.5+ / protocol 12+).
|
|
98
111
|
* If the signal is already aborted the query is not sent at all and the
|
|
@@ -103,15 +116,31 @@ export type QueryOptions = {
|
|
|
103
116
|
*/
|
|
104
117
|
signal?: AbortSignal;
|
|
105
118
|
};
|
|
119
|
+
export type QueryStreamOptions = QueryOptions & {
|
|
120
|
+
/**
|
|
121
|
+
* Rows buffered internally before fetching pauses (object-mode
|
|
122
|
+
* Readable highWaterMark, default 16).
|
|
123
|
+
*/
|
|
124
|
+
highWaterMark?: number;
|
|
125
|
+
/** Emit array rows instead of objects (like db.execute). */
|
|
126
|
+
asObject?: boolean;
|
|
127
|
+
};
|
|
106
128
|
export interface Database {
|
|
107
129
|
detach(callback?: SimpleCallback): Database;
|
|
108
130
|
transaction(options: TransactionOptions | Isolation | TransactionCallback, callback?: TransactionCallback): Database;
|
|
109
131
|
newStatement(query: string, callback: (err: Error | null, statement: Statement) => void): Database;
|
|
110
|
-
query(query: string, params:
|
|
111
|
-
execute(query: string, params:
|
|
132
|
+
query(query: string, params: QueryParams, callback: QueryCallback, options?: QueryOptions): Database;
|
|
133
|
+
execute(query: string, params: QueryParams, callback: QueryCallback, options?: QueryOptions): Database;
|
|
112
134
|
/** Bulk-execute in its own transaction, all-or-nothing (Firebird 4.0+). */
|
|
113
|
-
executeBatch(query: string, rows:
|
|
114
|
-
sequentially(query: string, params:
|
|
135
|
+
executeBatch(query: string, rows: QueryParams[], callback?: (err: any, result: BatchResult) => void, options?: BatchOptions): Database;
|
|
136
|
+
sequentially(query: string, params: QueryParams, rowCallback: SequentialCallback, callback: SimpleCallback, options?: QueryOptions | boolean): Database;
|
|
137
|
+
/**
|
|
138
|
+
* Run `query` and return an object-mode Readable emitting one row per
|
|
139
|
+
* chunk, with backpressure (fetching pauses while the buffer is full).
|
|
140
|
+
* Runs in its own transaction. Destroying the stream early aborts the
|
|
141
|
+
* fetch and releases the statement.
|
|
142
|
+
*/
|
|
143
|
+
queryStream(query: string, params?: QueryParams, options?: QueryStreamOptions): Readable;
|
|
115
144
|
drop(callback: SimpleCallback): void;
|
|
116
145
|
escape(value: any): string;
|
|
117
146
|
attachEvent(callback: any): this;
|
|
@@ -119,10 +148,10 @@ export interface Database {
|
|
|
119
148
|
alterTablespace(name: string, filePath: string, callback?: QueryCallback): Database;
|
|
120
149
|
dropTablespace(name: string, callback?: QueryCallback): Database;
|
|
121
150
|
createSchema(schemaName: string, tablespaceName?: string | QueryCallback, callback?: QueryCallback): Database;
|
|
122
|
-
queryAsync<T = any>(query: string, params?:
|
|
123
|
-
executeAsync<T = any>(query: string, params?:
|
|
124
|
-
executeBatchAsync(query: string, rows:
|
|
125
|
-
sequentiallyAsync(query: string, params:
|
|
151
|
+
queryAsync<T = any>(query: string, params?: QueryParams, options?: QueryOptions): Promise<T[]>;
|
|
152
|
+
executeAsync<T = any>(query: string, params?: QueryParams, options?: QueryOptions): Promise<T[]>;
|
|
153
|
+
executeBatchAsync(query: string, rows: QueryParams[], options?: BatchOptions): Promise<BatchResult>;
|
|
154
|
+
sequentiallyAsync(query: string, params: QueryParams | undefined, rowCallback: SequentialCallback, options?: QueryOptions | boolean): Promise<void>;
|
|
126
155
|
sequentiallyAsync(query: string, rowCallback: SequentialCallback, options?: QueryOptions | boolean): Promise<void>;
|
|
127
156
|
transactionAsync(options?: TransactionOptions | Isolation): Promise<Transaction>;
|
|
128
157
|
startTransactionAsync(options?: TransactionOptions | Isolation): Promise<Transaction>;
|
|
@@ -143,19 +172,25 @@ export interface Database {
|
|
|
143
172
|
}
|
|
144
173
|
export interface Transaction {
|
|
145
174
|
newStatement(query: string, callback: (err: Error | null, statement: Statement) => void): void;
|
|
146
|
-
query(query: string, params:
|
|
147
|
-
execute(query: string, params:
|
|
175
|
+
query(query: string, params: QueryParams, callback: QueryCallback, options?: QueryOptions): void;
|
|
176
|
+
execute(query: string, params: QueryParams, callback: QueryCallback, options?: QueryOptions): void;
|
|
148
177
|
/** Bulk-execute within this transaction; per-record failures do not roll back (Firebird 4.0+). */
|
|
149
|
-
executeBatch(query: string, rows:
|
|
150
|
-
sequentially(query: string, params:
|
|
178
|
+
executeBatch(query: string, rows: QueryParams[], callback?: (err: any, result: BatchResult) => void, options?: BatchOptions): void;
|
|
179
|
+
sequentially(query: string, params: QueryParams, rowCallback: SequentialCallback, callback: SimpleCallback, options?: QueryOptions | boolean): Database;
|
|
180
|
+
/**
|
|
181
|
+
* Run `query` inside this transaction and return an object-mode
|
|
182
|
+
* Readable emitting one row per chunk, with backpressure. The
|
|
183
|
+
* transaction is NOT committed when the stream ends.
|
|
184
|
+
*/
|
|
185
|
+
queryStream(query: string, params?: QueryParams, options?: QueryStreamOptions): Readable;
|
|
151
186
|
commit(callback?: SimpleCallback): void;
|
|
152
187
|
commitRetaining(callback?: SimpleCallback): void;
|
|
153
188
|
rollback(callback?: SimpleCallback): void;
|
|
154
189
|
rollbackRetaining(callback?: SimpleCallback): void;
|
|
155
|
-
queryAsync<T = any>(query: string, params?:
|
|
156
|
-
executeAsync<T = any>(query: string, params?:
|
|
157
|
-
executeBatchAsync(query: string, rows:
|
|
158
|
-
sequentiallyAsync(query: string, params:
|
|
190
|
+
queryAsync<T = any>(query: string, params?: QueryParams, options?: QueryOptions): Promise<T[]>;
|
|
191
|
+
executeAsync<T = any>(query: string, params?: QueryParams, options?: QueryOptions): Promise<T[]>;
|
|
192
|
+
executeBatchAsync(query: string, rows: QueryParams[], options?: BatchOptions): Promise<BatchResult>;
|
|
193
|
+
sequentiallyAsync(query: string, params: QueryParams | undefined, rowCallback: SequentialCallback, options?: QueryOptions | boolean): Promise<void>;
|
|
159
194
|
sequentiallyAsync(query: string, rowCallback: SequentialCallback, options?: QueryOptions | boolean): Promise<void>;
|
|
160
195
|
newStatementAsync(query: string): Promise<Statement>;
|
|
161
196
|
commitAsync(): Promise<void>;
|
|
@@ -167,14 +202,14 @@ export interface Statement {
|
|
|
167
202
|
close(callback?: SimpleCallback): void;
|
|
168
203
|
drop(callback?: SimpleCallback): void;
|
|
169
204
|
release(callback?: SimpleCallback): void;
|
|
170
|
-
execute(transaction: Transaction, params:
|
|
205
|
+
execute(transaction: Transaction, params: QueryParams, callback: QueryCallback, options?: QueryOptions): void;
|
|
171
206
|
fetch(transaction: Transaction, count: number, callback: QueryCallback): void;
|
|
172
207
|
fetchScroll(transaction: Transaction, direction: 'NEXT' | 'PRIOR' | 'FIRST' | 'LAST' | 'ABSOLUTE' | 'RELATIVE' | number, offset: number, count: number, callback: QueryCallback): void;
|
|
173
208
|
fetchAll(transaction: Transaction, callback: QueryCallback): void;
|
|
174
209
|
/** Execute this prepared statement once per row (Firebird 4.0+ batch API). */
|
|
175
|
-
executeBatch(transaction: Transaction, rows:
|
|
176
|
-
executeAsync(transaction: Transaction, params?:
|
|
177
|
-
executeBatchAsync(transaction: Transaction, rows:
|
|
210
|
+
executeBatch(transaction: Transaction, rows: QueryParams[], callback?: (err: any, result: BatchResult) => void, options?: BatchOptions): void;
|
|
211
|
+
executeAsync(transaction: Transaction, params?: QueryParams, options?: QueryOptions): Promise<any>;
|
|
212
|
+
executeBatchAsync(transaction: Transaction, rows: QueryParams[], options?: BatchOptions): Promise<BatchResult>;
|
|
178
213
|
fetchAsync(transaction: Transaction, count: number | 'all'): Promise<any>;
|
|
179
214
|
fetchScrollAsync(transaction: Transaction, direction: 'NEXT' | 'PRIOR' | 'FIRST' | 'LAST' | 'ABSOLUTE' | 'RELATIVE' | number, offset?: number, count?: number): Promise<any>;
|
|
180
215
|
fetchAllAsync(transaction: Transaction): Promise<any>;
|
|
@@ -209,6 +244,26 @@ export interface Options {
|
|
|
209
244
|
blobReadChunkSize?: number;
|
|
210
245
|
wireCrypt?: number;
|
|
211
246
|
wireCompression?: boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Enable named placeholders: SQL may use `:name` markers and params may
|
|
249
|
+
* be a values-by-name object (`db.query('... WHERE id = :id', { id: 1 })`).
|
|
250
|
+
* Placeholders are rewritten client-side to positional `?` before
|
|
251
|
+
* preparing; positional arrays keep working unchanged. Off by default
|
|
252
|
+
* because `EXECUTE BLOCK` bodies use `:variable` for PSQL references —
|
|
253
|
+
* with this option on, run such statements with positional params or a
|
|
254
|
+
* per-query `namedPlaceholders: false` override.
|
|
255
|
+
*/
|
|
256
|
+
namedPlaceholders?: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* TCP keepalive probing to detect dead/stale connections (same option
|
|
259
|
+
* names as mysql2). On by default; set false to disable.
|
|
260
|
+
*/
|
|
261
|
+
enableKeepAlive?: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Milliseconds a socket must be idle before the first TCP keepalive
|
|
264
|
+
* probe is sent (default 60000). Ignored when enableKeepAlive is false.
|
|
265
|
+
*/
|
|
266
|
+
keepAliveInitialDelay?: number;
|
|
212
267
|
pluginName?: string;
|
|
213
268
|
parallelWorkers?: number;
|
|
214
269
|
maxInlineBlobSize?: number;
|
|
@@ -240,11 +295,11 @@ export interface Options {
|
|
|
240
295
|
/**
|
|
241
296
|
* **Firebird 6.0+ only (Protocol 20+)**
|
|
242
297
|
*
|
|
243
|
-
* Sets the session's current schema at connection time.
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
298
|
+
* Sets the session's current schema at connection time. `CURRENT_SCHEMA`
|
|
299
|
+
* in Firebird is the first existing schema of the search path, so this
|
|
300
|
+
* option is implemented by putting the schema at the front of the
|
|
301
|
+
* `searchPath` sent to the server (with `PUBLIC` kept as a fallback when
|
|
302
|
+
* no explicit `searchPath` is given).
|
|
248
303
|
*
|
|
249
304
|
* Example: `defaultSchema: 'myapp'`
|
|
250
305
|
*/
|
|
@@ -266,6 +321,18 @@ export interface Options {
|
|
|
266
321
|
* (typically `PUBLIC` then `SYSTEM`).
|
|
267
322
|
*/
|
|
268
323
|
searchPath?: string | string[];
|
|
324
|
+
/**
|
|
325
|
+
* **Firebird 6.0+ only**
|
|
326
|
+
*
|
|
327
|
+
* Owner of a newly created database (`isc_dpb_owner`), allowing a
|
|
328
|
+
* superuser to create a database owned by another user
|
|
329
|
+
* ([firebird#7718](https://github.com/FirebirdSQL/firebird/issues/7718)).
|
|
330
|
+
* Only honored by `create`/`attachOrCreate` when the database is
|
|
331
|
+
* created; ignored on plain attach and by older servers.
|
|
332
|
+
*
|
|
333
|
+
* Example: `owner: 'APP_OWNER'`
|
|
334
|
+
*/
|
|
335
|
+
owner?: string;
|
|
269
336
|
/**
|
|
270
337
|
* **Firebird 6.0+ only (Protocol 20+)**
|
|
271
338
|
*
|
|
@@ -274,7 +341,55 @@ export interface Options {
|
|
|
274
341
|
* text/BLOB columns back into JavaScript objects/arrays.
|
|
275
342
|
*/
|
|
276
343
|
jsonAsObject?: boolean;
|
|
344
|
+
/**
|
|
345
|
+
* Custom type parser (mysql2-style). Called for every column value of
|
|
346
|
+
* every result row (including NULLs); whatever it returns becomes the
|
|
347
|
+
* value in the row. Call `next()` to get the value the driver would
|
|
348
|
+
* produce by default (after `blobAsText`/`jsonAsObject` are applied).
|
|
349
|
+
*
|
|
350
|
+
* ```js
|
|
351
|
+
* typeCast: (column, next) =>
|
|
352
|
+
* column.typeName === 'INT64' ? Number(next()) : next()
|
|
353
|
+
* ```
|
|
354
|
+
*
|
|
355
|
+
* Non-text BLOB columns reach the hook as the usual fetch function;
|
|
356
|
+
* text BLOBs with `blobAsText` reach it as the resolved string. The
|
|
357
|
+
* hook must be a pure function: a row can be decoded more than once
|
|
358
|
+
* when a response spans TCP packets.
|
|
359
|
+
*/
|
|
360
|
+
typeCast?: TypeCastFunction;
|
|
361
|
+
/**
|
|
362
|
+
* Per-connection LRU cache of prepared statements (like mysql2's
|
|
363
|
+
* statement cache). `db.query`/`tx.query` and friends transparently
|
|
364
|
+
* reuse the prepared handle for a repeated SQL string, skipping the
|
|
365
|
+
* prepare round-trip on hot paths. The number is the maximum of idle
|
|
366
|
+
* cached statements; least-recently-used ones are dropped over the
|
|
367
|
+
* limit. 0 / unset = disabled. Statements that failed and DDL are
|
|
368
|
+
* never cached; concurrent runs of the same SQL never share a
|
|
369
|
+
* statement (extra preparations are simply not cached).
|
|
370
|
+
*/
|
|
371
|
+
statementCacheSize?: number;
|
|
277
372
|
}
|
|
373
|
+
/** Column metadata passed to the {@link Options.typeCast} hook. */
|
|
374
|
+
export interface TypeCastColumn {
|
|
375
|
+
/** Firebird SQL type code (see the exported `SQL_TYPES` map). */
|
|
376
|
+
type: number;
|
|
377
|
+
/** Friendly name of the type code: 'VARYING', 'INT64', 'BLOB', ... */
|
|
378
|
+
typeName: string;
|
|
379
|
+
/** Column subtype (e.g. 1 = text for BLOBs; charset id for strings). */
|
|
380
|
+
subType?: number;
|
|
381
|
+
/** Negative decimal scale for NUMERIC/DECIMAL columns (e.g. -2). */
|
|
382
|
+
scale?: number;
|
|
383
|
+
/** Declared length in bytes. */
|
|
384
|
+
length?: number;
|
|
385
|
+
/** Column name in the table. */
|
|
386
|
+
field?: string;
|
|
387
|
+
/** Table (relation) name. */
|
|
388
|
+
relation?: string;
|
|
389
|
+
/** Alias used in the SELECT list (the row key for object rows). */
|
|
390
|
+
alias?: string;
|
|
391
|
+
}
|
|
392
|
+
export type TypeCastFunction = (column: TypeCastColumn, next: () => any) => any;
|
|
278
393
|
export interface SvcMgrOptions extends Options {
|
|
279
394
|
manager: true;
|
|
280
395
|
}
|
|
@@ -484,4 +599,49 @@ export interface ServiceManager {
|
|
|
484
599
|
hasRunningAction(options: ReadableOptions, callback: ReadableCallback): void;
|
|
485
600
|
readusers(options: ReadableOptions, callback: ReadableCallback): void;
|
|
486
601
|
readlimbo(options: ReadableOptions, callback: ReadableCallback): void;
|
|
602
|
+
detachAsync(force?: boolean): Promise<void>;
|
|
603
|
+
backupAsync(options: BackupOptions): Promise<NodeJS.ReadableStream>;
|
|
604
|
+
nbackupAsync(options: BackupOptions): Promise<NodeJS.ReadableStream>;
|
|
605
|
+
restoreAsync(options: RestoreOptions): Promise<NodeJS.ReadableStream>;
|
|
606
|
+
nrestoreAsync(options: NRestoreOptions): Promise<NodeJS.ReadableStream>;
|
|
607
|
+
setDialectAsync(db: string, dialect: 1 | 3): Promise<NodeJS.ReadableStream>;
|
|
608
|
+
setSweepintervalAsync(db: string, interval: number): Promise<any>;
|
|
609
|
+
setCachebufferAsync(db: string, nbpages: any): Promise<NodeJS.ReadableStream>;
|
|
610
|
+
BringOnlineAsync(db: string): Promise<NodeJS.ReadableStream>;
|
|
611
|
+
ShutdownAsync(db: string, kind: ShutdownKind, delay: number, mode?: ShutdownMode): Promise<NodeJS.ReadableStream>;
|
|
612
|
+
setShadowAsync(db: string, val: boolean): Promise<NodeJS.ReadableStream>;
|
|
613
|
+
setForcewriteAsync(db: string, val: boolean): Promise<NodeJS.ReadableStream>;
|
|
614
|
+
setReservespaceAsync(db: string, val: boolean): Promise<NodeJS.ReadableStream>;
|
|
615
|
+
setReadonlyModeAsync(db: string): Promise<NodeJS.ReadableStream>;
|
|
616
|
+
setReadwriteModeAsync(db: string): Promise<NodeJS.ReadableStream>;
|
|
617
|
+
validateAsync(options: ValidateOptions): Promise<NodeJS.ReadableStream>;
|
|
618
|
+
commitAsync(db: string, transactid: number): Promise<NodeJS.ReadableStream>;
|
|
619
|
+
rollbackAsync(db: string, transactid: number): Promise<NodeJS.ReadableStream>;
|
|
620
|
+
recoverAsync(db: string, transactid: number): Promise<NodeJS.ReadableStream>;
|
|
621
|
+
getStatsAsync(options: StatsOptions): Promise<NodeJS.ReadableStream>;
|
|
622
|
+
getLogAsync(options: ReadableOptions): Promise<NodeJS.ReadableStream>;
|
|
623
|
+
getUsersAsync(username?: string | null): Promise<ServerInfo>;
|
|
624
|
+
addUserAsync(username: string, password: string, info?: UserInfo): Promise<NodeJS.ReadableStream>;
|
|
625
|
+
editUserAsync(username: string, info: UserInfo): Promise<NodeJS.ReadableStream>;
|
|
626
|
+
removeUserAsync(username: string, rolename?: string | null): Promise<NodeJS.ReadableStream>;
|
|
627
|
+
getFbserverInfosAsync(infos?: ServerInfoReq, options?: {
|
|
628
|
+
buffersize?: number;
|
|
629
|
+
timeout?: number;
|
|
630
|
+
}): Promise<ServerInfo>;
|
|
631
|
+
startTraceAsync(options: TraceOptions): Promise<NodeJS.ReadableStream>;
|
|
632
|
+
suspendTraceAsync(options: TraceOptions): Promise<NodeJS.ReadableStream>;
|
|
633
|
+
resumeTraceAsync(options: TraceOptions): Promise<NodeJS.ReadableStream>;
|
|
634
|
+
stopTraceAsync(options: TraceOptions): Promise<NodeJS.ReadableStream>;
|
|
635
|
+
getTraceListAsync(options?: ReadableOptions): Promise<NodeJS.ReadableStream>;
|
|
636
|
+
readlineAsync(options?: ReadableOptions): Promise<{
|
|
637
|
+
result: number;
|
|
638
|
+
line: string;
|
|
639
|
+
}>;
|
|
640
|
+
readeofAsync(options?: ReadableOptions): Promise<{
|
|
641
|
+
result: number;
|
|
642
|
+
line: string;
|
|
643
|
+
}>;
|
|
644
|
+
hasRunningActionAsync(options?: ReadableOptions): Promise<any>;
|
|
645
|
+
readusersAsync(options?: ReadableOptions): Promise<any>;
|
|
646
|
+
readlimboAsync(options?: ReadableOptions): Promise<any>;
|
|
487
647
|
}
|
package/lib/uri.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* Connection URI strings
|
|
4
|
+
*
|
|
5
|
+
***************************************/
|
|
6
|
+
import type { Options } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Parse a firebird:// connection URI into an options object.
|
|
9
|
+
*
|
|
10
|
+
* firebird://user:password@host:port/database?option=value&...
|
|
11
|
+
*
|
|
12
|
+
* The database part:
|
|
13
|
+
* firebird://host/employee → alias "employee"
|
|
14
|
+
* firebird://host//var/db/prod.fdb → absolute path "/var/db/prod.fdb"
|
|
15
|
+
* firebird://host/var/db/prod.fdb → "/var/db/prod.fdb" (a database
|
|
16
|
+
* part with slashes is a path —
|
|
17
|
+
* aliases cannot contain "/")
|
|
18
|
+
* firebird://host/C:/db/prod.fdb → Windows path "C:/db/prod.fdb"
|
|
19
|
+
*
|
|
20
|
+
* Credentials and the database path are URL-decoded, so reserved characters
|
|
21
|
+
* can be percent-encoded (e.g. p%40ss for "p@ss"). Query parameters map
|
|
22
|
+
* 1:1 to option keys and are coerced to the option's type (booleans accept
|
|
23
|
+
* 1/true/yes/on). `user` and `password` may be given as query parameters
|
|
24
|
+
* instead of in the authority.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseConnectionUri(uri: string): Options;
|
|
27
|
+
/**
|
|
28
|
+
* Parse a traditional ("old style") Firebird connection string:
|
|
29
|
+
*
|
|
30
|
+
* [host[/port]:]{path | alias}
|
|
31
|
+
*
|
|
32
|
+
* employee → alias "employee" (default host)
|
|
33
|
+
* /var/fb/prod.fdb → local path (default host)
|
|
34
|
+
* C:\fbdata\prod.fdb → Windows path — a single character
|
|
35
|
+
* before ":" is a drive letter, not
|
|
36
|
+
* a host (same rule as Firebird)
|
|
37
|
+
* db.example.com:employee → host + alias
|
|
38
|
+
* db.example.com/3051:/var/fb/prod.fdb → host + port + path
|
|
39
|
+
* myserver:C:\fbdata\prod.fdb → host + Windows path
|
|
40
|
+
* [::1]/3050:employee → IPv6 host + port + alias
|
|
41
|
+
*
|
|
42
|
+
* Unlike firebird:// URIs, traditional strings carry no credentials or
|
|
43
|
+
* options — the driver defaults apply (SYSDBA/masterkey, port 3050).
|
|
44
|
+
* The port must be numeric; /etc/services names are not resolved.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseOldStyleConnectionString(str: string): Options;
|
|
47
|
+
/**
|
|
48
|
+
* Parse any connection string the driver accepts: a firebird:// URI, or a
|
|
49
|
+
* traditional [host[/port]:]database string when there is no scheme.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseConnectionString(str: string): Options;
|
|
52
|
+
/**
|
|
53
|
+
* Accept either an options object or a connection string (firebird:// URI
|
|
54
|
+
* or traditional host[/port]:database) everywhere options are taken.
|
|
55
|
+
* Strings are parsed; objects pass through unchanged.
|
|
56
|
+
*/
|
|
57
|
+
export declare function normalizeOptions<T>(options: T | string): T;
|
package/lib/uri.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/***************************************
|
|
3
|
+
*
|
|
4
|
+
* Connection URI strings
|
|
5
|
+
*
|
|
6
|
+
***************************************/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.parseConnectionUri = parseConnectionUri;
|
|
9
|
+
exports.parseOldStyleConnectionString = parseOldStyleConnectionString;
|
|
10
|
+
exports.parseConnectionString = parseConnectionString;
|
|
11
|
+
exports.normalizeOptions = normalizeOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Option keys coerced to boolean when they arrive as URI query parameters.
|
|
14
|
+
* "1"/"true"/"yes"/"on" (case-insensitive) → true, everything else → false.
|
|
15
|
+
*/
|
|
16
|
+
const BOOLEAN_KEYS = new Set([
|
|
17
|
+
'lowercase_keys', 'blobAsText', 'wireCompression', 'manager',
|
|
18
|
+
'namedPlaceholders', 'enableKeepAlive',
|
|
19
|
+
]);
|
|
20
|
+
/** Option keys coerced to number when they arrive as URI query parameters. */
|
|
21
|
+
const NUMBER_KEYS = new Set([
|
|
22
|
+
'port', 'pageSize', 'timeout', 'retryConnectionInterval',
|
|
23
|
+
'blobChunkSize', 'blobReadChunkSize', 'wireCrypt', 'parallelWorkers',
|
|
24
|
+
'maxInlineBlobSize', 'maxNegotiatedProtocols', 'connectTimeout',
|
|
25
|
+
'min', 'idleTimeoutMillis', 'keepAliveInitialDelay',
|
|
26
|
+
]);
|
|
27
|
+
function coerce(key, value) {
|
|
28
|
+
if (BOOLEAN_KEYS.has(key)) {
|
|
29
|
+
return /^(1|true|yes|on)$/i.test(value);
|
|
30
|
+
}
|
|
31
|
+
if (NUMBER_KEYS.has(key)) {
|
|
32
|
+
var n = Number(value);
|
|
33
|
+
if (Number.isNaN(n)) {
|
|
34
|
+
throw new Error('Invalid numeric value for connection URI option "' + key + '": ' + value);
|
|
35
|
+
}
|
|
36
|
+
return n;
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a firebird:// connection URI into an options object.
|
|
42
|
+
*
|
|
43
|
+
* firebird://user:password@host:port/database?option=value&...
|
|
44
|
+
*
|
|
45
|
+
* The database part:
|
|
46
|
+
* firebird://host/employee → alias "employee"
|
|
47
|
+
* firebird://host//var/db/prod.fdb → absolute path "/var/db/prod.fdb"
|
|
48
|
+
* firebird://host/var/db/prod.fdb → "/var/db/prod.fdb" (a database
|
|
49
|
+
* part with slashes is a path —
|
|
50
|
+
* aliases cannot contain "/")
|
|
51
|
+
* firebird://host/C:/db/prod.fdb → Windows path "C:/db/prod.fdb"
|
|
52
|
+
*
|
|
53
|
+
* Credentials and the database path are URL-decoded, so reserved characters
|
|
54
|
+
* can be percent-encoded (e.g. p%40ss for "p@ss"). Query parameters map
|
|
55
|
+
* 1:1 to option keys and are coerced to the option's type (booleans accept
|
|
56
|
+
* 1/true/yes/on). `user` and `password` may be given as query parameters
|
|
57
|
+
* instead of in the authority.
|
|
58
|
+
*/
|
|
59
|
+
function parseConnectionUri(uri) {
|
|
60
|
+
var url;
|
|
61
|
+
try {
|
|
62
|
+
url = new URL(uri);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
throw new Error('Invalid connection URI: ' + uri);
|
|
66
|
+
}
|
|
67
|
+
if (url.protocol !== 'firebird:') {
|
|
68
|
+
throw new Error('Unsupported connection URI scheme "' + url.protocol.replace(/:$/, '') +
|
|
69
|
+
'" (expected firebird://...)');
|
|
70
|
+
}
|
|
71
|
+
var options = {};
|
|
72
|
+
if (url.hostname) {
|
|
73
|
+
// URL keeps IPv6 hostnames bracketed ([::1]); net.connect wants them bare
|
|
74
|
+
options.host = url.hostname.replace(/^\[(.*)\]$/, '$1');
|
|
75
|
+
}
|
|
76
|
+
if (url.port) {
|
|
77
|
+
options.port = Number(url.port);
|
|
78
|
+
}
|
|
79
|
+
if (url.username) {
|
|
80
|
+
options.user = decodeURIComponent(url.username);
|
|
81
|
+
}
|
|
82
|
+
if (url.password) {
|
|
83
|
+
options.password = decodeURIComponent(url.password);
|
|
84
|
+
}
|
|
85
|
+
var database = decodeURIComponent(url.pathname || '');
|
|
86
|
+
if (database.startsWith('/')) {
|
|
87
|
+
database = database.slice(1);
|
|
88
|
+
}
|
|
89
|
+
// A database part with path separators is a filesystem path, not an
|
|
90
|
+
// alias (aliases cannot contain "/") — restore the leading slash unless
|
|
91
|
+
// it is a Windows drive path or already absolute (double-slash form).
|
|
92
|
+
if (database.includes('/') && !database.startsWith('/') && !/^[A-Za-z]:\//.test(database)) {
|
|
93
|
+
database = '/' + database;
|
|
94
|
+
}
|
|
95
|
+
if (database) {
|
|
96
|
+
options.database = database;
|
|
97
|
+
}
|
|
98
|
+
url.searchParams.forEach(function (value, key) {
|
|
99
|
+
options[key] = coerce(key, value);
|
|
100
|
+
});
|
|
101
|
+
return options;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Parse a traditional ("old style") Firebird connection string:
|
|
105
|
+
*
|
|
106
|
+
* [host[/port]:]{path | alias}
|
|
107
|
+
*
|
|
108
|
+
* employee → alias "employee" (default host)
|
|
109
|
+
* /var/fb/prod.fdb → local path (default host)
|
|
110
|
+
* C:\fbdata\prod.fdb → Windows path — a single character
|
|
111
|
+
* before ":" is a drive letter, not
|
|
112
|
+
* a host (same rule as Firebird)
|
|
113
|
+
* db.example.com:employee → host + alias
|
|
114
|
+
* db.example.com/3051:/var/fb/prod.fdb → host + port + path
|
|
115
|
+
* myserver:C:\fbdata\prod.fdb → host + Windows path
|
|
116
|
+
* [::1]/3050:employee → IPv6 host + port + alias
|
|
117
|
+
*
|
|
118
|
+
* Unlike firebird:// URIs, traditional strings carry no credentials or
|
|
119
|
+
* options — the driver defaults apply (SYSDBA/masterkey, port 3050).
|
|
120
|
+
* The port must be numeric; /etc/services names are not resolved.
|
|
121
|
+
*/
|
|
122
|
+
function parseOldStyleConnectionString(str) {
|
|
123
|
+
var options = {};
|
|
124
|
+
var host = null;
|
|
125
|
+
var port = null;
|
|
126
|
+
var database = str;
|
|
127
|
+
var ipv6 = /^\[([^\]]+)\](?:\/([^:]*))?:(.*)$/.exec(str);
|
|
128
|
+
if (ipv6) {
|
|
129
|
+
host = ipv6[1];
|
|
130
|
+
port = ipv6[2] !== undefined ? ipv6[2] : null;
|
|
131
|
+
database = ipv6[3];
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
var colon = str.indexOf(':');
|
|
135
|
+
if (colon === 0) {
|
|
136
|
+
throw new Error('Invalid connection string (empty host): ' + str);
|
|
137
|
+
}
|
|
138
|
+
// colon === 1 → single character before ":" is a drive letter;
|
|
139
|
+
// colon === -1 → no host part. Both leave the whole string as database.
|
|
140
|
+
if (colon > 1) {
|
|
141
|
+
var hostPart = str.slice(0, colon);
|
|
142
|
+
database = str.slice(colon + 1);
|
|
143
|
+
var slash = hostPart.indexOf('/');
|
|
144
|
+
if (slash !== -1) {
|
|
145
|
+
host = hostPart.slice(0, slash);
|
|
146
|
+
port = hostPart.slice(slash + 1);
|
|
147
|
+
if (!host) {
|
|
148
|
+
throw new Error('Invalid connection string (empty host): ' + str);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
host = hostPart;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!database) {
|
|
157
|
+
throw new Error('Invalid connection string (empty database): ' + str);
|
|
158
|
+
}
|
|
159
|
+
if (host) {
|
|
160
|
+
options.host = host;
|
|
161
|
+
}
|
|
162
|
+
if (port !== null) {
|
|
163
|
+
var n = Number(port);
|
|
164
|
+
if (!/^\d+$/.test(port) || n < 1 || n > 65535) {
|
|
165
|
+
throw new Error('Invalid port in connection string "' + str +
|
|
166
|
+
'" (service names are not supported — use a numeric port)');
|
|
167
|
+
}
|
|
168
|
+
options.port = n;
|
|
169
|
+
}
|
|
170
|
+
options.database = database;
|
|
171
|
+
return options;
|
|
172
|
+
}
|
|
173
|
+
const URI_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*:\/\//;
|
|
174
|
+
/**
|
|
175
|
+
* Parse any connection string the driver accepts: a firebird:// URI, or a
|
|
176
|
+
* traditional [host[/port]:]database string when there is no scheme.
|
|
177
|
+
*/
|
|
178
|
+
function parseConnectionString(str) {
|
|
179
|
+
return URI_SCHEME.test(str)
|
|
180
|
+
? parseConnectionUri(str)
|
|
181
|
+
: parseOldStyleConnectionString(str);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Accept either an options object or a connection string (firebird:// URI
|
|
185
|
+
* or traditional host[/port]:database) everywhere options are taken.
|
|
186
|
+
* Strings are parsed; objects pass through unchanged.
|
|
187
|
+
*/
|
|
188
|
+
function normalizeOptions(options) {
|
|
189
|
+
if (typeof options === 'string') {
|
|
190
|
+
return parseConnectionString(options);
|
|
191
|
+
}
|
|
192
|
+
return options;
|
|
193
|
+
}
|