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/src/wire/transaction.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { doCallback, doError, fromCallback } from '../callback';
|
|
1
|
+
import { doCallback, doError, fromCallback, type Callback, type SimpleCallback } from '../callback';
|
|
2
|
+
import { parseNamedPlaceholders } from '../named-params';
|
|
2
3
|
import { noop } from '../utils';
|
|
3
4
|
import Const from './const';
|
|
5
|
+
import makeQueryStream from './query-stream';
|
|
6
|
+
import type Connection from './connection';
|
|
7
|
+
import type Database from './database';
|
|
8
|
+
import type Statement from './statement';
|
|
9
|
+
import type { BatchCb, StatementCb, InternalQueryOptions } from './wire-types';
|
|
10
|
+
import type { BatchOptions, BatchResult, QueryOptions, QueryParams, QueryStreamOptions, SequentialCallback } from '../types';
|
|
4
11
|
|
|
5
12
|
/***************************************
|
|
6
13
|
*
|
|
@@ -25,7 +32,7 @@ function abortError(signal: any): Error {
|
|
|
25
32
|
* GDSCode.CANCELLED). Returns the wrapped callback that detaches the
|
|
26
33
|
* listener once the operation settles.
|
|
27
34
|
*/
|
|
28
|
-
function hookAbortSignal(connection:
|
|
35
|
+
function hookAbortSignal(connection: Connection, signal: AbortSignal, callback: any): any {
|
|
29
36
|
var settled = false;
|
|
30
37
|
var onAbort = function() {
|
|
31
38
|
if (!settled)
|
|
@@ -41,29 +48,58 @@ function hookAbortSignal(connection: any, signal: any, callback: any): any {
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
class Transaction {
|
|
44
|
-
connection:
|
|
45
|
-
db:
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
connection: Connection;
|
|
52
|
+
db: Database;
|
|
53
|
+
// populated externally from the op_transaction response
|
|
54
|
+
handle!: number;
|
|
48
55
|
|
|
49
|
-
constructor(connection:
|
|
56
|
+
constructor(connection: Connection) {
|
|
50
57
|
this.connection = connection;
|
|
51
58
|
this.db = connection.db;
|
|
52
59
|
}
|
|
53
60
|
|
|
54
|
-
|
|
61
|
+
/** Per-call options.namedPlaceholders overrides the connection option. */
|
|
62
|
+
private namedPlaceholdersEnabled(options?: InternalQueryOptions): boolean {
|
|
63
|
+
if (options && options.namedPlaceholders !== undefined)
|
|
64
|
+
return !!options.namedPlaceholders;
|
|
65
|
+
return !!(this.connection.options && this.connection.options.namedPlaceholders);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
newStatement(query: string, callback: StatementCb, options?: InternalQueryOptions): void {
|
|
55
69
|
var cnx = this.connection;
|
|
56
70
|
var self = this;
|
|
57
|
-
|
|
71
|
+
// the public strict callback shape and the internal optional-args
|
|
72
|
+
// shape only differ in optionality; treat it as the internal one
|
|
73
|
+
var cb = callback as Callback<Statement>;
|
|
74
|
+
|
|
75
|
+
// With namedPlaceholders on, prepare the positional rewrite and
|
|
76
|
+
// remember the name order on the statement so statement.execute can
|
|
77
|
+
// accept a values-by-name object. The rewritten SQL is the cache key.
|
|
78
|
+
var names: string[] | null = null;
|
|
79
|
+
if (this.namedPlaceholdersEnabled(options)) {
|
|
80
|
+
var parsed = parseNamedPlaceholders(query);
|
|
81
|
+
if (parsed.names) {
|
|
82
|
+
query = parsed.sql;
|
|
83
|
+
names = parsed.names;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var deliver = function(err: any, statement?: Statement) {
|
|
88
|
+
if (statement)
|
|
89
|
+
statement.namedParams = names;
|
|
90
|
+
cb(err, statement);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
var query_cache = cnx.takeCachedStatement(query);
|
|
58
94
|
|
|
59
95
|
if (query_cache) {
|
|
60
|
-
|
|
96
|
+
deliver(null, query_cache);
|
|
61
97
|
} else {
|
|
62
|
-
cnx.prepare(self, query, false,
|
|
98
|
+
cnx.prepare(self, query, false, deliver);
|
|
63
99
|
}
|
|
64
100
|
}
|
|
65
101
|
|
|
66
|
-
execute(query: string, params?:
|
|
102
|
+
execute(query: string, params?: QueryParams | Callback, callback?: any, options?: InternalQueryOptions): void {
|
|
67
103
|
if (params instanceof Function) {
|
|
68
104
|
options = callback;
|
|
69
105
|
callback = params;
|
|
@@ -80,15 +116,19 @@ class Transaction {
|
|
|
80
116
|
}
|
|
81
117
|
|
|
82
118
|
var self = this;
|
|
83
|
-
this.newStatement(query, function(err: any, statement
|
|
119
|
+
this.newStatement(query, function(err: any, statement?: Statement) {
|
|
84
120
|
|
|
85
|
-
if (err) {
|
|
121
|
+
if (err || !statement) {
|
|
86
122
|
doError(err, callback);
|
|
87
123
|
return;
|
|
88
124
|
}
|
|
89
125
|
|
|
90
126
|
function dropError(err: any) {
|
|
91
|
-
statement
|
|
127
|
+
// do not put a statement that just failed back into the cache
|
|
128
|
+
// (statement is guaranteed by the guard above; hoisting keeps
|
|
129
|
+
// the narrowing from reaching this function declaration)
|
|
130
|
+
statement!._failed = true;
|
|
131
|
+
statement!.release();
|
|
92
132
|
doCallback(err, callback);
|
|
93
133
|
}
|
|
94
134
|
|
|
@@ -148,10 +188,10 @@ class Transaction {
|
|
|
148
188
|
}
|
|
149
189
|
|
|
150
190
|
}, options);
|
|
151
|
-
});
|
|
191
|
+
}, options);
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
sequentially(query: string, params?: any, on?: any, callback?: any, options:
|
|
194
|
+
sequentially(query: string, params?: any, on?: any, callback?: any, options: InternalQueryOptions | boolean = {}): this {
|
|
155
195
|
if (params instanceof Function) {
|
|
156
196
|
options = callback;
|
|
157
197
|
callback = on;
|
|
@@ -169,7 +209,7 @@ class Transaction {
|
|
|
169
209
|
}
|
|
170
210
|
|
|
171
211
|
var self = this;
|
|
172
|
-
var _on = function(row: any, i: number, meta: any, next: (err?: any) => void) {
|
|
212
|
+
var _on = function(row: any, i: number, meta: any[], next: (err?: any) => void) {
|
|
173
213
|
var done = false;
|
|
174
214
|
var finish = function(err?: any) {
|
|
175
215
|
if (done) {
|
|
@@ -215,7 +255,17 @@ class Transaction {
|
|
|
215
255
|
return self;
|
|
216
256
|
}
|
|
217
257
|
|
|
218
|
-
|
|
258
|
+
/**
|
|
259
|
+
* Run `query` inside this transaction and return an object-mode
|
|
260
|
+
* Readable emitting one row per chunk, with real backpressure (see
|
|
261
|
+
* Database.queryStream). The transaction is NOT committed when the
|
|
262
|
+
* stream ends — commit or roll back yourself.
|
|
263
|
+
*/
|
|
264
|
+
queryStream(query: string, params?: QueryParams, options?: QueryStreamOptions) {
|
|
265
|
+
return makeQueryStream(this, query, params, options);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
query(query: string, params?: QueryParams | Callback, callback?: any, options: InternalQueryOptions = {}): void {
|
|
219
269
|
if (params instanceof Function) {
|
|
220
270
|
callback = params;
|
|
221
271
|
params = undefined;
|
|
@@ -242,56 +292,58 @@ class Transaction {
|
|
|
242
292
|
* commit or roll back yourself (or use db.executeBatch for
|
|
243
293
|
* all-or-nothing semantics).
|
|
244
294
|
*/
|
|
245
|
-
executeBatch(query: string, rows:
|
|
295
|
+
executeBatch(query: string, rows: QueryParams[], callback?: BatchCb, options?: BatchOptions & QueryOptions): void {
|
|
246
296
|
var self = this;
|
|
247
|
-
this.newStatement(query, function(err: any, statement
|
|
248
|
-
if (err) {
|
|
297
|
+
this.newStatement(query, function(err: any, statement?: Statement) {
|
|
298
|
+
if (err || !statement) {
|
|
249
299
|
doError(err, callback);
|
|
250
300
|
return;
|
|
251
301
|
}
|
|
252
302
|
|
|
253
|
-
statement.executeBatch(self, rows, function(err: any, result:
|
|
303
|
+
statement.executeBatch(self, rows, function(err: any, result: BatchResult) {
|
|
304
|
+
if (err)
|
|
305
|
+
statement._failed = true;
|
|
254
306
|
statement.release();
|
|
255
307
|
if (callback)
|
|
256
308
|
callback(err, result);
|
|
257
309
|
}, options);
|
|
258
|
-
});
|
|
310
|
+
}, options);
|
|
259
311
|
}
|
|
260
312
|
|
|
261
|
-
executeBatchAsync(query: string, rows:
|
|
313
|
+
executeBatchAsync(query: string, rows: QueryParams[], options?: BatchOptions & QueryOptions): Promise<BatchResult> {
|
|
262
314
|
var self = this;
|
|
263
315
|
return fromCallback(function(cb) { self.executeBatch(query, rows, cb, options); });
|
|
264
316
|
}
|
|
265
317
|
|
|
266
|
-
commit(callback?:
|
|
318
|
+
commit(callback?: SimpleCallback): void {
|
|
267
319
|
this.connection.commit(this, callback);
|
|
268
320
|
}
|
|
269
321
|
|
|
270
|
-
rollback(callback?:
|
|
322
|
+
rollback(callback?: SimpleCallback): void {
|
|
271
323
|
this.connection.rollback(this, callback);
|
|
272
324
|
}
|
|
273
325
|
|
|
274
|
-
commitRetaining(callback?:
|
|
326
|
+
commitRetaining(callback?: SimpleCallback): void {
|
|
275
327
|
this.connection.commitRetaining(this, callback);
|
|
276
328
|
}
|
|
277
329
|
|
|
278
|
-
rollbackRetaining(callback?:
|
|
330
|
+
rollbackRetaining(callback?: SimpleCallback): void {
|
|
279
331
|
this.connection.rollbackRetaining(this, callback);
|
|
280
332
|
}
|
|
281
333
|
|
|
282
334
|
/* Promise / async-await API — wrappers over the callback methods above. */
|
|
283
335
|
|
|
284
|
-
queryAsync(query: string, params?:
|
|
336
|
+
queryAsync(query: string, params?: QueryParams, options?: InternalQueryOptions): Promise<any[]> {
|
|
285
337
|
var self = this;
|
|
286
338
|
return fromCallback(function(cb) { self.query(query, params, cb, options); });
|
|
287
339
|
}
|
|
288
340
|
|
|
289
|
-
executeAsync(query: string, params?:
|
|
341
|
+
executeAsync(query: string, params?: QueryParams, options?: InternalQueryOptions): Promise<any[]> {
|
|
290
342
|
var self = this;
|
|
291
343
|
return fromCallback(function(cb) { self.execute(query, params, cb, options); });
|
|
292
344
|
}
|
|
293
345
|
|
|
294
|
-
sequentiallyAsync(query: string, params?: any, on?:
|
|
346
|
+
sequentiallyAsync(query: string, params?: any, on?: SequentialCallback, options?: InternalQueryOptions | boolean): Promise<void> {
|
|
295
347
|
if (params instanceof Function) {
|
|
296
348
|
options = on;
|
|
297
349
|
on = params;
|
|
@@ -301,7 +353,7 @@ class Transaction {
|
|
|
301
353
|
return fromCallback(function(cb) { self.sequentially(query, params, on, cb, options); });
|
|
302
354
|
}
|
|
303
355
|
|
|
304
|
-
newStatementAsync(query: string): Promise<
|
|
356
|
+
newStatementAsync(query: string): Promise<Statement> {
|
|
305
357
|
var self = this;
|
|
306
358
|
return fromCallback(function(cb) { self.newStatement(query, cb); });
|
|
307
359
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* Internal wire-protocol types (type-only module)
|
|
4
|
+
*
|
|
5
|
+
* Shared vocabulary for the wire core (connection/statement/transaction/
|
|
6
|
+
* database). Nothing here exists at runtime.
|
|
7
|
+
*
|
|
8
|
+
***************************************/
|
|
9
|
+
|
|
10
|
+
import type { Callback, FbStatusItem } from '../callback';
|
|
11
|
+
import type Statement from './statement';
|
|
12
|
+
import type { BatchResult, Options, QueryOptions, Statement as PublicStatement } from '../types';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* One entry of the connection's response queue (`connection._queue`).
|
|
16
|
+
* The function itself is the user/driver callback; the extra properties
|
|
17
|
+
* steer decodeResponse:
|
|
18
|
+
*
|
|
19
|
+
* - `response` — pre-allocated object the op_response decode fills in
|
|
20
|
+
* (a Statement, Transaction, or plain response object).
|
|
21
|
+
* - `statement` — statement whose `output` describes the rows of an
|
|
22
|
+
* op_fetch_response / op_sql_response.
|
|
23
|
+
* - `lazy_count`— number of chained lazy op_responses this entry consumes
|
|
24
|
+
* (ptype_lazy_send batches e.g. allocate+prepare).
|
|
25
|
+
*
|
|
26
|
+
* Deferred ops (op_free_statement, op_close_blob, ...) push `undefined`
|
|
27
|
+
* placeholders so every server response still pairs with one entry.
|
|
28
|
+
*/
|
|
29
|
+
export interface QueueCallback {
|
|
30
|
+
(err?: any, obj?: any): void;
|
|
31
|
+
response?: any;
|
|
32
|
+
statement?: Statement;
|
|
33
|
+
lazy_count?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A queue entry: a callback, or a placeholder for a deferred op. */
|
|
37
|
+
export type QueueEntry = QueueCallback | undefined;
|
|
38
|
+
|
|
39
|
+
/** XDR quad — 64-bit value as two 32-bit halves (blob ids, object ids). */
|
|
40
|
+
export interface Quad {
|
|
41
|
+
high: number;
|
|
42
|
+
low: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Decoded op_response packet (see parseOpResponse): object handle, object
|
|
47
|
+
* id, optional info buffer and, on failure, the status vector. Statement /
|
|
48
|
+
* Transaction responses are these fields merged onto the pre-allocated
|
|
49
|
+
* object from QueueCallback.response.
|
|
50
|
+
*/
|
|
51
|
+
export interface WireResponse {
|
|
52
|
+
handle?: number;
|
|
53
|
+
oid?: Quad;
|
|
54
|
+
buffer?: Buffer;
|
|
55
|
+
status?: FbStatusItem[];
|
|
56
|
+
/** isc_arg_warning entries — attached to a SUCCESSFUL response */
|
|
57
|
+
warnings?: FbStatusItem[];
|
|
58
|
+
sqlcode?: number;
|
|
59
|
+
message?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Result of decoding op_fetch_response / op_sql_response row data. */
|
|
63
|
+
export interface FetchResult {
|
|
64
|
+
data: any[];
|
|
65
|
+
/** true when the cursor is exhausted (fetch status 100 / singleton). */
|
|
66
|
+
fetched: boolean;
|
|
67
|
+
/** pending blobAsText fetches to resolve before delivering rows. */
|
|
68
|
+
arrBlob?: any[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Protocol negotiation result decoded from op_accept / op_cond_accept /
|
|
73
|
+
* op_accept_data, plus the auth/crypt state accumulated during the
|
|
74
|
+
* handshake (op_cont_auth rounds, wire-crypt keys).
|
|
75
|
+
*/
|
|
76
|
+
export interface AcceptPacket {
|
|
77
|
+
protocolVersion: number;
|
|
78
|
+
protocolArchitecture: number;
|
|
79
|
+
protocolMinimumType: number;
|
|
80
|
+
compress: boolean;
|
|
81
|
+
pluginName: string;
|
|
82
|
+
authData: any;
|
|
83
|
+
sessionKey?: any;
|
|
84
|
+
[key: string]: any;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Query options as the wire core sees them: the public QueryOptions plus
|
|
89
|
+
* the internal row-delivery flags set by the Database/Transaction helpers
|
|
90
|
+
* (query / sequentially / queryStream).
|
|
91
|
+
*/
|
|
92
|
+
export type InternalQueryOptions = QueryOptions & {
|
|
93
|
+
/** deliver rows as objects keyed by column alias */
|
|
94
|
+
asObject?: boolean;
|
|
95
|
+
/** deliver rows one by one (row events / `on` delegate) instead of accumulating */
|
|
96
|
+
asStream?: boolean;
|
|
97
|
+
/** per-row delegate installed by sequentially() */
|
|
98
|
+
on?: (row: any, index: number, meta: any[], next: (err?: any) => void) => void;
|
|
99
|
+
[key: string]: any;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* newStatement callback: the internal optional-args shape, or the public
|
|
104
|
+
* strict shape (non-optional statement) declared in types.ts.
|
|
105
|
+
*/
|
|
106
|
+
export type StatementCb = Callback<Statement> | ((err: Error | null, statement: PublicStatement) => void);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* executeBatch callback: the internal optional-args shape, or the public
|
|
110
|
+
* strict shape (non-optional result) declared in types.ts.
|
|
111
|
+
*/
|
|
112
|
+
export type BatchCb = Callback<BatchResult> | ((err: any, result: BatchResult) => void);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Connection options as the wire core sees them: the public Options plus
|
|
116
|
+
* internal flags set by the driver itself.
|
|
117
|
+
*/
|
|
118
|
+
export type InternalOptions = Options & {
|
|
119
|
+
/** set by the pool so detach() returns the connection instead */
|
|
120
|
+
isPool?: boolean;
|
|
121
|
+
/** override path of the firebird.msg error-message file */
|
|
122
|
+
messageFile?: string;
|
|
123
|
+
/** legacy statement-cache flags (mapped onto statementCacheSize) */
|
|
124
|
+
cacheQuery?: boolean;
|
|
125
|
+
maxCachedQuery?: number;
|
|
126
|
+
[key: string]: any;
|
|
127
|
+
};
|
package/src/wire/xsqlvar.ts
CHANGED
|
@@ -26,7 +26,7 @@ const
|
|
|
26
26
|
* Commonly used Firebird charsets not listed here fall back to the
|
|
27
27
|
* connection-level DEFAULT_ENCODING (typically 'utf8').
|
|
28
28
|
*/
|
|
29
|
-
const FirebirdToNodeEncoding = Object.freeze({
|
|
29
|
+
const FirebirdToNodeEncoding: Readonly<Record<string, string>> = Object.freeze({
|
|
30
30
|
UTF8: 'utf8',
|
|
31
31
|
UNICODE_FSS: 'utf8',
|
|
32
32
|
WIN1252: 'latin1',
|
|
@@ -36,7 +36,7 @@ const FirebirdToNodeEncoding = Object.freeze({
|
|
|
36
36
|
NONE: 'latin1', // unspecified charset – treat as binary-safe latin1
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
const FirebirdCharsetWidths = {
|
|
39
|
+
const FirebirdCharsetWidths: Record<string, number> = {
|
|
40
40
|
'UTF8': 4,
|
|
41
41
|
'UNICODE_FSS': 3,
|
|
42
42
|
'SJIS': 2,
|
|
@@ -71,11 +71,13 @@ function resolveTextEncoding(options?: any): BufferEncoding {
|
|
|
71
71
|
* describe response before decode()/calcBlr() are called.
|
|
72
72
|
*/
|
|
73
73
|
export abstract class SQLVarBase {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
// populated externally (see the doc comment above), hence the definite
|
|
75
|
+
// assignment assertions
|
|
76
|
+
type!: number;
|
|
77
|
+
subType!: number;
|
|
78
|
+
scale!: number;
|
|
79
|
+
length!: number;
|
|
80
|
+
nullable!: boolean;
|
|
79
81
|
field?: string;
|
|
80
82
|
relation?: string;
|
|
81
83
|
relationSchema?: string;
|