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/wire/database.d.ts
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import Events from 'events';
|
|
2
|
+
import { type Callback, type SimpleCallback } from '../callback';
|
|
3
|
+
import FbEventManager from './fbEventManager';
|
|
4
|
+
import type Connection from './connection';
|
|
5
|
+
import type Transaction from './transaction';
|
|
6
|
+
import type Statement from './statement';
|
|
7
|
+
import type { BatchCb, StatementCb, InternalQueryOptions } from './wire-types';
|
|
8
|
+
import type { BatchOptions, BatchResult, Isolation, QueryParams, QueryStreamOptions, TransactionCallback, TransactionOptions } from '../types';
|
|
9
|
+
/** Callback for startTransaction: the internal optional-args shape, or the
|
|
10
|
+
* public TransactionCallback (non-optional transaction) from types.ts. */
|
|
11
|
+
type TransactionCb = Callback<Transaction> | TransactionCallback;
|
|
12
|
+
/** startTransaction options: resolved options object, a bare isolation
|
|
13
|
+
* array, or omitted entirely (callback in the options position). */
|
|
14
|
+
type TransactionArg = TransactionOptions | Isolation | TransactionCb | undefined;
|
|
2
15
|
declare class Database extends Events.EventEmitter {
|
|
3
|
-
connection:
|
|
16
|
+
connection: Connection;
|
|
4
17
|
eventid: number;
|
|
5
|
-
constructor(connection:
|
|
18
|
+
constructor(connection: Connection);
|
|
6
19
|
escape(value: any): string;
|
|
7
|
-
detach(callback?:
|
|
8
|
-
transaction(options:
|
|
9
|
-
startTransaction(options:
|
|
10
|
-
newStatement(query: string, callback:
|
|
11
|
-
execute(query: string, params?:
|
|
20
|
+
detach(callback?: Callback, force?: boolean): this;
|
|
21
|
+
transaction(options: TransactionArg, callback?: TransactionCb): this;
|
|
22
|
+
startTransaction(options: TransactionArg, callback?: TransactionCb): this;
|
|
23
|
+
newStatement(query: string, callback: StatementCb): this;
|
|
24
|
+
execute(query: string, params?: QueryParams | Callback, callback?: any, options?: InternalQueryOptions): this;
|
|
12
25
|
/**
|
|
13
26
|
* Bulk-execute `query` once per row via the Firebird 4 batch API
|
|
14
27
|
* (protocol 16+) with all-or-nothing semantics: the batch runs in its
|
|
@@ -18,10 +31,20 @@ declare class Database extends Events.EventEmitter {
|
|
|
18
31
|
* err.batchCompletion. Use transaction.executeBatch for partial-success
|
|
19
32
|
* handling.
|
|
20
33
|
*/
|
|
21
|
-
executeBatch(query: string, rows:
|
|
22
|
-
sequentially(query: string, params?: any, on?: any, callback?: any, options?:
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
executeBatch(query: string, rows: QueryParams[], callback?: BatchCb, options?: BatchOptions): this;
|
|
35
|
+
sequentially(query: string, params?: any, on?: any, callback?: any, options?: InternalQueryOptions | boolean): this;
|
|
36
|
+
/**
|
|
37
|
+
* Run `query` and return an object-mode Readable emitting one row per
|
|
38
|
+
* chunk (what pg-query-stream / mysql2 .stream() return), with real
|
|
39
|
+
* backpressure: fetching pauses while the stream buffer is full. Runs
|
|
40
|
+
* in its own transaction, like db.query. Destroying the stream early
|
|
41
|
+
* (e.g. a pipeline() teardown) aborts the fetch and releases the
|
|
42
|
+
* statement. Rows go through the regular decode path, so typeCast,
|
|
43
|
+
* blobAsText and jsonAsObject all apply.
|
|
44
|
+
*/
|
|
45
|
+
queryStream(query: string, params?: QueryParams, options?: QueryStreamOptions): import("node:stream").Readable;
|
|
46
|
+
query(query: string, params?: QueryParams | Callback, callback?: any, options?: InternalQueryOptions): this;
|
|
47
|
+
drop(callback?: SimpleCallback): void;
|
|
25
48
|
/**
|
|
26
49
|
* Cancel the operation currently executing on this connection by sending
|
|
27
50
|
* an out-of-band op_cancel (Firebird 2.5+ / protocol 12+). The cancelled
|
|
@@ -29,8 +52,8 @@ declare class Database extends Events.EventEmitter {
|
|
|
29
52
|
* GDSCode.CANCELLED. `kind` defaults to fb_cancel_raise; cancellation is
|
|
30
53
|
* per-attachment, not per-statement.
|
|
31
54
|
*/
|
|
32
|
-
cancel(kind?: number |
|
|
33
|
-
attachEvent(callback:
|
|
55
|
+
cancel(kind?: number | SimpleCallback, callback?: SimpleCallback): this;
|
|
56
|
+
attachEvent(callback: Callback<FbEventManager>): this;
|
|
34
57
|
/**
|
|
35
58
|
* Create a physical tablespace.
|
|
36
59
|
* Supported in Firebird 6.0+ (Protocol 20+).
|
|
@@ -40,7 +63,7 @@ declare class Database extends Events.EventEmitter {
|
|
|
40
63
|
* @param {function} [callback] - Asynchronous completion callback.
|
|
41
64
|
* @returns {Database}
|
|
42
65
|
*/
|
|
43
|
-
createTablespace(name: string, filePath: string, callback?:
|
|
66
|
+
createTablespace(name: string, filePath: string, callback?: Callback): this;
|
|
44
67
|
/**
|
|
45
68
|
* Alter an existing tablespace physical location.
|
|
46
69
|
* Supported in Firebird 6.0+ (Protocol 20+).
|
|
@@ -50,7 +73,7 @@ declare class Database extends Events.EventEmitter {
|
|
|
50
73
|
* @param {function} [callback] - Asynchronous completion callback.
|
|
51
74
|
* @returns {Database}
|
|
52
75
|
*/
|
|
53
|
-
alterTablespace(name: string, filePath: string, callback?:
|
|
76
|
+
alterTablespace(name: string, filePath: string, callback?: Callback): this;
|
|
54
77
|
/**
|
|
55
78
|
* Drop a tablespace.
|
|
56
79
|
* Supported in Firebird 6.0+ (Protocol 20+).
|
|
@@ -59,7 +82,7 @@ declare class Database extends Events.EventEmitter {
|
|
|
59
82
|
* @param {function} [callback] - Asynchronous completion callback.
|
|
60
83
|
* @returns {Database}
|
|
61
84
|
*/
|
|
62
|
-
dropTablespace(name: string, callback?:
|
|
85
|
+
dropTablespace(name: string, callback?: Callback): this;
|
|
63
86
|
/**
|
|
64
87
|
* Create a schema/namespace. Can optionally partition/map the namespace
|
|
65
88
|
* to a physical tablespace.
|
|
@@ -70,23 +93,25 @@ declare class Database extends Events.EventEmitter {
|
|
|
70
93
|
* @param {function} [callback] - Asynchronous completion callback.
|
|
71
94
|
* @returns {Database}
|
|
72
95
|
*/
|
|
73
|
-
createSchema(schemaName: string, tablespaceName?: string |
|
|
74
|
-
queryAsync(query: string, params?:
|
|
75
|
-
executeAsync(query: string, params?:
|
|
76
|
-
executeBatchAsync(query: string, rows:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
createSchema(schemaName: string, tablespaceName?: string | Callback, callback?: Callback): this;
|
|
97
|
+
queryAsync(query: string, params?: QueryParams, options?: InternalQueryOptions): Promise<any[]>;
|
|
98
|
+
executeAsync(query: string, params?: QueryParams, options?: InternalQueryOptions): Promise<any[]>;
|
|
99
|
+
executeBatchAsync(query: string, rows: QueryParams[], options?: BatchOptions): Promise<BatchResult>;
|
|
100
|
+
/** `on` may hold the options when the params argument is the row callback
|
|
101
|
+
* (public overload: sequentiallyAsync(query, rowCallback, options)). */
|
|
102
|
+
sequentiallyAsync(query: string, params?: any, on?: any, options?: InternalQueryOptions | boolean): Promise<void>;
|
|
103
|
+
transactionAsync(options?: TransactionOptions | Isolation): Promise<Transaction>;
|
|
104
|
+
startTransactionAsync(options?: TransactionOptions | Isolation): Promise<Transaction>;
|
|
105
|
+
newStatementAsync(query: string): Promise<Statement>;
|
|
81
106
|
detachAsync(force?: boolean): Promise<void>;
|
|
82
107
|
dropAsync(): Promise<void>;
|
|
83
|
-
attachEventAsync(): Promise<
|
|
108
|
+
attachEventAsync(): Promise<FbEventManager>;
|
|
84
109
|
cancelAsync(kind?: number): Promise<void>;
|
|
85
110
|
/**
|
|
86
111
|
* Run `work` inside a transaction: commits when the returned promise
|
|
87
112
|
* resolves, rolls back when it rejects (the original error is rethrown,
|
|
88
113
|
* even if the rollback itself fails).
|
|
89
114
|
*/
|
|
90
|
-
withTransaction<T>(work: (transaction:
|
|
115
|
+
withTransaction<T>(work: (transaction: Transaction) => Promise<T> | T, options?: TransactionOptions | Isolation): Promise<T>;
|
|
91
116
|
}
|
|
92
117
|
export = Database;
|
package/lib/wire/database.js
CHANGED
|
@@ -8,6 +8,7 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const const_1 = __importDefault(require("./const"));
|
|
9
9
|
const eventConnection_1 = __importDefault(require("./eventConnection"));
|
|
10
10
|
const fbEventManager_1 = __importDefault(require("./fbEventManager"));
|
|
11
|
+
const query_stream_1 = __importDefault(require("./query-stream"));
|
|
11
12
|
/***************************************
|
|
12
13
|
*
|
|
13
14
|
* Database
|
|
@@ -128,7 +129,7 @@ class Database extends events_1.default.EventEmitter {
|
|
|
128
129
|
self.emit('detach', false);
|
|
129
130
|
if (callback)
|
|
130
131
|
callback(err, obj);
|
|
131
|
-
}
|
|
132
|
+
});
|
|
132
133
|
}
|
|
133
134
|
else {
|
|
134
135
|
self.emit('detach', false);
|
|
@@ -145,18 +146,21 @@ class Database extends events_1.default.EventEmitter {
|
|
|
145
146
|
return this;
|
|
146
147
|
}
|
|
147
148
|
newStatement(query, callback) {
|
|
149
|
+
// the public strict callback shape and the internal optional-args
|
|
150
|
+
// shape only differ in optionality; treat it as the internal one
|
|
151
|
+
const cb = callback;
|
|
148
152
|
this.startTransaction(function (err, transaction) {
|
|
149
|
-
if (err) {
|
|
150
|
-
|
|
153
|
+
if (err || !transaction) {
|
|
154
|
+
cb(err);
|
|
151
155
|
return;
|
|
152
156
|
}
|
|
153
157
|
transaction.newStatement(query, function (err, statement) {
|
|
154
158
|
if (err) {
|
|
155
|
-
|
|
159
|
+
cb(err);
|
|
156
160
|
return;
|
|
157
161
|
}
|
|
158
162
|
transaction.commit(function (err) {
|
|
159
|
-
|
|
163
|
+
cb(err, statement);
|
|
160
164
|
});
|
|
161
165
|
});
|
|
162
166
|
});
|
|
@@ -170,7 +174,7 @@ class Database extends events_1.default.EventEmitter {
|
|
|
170
174
|
}
|
|
171
175
|
var self = this;
|
|
172
176
|
self.connection.startTransaction(function (err, transaction) {
|
|
173
|
-
if (err) {
|
|
177
|
+
if (err || !transaction) {
|
|
174
178
|
(0, callback_1.doError)(err, callback);
|
|
175
179
|
return;
|
|
176
180
|
}
|
|
@@ -201,12 +205,12 @@ class Database extends events_1.default.EventEmitter {
|
|
|
201
205
|
executeBatch(query, rows, callback, options) {
|
|
202
206
|
var self = this;
|
|
203
207
|
self.connection.startTransaction(function (err, transaction) {
|
|
204
|
-
if (err) {
|
|
208
|
+
if (err || !transaction) {
|
|
205
209
|
(0, callback_1.doError)(err, callback);
|
|
206
210
|
return;
|
|
207
211
|
}
|
|
208
212
|
transaction.executeBatch(query, rows, function (err, result) {
|
|
209
|
-
if (err) {
|
|
213
|
+
if (err || !result) {
|
|
210
214
|
transaction.rollback(function () {
|
|
211
215
|
(0, callback_1.doError)(err, callback);
|
|
212
216
|
});
|
|
@@ -297,6 +301,18 @@ class Database extends events_1.default.EventEmitter {
|
|
|
297
301
|
self.execute(query, params, callback, options);
|
|
298
302
|
return self;
|
|
299
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Run `query` and return an object-mode Readable emitting one row per
|
|
306
|
+
* chunk (what pg-query-stream / mysql2 .stream() return), with real
|
|
307
|
+
* backpressure: fetching pauses while the stream buffer is full. Runs
|
|
308
|
+
* in its own transaction, like db.query. Destroying the stream early
|
|
309
|
+
* (e.g. a pipeline() teardown) aborts the fetch and releases the
|
|
310
|
+
* statement. Rows go through the regular decode path, so typeCast,
|
|
311
|
+
* blobAsText and jsonAsObject all apply.
|
|
312
|
+
*/
|
|
313
|
+
queryStream(query, params, options) {
|
|
314
|
+
return (0, query_stream_1.default)(this, query, params, options);
|
|
315
|
+
}
|
|
300
316
|
query(query, params, callback, options = {}) {
|
|
301
317
|
if (params instanceof Function) {
|
|
302
318
|
options = callback || {};
|
|
@@ -452,6 +468,8 @@ class Database extends events_1.default.EventEmitter {
|
|
|
452
468
|
var self = this;
|
|
453
469
|
return (0, callback_1.fromCallback)(function (cb) { self.executeBatch(query, rows, cb, options); });
|
|
454
470
|
}
|
|
471
|
+
/** `on` may hold the options when the params argument is the row callback
|
|
472
|
+
* (public overload: sequentiallyAsync(query, rowCallback, options)). */
|
|
455
473
|
sequentiallyAsync(query, params, on, options) {
|
|
456
474
|
if (params instanceof Function) {
|
|
457
475
|
options = on;
|
|
@@ -15,8 +15,8 @@ class EventConnection {
|
|
|
15
15
|
this._isOpened = false;
|
|
16
16
|
this._socket = net_1.default.createConnection(port, host);
|
|
17
17
|
this._bind_events(host, port, callback);
|
|
18
|
-
this.error;
|
|
19
|
-
this.eventcallback;
|
|
18
|
+
this.error = null;
|
|
19
|
+
this.eventcallback = null;
|
|
20
20
|
}
|
|
21
21
|
_bind_events(host, port, callback) {
|
|
22
22
|
var self = this;
|
|
@@ -45,8 +45,8 @@ class EventConnection {
|
|
|
45
45
|
data.copy(buf, xdr.buffer.length);
|
|
46
46
|
xdr.buffer = buf;
|
|
47
47
|
}
|
|
48
|
+
var op_pos = xdr.pos;
|
|
48
49
|
try {
|
|
49
|
-
var op_pos = xdr.pos;
|
|
50
50
|
var tmp_event;
|
|
51
51
|
while (xdr.pos < xdr.buffer.length) {
|
|
52
52
|
do {
|
|
@@ -55,6 +55,8 @@ class EventConnection {
|
|
|
55
55
|
switch (r) {
|
|
56
56
|
case const_1.default.op_event:
|
|
57
57
|
xdr.readInt(); // db handle
|
|
58
|
+
// op_event always carries a payload; readArray only
|
|
59
|
+
// returns undefined for zero-length arrays
|
|
58
60
|
buf = xdr.readArray();
|
|
59
61
|
// first byte is always set to 1
|
|
60
62
|
tmp_event = {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* queryStream — object-mode Readable over sequentially()
|
|
4
|
+
*
|
|
5
|
+
***************************************/
|
|
6
|
+
import { Readable } from 'stream';
|
|
7
|
+
/**
|
|
8
|
+
* Build an object-mode Readable that emits one row per chunk, implemented
|
|
9
|
+
* on top of `target.sequentially()`'s next()-based backpressure: fetching
|
|
10
|
+
* pauses whenever the stream's internal buffer is full and resumes when
|
|
11
|
+
* the consumer drains it. Shared by Database.queryStream and
|
|
12
|
+
* Transaction.queryStream.
|
|
13
|
+
*
|
|
14
|
+
* Destroying the stream early (including a pipeline() teardown) aborts the
|
|
15
|
+
* row loop, which releases the statement server-side.
|
|
16
|
+
*/
|
|
17
|
+
declare function makeQueryStream(target: any, query: string, params?: any, options?: any): Readable;
|
|
18
|
+
export = makeQueryStream;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/***************************************
|
|
3
|
+
*
|
|
4
|
+
* queryStream — object-mode Readable over sequentially()
|
|
5
|
+
*
|
|
6
|
+
***************************************/
|
|
7
|
+
const stream_1 = require("stream");
|
|
8
|
+
/**
|
|
9
|
+
* Build an object-mode Readable that emits one row per chunk, implemented
|
|
10
|
+
* on top of `target.sequentially()`'s next()-based backpressure: fetching
|
|
11
|
+
* pauses whenever the stream's internal buffer is full and resumes when
|
|
12
|
+
* the consumer drains it. Shared by Database.queryStream and
|
|
13
|
+
* Transaction.queryStream.
|
|
14
|
+
*
|
|
15
|
+
* Destroying the stream early (including a pipeline() teardown) aborts the
|
|
16
|
+
* row loop, which releases the statement server-side.
|
|
17
|
+
*/
|
|
18
|
+
function makeQueryStream(target, query, params, options) {
|
|
19
|
+
options = options || {};
|
|
20
|
+
const streamOptions = { objectMode: true };
|
|
21
|
+
if (options.highWaterMark !== undefined) {
|
|
22
|
+
streamOptions.highWaterMark = options.highWaterMark;
|
|
23
|
+
}
|
|
24
|
+
// forwarded to sequentially(); these keys would break its plumbing
|
|
25
|
+
const queryOptions = { ...options };
|
|
26
|
+
delete queryOptions.on;
|
|
27
|
+
delete queryOptions.asStream;
|
|
28
|
+
delete queryOptions.highWaterMark;
|
|
29
|
+
// sentinel used to stop the row loop on early destroy; recognized by
|
|
30
|
+
// identity in the completion callback and never surfaced to the user
|
|
31
|
+
const abortError = new Error('queryStream destroyed');
|
|
32
|
+
let pendingNext = null;
|
|
33
|
+
const resume = (err) => {
|
|
34
|
+
if (pendingNext) {
|
|
35
|
+
const next = pendingNext;
|
|
36
|
+
pendingNext = null;
|
|
37
|
+
next(err);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const stream = new stream_1.Readable({
|
|
41
|
+
...streamOptions,
|
|
42
|
+
read() {
|
|
43
|
+
resume();
|
|
44
|
+
},
|
|
45
|
+
destroy(err, cb) {
|
|
46
|
+
// if the row loop is paused waiting for us, abort it so the
|
|
47
|
+
// statement is released instead of leaking mid-fetch
|
|
48
|
+
resume(abortError);
|
|
49
|
+
cb(err);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
target.sequentially(query, params, function (row, _index, next) {
|
|
53
|
+
if (stream.destroyed) {
|
|
54
|
+
next(abortError);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (stream.push(row)) {
|
|
58
|
+
next();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
pendingNext = next;
|
|
62
|
+
}
|
|
63
|
+
}, function (err) {
|
|
64
|
+
if (err && err !== abortError) {
|
|
65
|
+
stream.destroy(err);
|
|
66
|
+
}
|
|
67
|
+
else if (!stream.destroyed) {
|
|
68
|
+
stream.push(null);
|
|
69
|
+
}
|
|
70
|
+
}, queryOptions);
|
|
71
|
+
return stream;
|
|
72
|
+
}
|
|
73
|
+
module.exports = makeQueryStream;
|
package/lib/wire/serialize.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare class BlrReader {
|
|
|
27
27
|
constructor(buffer: Buffer);
|
|
28
28
|
readByteCode(): number;
|
|
29
29
|
readInt32(): number;
|
|
30
|
-
readInt():
|
|
30
|
+
readInt(): number | undefined;
|
|
31
31
|
readString(encoding?: BufferEncoding): string;
|
|
32
32
|
readSegment(): Buffer;
|
|
33
33
|
}
|
|
@@ -69,6 +69,22 @@ export declare class XdrWriter {
|
|
|
69
69
|
export declare class XdrReader {
|
|
70
70
|
buffer: Buffer;
|
|
71
71
|
pos: number;
|
|
72
|
+
/** opcode carried over for a resumed decode (vestigial, see connection.ts) */
|
|
73
|
+
r?: number | null;
|
|
74
|
+
/** partial fetch-op flag (vestigial) */
|
|
75
|
+
fop?: boolean;
|
|
76
|
+
/** fetch status of the current row batch (100 = end of cursor) */
|
|
77
|
+
fstatus?: number;
|
|
78
|
+
/** rows remaining in the current packet */
|
|
79
|
+
fcount?: number;
|
|
80
|
+
/** column index the row decode stopped at */
|
|
81
|
+
fcolumn?: number;
|
|
82
|
+
/** row currently being decoded (object or array) */
|
|
83
|
+
frow?: any;
|
|
84
|
+
/** rows decoded so far in this call */
|
|
85
|
+
frows?: any[];
|
|
86
|
+
/** cached object-row keys (column aliases) */
|
|
87
|
+
fcols?: string[];
|
|
72
88
|
constructor(buffer: Buffer);
|
|
73
89
|
readInt(): number;
|
|
74
90
|
readUInt(): number;
|
|
@@ -83,7 +99,7 @@ export declare class XdrReader {
|
|
|
83
99
|
};
|
|
84
100
|
readFloat(): number;
|
|
85
101
|
readDouble(): number;
|
|
86
|
-
readArray(): Buffer<ArrayBuffer
|
|
102
|
+
readArray(): Buffer<ArrayBuffer> | undefined;
|
|
87
103
|
readBuffer(len?: number, toAlign?: boolean): Buffer | undefined;
|
|
88
104
|
readString(encoding: BufferEncoding): string;
|
|
89
105
|
readText(len: number, encoding: BufferEncoding): string;
|
package/lib/wire/serialize.js
CHANGED
|
@@ -408,6 +408,13 @@ class XdrReader {
|
|
|
408
408
|
var len = this.readInt();
|
|
409
409
|
if (!len)
|
|
410
410
|
return;
|
|
411
|
+
// Firebird 2.5 sign-extends XDR opaque lengths above 32767: a
|
|
412
|
+
// 32768-byte array arrives as length 0xFFFF8000. A negative length
|
|
413
|
+
// is never valid, so recover the real length from the low 16 bits
|
|
414
|
+
// instead of corrupting the read position (issue #312 — hang when
|
|
415
|
+
// preparing a statement with very many parameters on FB 2.5).
|
|
416
|
+
if (len < 0)
|
|
417
|
+
len &= 0xFFFF;
|
|
411
418
|
var r = this.buffer.slice(this.pos, this.pos + len);
|
|
412
419
|
this.pos += align(len);
|
|
413
420
|
return r;
|
package/lib/wire/service.d.ts
CHANGED
|
@@ -62,5 +62,47 @@ declare class ServiceManager extends Events.EventEmitter {
|
|
|
62
62
|
hasRunningAction(options: any, callback: any): void;
|
|
63
63
|
readusers(options: any, callback: any): void;
|
|
64
64
|
readlimbo(options: any, callback: any): void;
|
|
65
|
+
detachAsync(force?: boolean): Promise<void>;
|
|
66
|
+
backupAsync(options: any): Promise<stream.Readable>;
|
|
67
|
+
nbackupAsync(options: any): Promise<stream.Readable>;
|
|
68
|
+
restoreAsync(options: any): Promise<stream.Readable>;
|
|
69
|
+
nrestoreAsync(options: any): Promise<stream.Readable>;
|
|
70
|
+
setDialectAsync(db: string, dialect: number): Promise<any>;
|
|
71
|
+
setSweepintervalAsync(db: string, sweepinterval: number): Promise<any>;
|
|
72
|
+
setCachebufferAsync(db: string, nbpages: number): Promise<any>;
|
|
73
|
+
BringOnlineAsync(db: string): Promise<any>;
|
|
74
|
+
ShutdownAsync(db: string, kind: number, delay: number, mode?: any): Promise<any>;
|
|
75
|
+
setShadowAsync(db: string, val: boolean): Promise<any>;
|
|
76
|
+
setForcewriteAsync(db: string, val: boolean): Promise<any>;
|
|
77
|
+
setReservespaceAsync(db: string, val: boolean): Promise<any>;
|
|
78
|
+
setReadonlyModeAsync(db: string): Promise<any>;
|
|
79
|
+
setReadwriteModeAsync(db: string): Promise<any>;
|
|
80
|
+
validateAsync(options: any): Promise<stream.Readable>;
|
|
81
|
+
commitAsync(db: string, transactid: number): Promise<any>;
|
|
82
|
+
rollbackAsync(db: string, transactid: number): Promise<any>;
|
|
83
|
+
recoverAsync(db: string, transactid: number): Promise<any>;
|
|
84
|
+
getStatsAsync(options: any): Promise<stream.Readable>;
|
|
85
|
+
getLogAsync(options: any): Promise<stream.Readable>;
|
|
86
|
+
getUsersAsync(username?: string | null): Promise<any>;
|
|
87
|
+
addUserAsync(username: string, password: string, options?: any): Promise<any>;
|
|
88
|
+
editUserAsync(username: string, options: any): Promise<any>;
|
|
89
|
+
removeUserAsync(username: string, rolename?: string | null): Promise<any>;
|
|
90
|
+
getFbserverInfosAsync(infos?: any, options?: any): Promise<any>;
|
|
91
|
+
startTraceAsync(options: any): Promise<stream.Readable>;
|
|
92
|
+
suspendTraceAsync(options: any): Promise<stream.Readable>;
|
|
93
|
+
resumeTraceAsync(options: any): Promise<stream.Readable>;
|
|
94
|
+
stopTraceAsync(options: any): Promise<stream.Readable>;
|
|
95
|
+
getTraceListAsync(options?: any): Promise<stream.Readable>;
|
|
96
|
+
readlineAsync(options?: any): Promise<{
|
|
97
|
+
result: number;
|
|
98
|
+
line: string;
|
|
99
|
+
}>;
|
|
100
|
+
readeofAsync(options?: any): Promise<{
|
|
101
|
+
result: number;
|
|
102
|
+
line: string;
|
|
103
|
+
}>;
|
|
104
|
+
hasRunningActionAsync(options?: any): Promise<any>;
|
|
105
|
+
readusersAsync(options?: any): Promise<any>;
|
|
106
|
+
readlimboAsync(options?: any): Promise<any>;
|
|
65
107
|
}
|
|
66
108
|
export = ServiceManager;
|
package/lib/wire/service.js
CHANGED
|
@@ -1027,5 +1027,150 @@ class ServiceManager extends events_1.default.EventEmitter {
|
|
|
1027
1027
|
self._processquery(data.buffer, callback);
|
|
1028
1028
|
});
|
|
1029
1029
|
}
|
|
1030
|
+
/* Promise / async-await API — wrappers over the callback methods above. */
|
|
1031
|
+
detachAsync(force) {
|
|
1032
|
+
var self = this;
|
|
1033
|
+
return (0, callback_1.fromCallback)(function (cb) { self.detach(cb, force); });
|
|
1034
|
+
}
|
|
1035
|
+
backupAsync(options) {
|
|
1036
|
+
var self = this;
|
|
1037
|
+
return (0, callback_1.fromCallback)(function (cb) { self.backup(options, cb); });
|
|
1038
|
+
}
|
|
1039
|
+
nbackupAsync(options) {
|
|
1040
|
+
var self = this;
|
|
1041
|
+
return (0, callback_1.fromCallback)(function (cb) { self.nbackup(options, cb); });
|
|
1042
|
+
}
|
|
1043
|
+
restoreAsync(options) {
|
|
1044
|
+
var self = this;
|
|
1045
|
+
return (0, callback_1.fromCallback)(function (cb) { self.restore(options, cb); });
|
|
1046
|
+
}
|
|
1047
|
+
nrestoreAsync(options) {
|
|
1048
|
+
var self = this;
|
|
1049
|
+
return (0, callback_1.fromCallback)(function (cb) { self.nrestore(options, cb); });
|
|
1050
|
+
}
|
|
1051
|
+
setDialectAsync(db, dialect) {
|
|
1052
|
+
var self = this;
|
|
1053
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setDialect(db, dialect, cb); });
|
|
1054
|
+
}
|
|
1055
|
+
setSweepintervalAsync(db, sweepinterval) {
|
|
1056
|
+
var self = this;
|
|
1057
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setSweepinterval(db, sweepinterval, cb); });
|
|
1058
|
+
}
|
|
1059
|
+
setCachebufferAsync(db, nbpages) {
|
|
1060
|
+
var self = this;
|
|
1061
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setCachebuffer(db, nbpages, cb); });
|
|
1062
|
+
}
|
|
1063
|
+
BringOnlineAsync(db) {
|
|
1064
|
+
var self = this;
|
|
1065
|
+
return (0, callback_1.fromCallback)(function (cb) { self.BringOnline(db, cb); });
|
|
1066
|
+
}
|
|
1067
|
+
ShutdownAsync(db, kind, delay, mode) {
|
|
1068
|
+
var self = this;
|
|
1069
|
+
return (0, callback_1.fromCallback)(function (cb) { self.Shutdown(db, kind, delay, mode, cb); });
|
|
1070
|
+
}
|
|
1071
|
+
setShadowAsync(db, val) {
|
|
1072
|
+
var self = this;
|
|
1073
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setShadow(db, val, cb); });
|
|
1074
|
+
}
|
|
1075
|
+
setForcewriteAsync(db, val) {
|
|
1076
|
+
var self = this;
|
|
1077
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setForcewrite(db, val, cb); });
|
|
1078
|
+
}
|
|
1079
|
+
setReservespaceAsync(db, val) {
|
|
1080
|
+
var self = this;
|
|
1081
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setReservespace(db, val, cb); });
|
|
1082
|
+
}
|
|
1083
|
+
setReadonlyModeAsync(db) {
|
|
1084
|
+
var self = this;
|
|
1085
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setReadonlyMode(db, cb); });
|
|
1086
|
+
}
|
|
1087
|
+
setReadwriteModeAsync(db) {
|
|
1088
|
+
var self = this;
|
|
1089
|
+
return (0, callback_1.fromCallback)(function (cb) { self.setReadwriteMode(db, cb); });
|
|
1090
|
+
}
|
|
1091
|
+
validateAsync(options) {
|
|
1092
|
+
var self = this;
|
|
1093
|
+
return (0, callback_1.fromCallback)(function (cb) { self.validate(options, cb); });
|
|
1094
|
+
}
|
|
1095
|
+
commitAsync(db, transactid) {
|
|
1096
|
+
var self = this;
|
|
1097
|
+
return (0, callback_1.fromCallback)(function (cb) { self.commit(db, transactid, cb); });
|
|
1098
|
+
}
|
|
1099
|
+
rollbackAsync(db, transactid) {
|
|
1100
|
+
var self = this;
|
|
1101
|
+
return (0, callback_1.fromCallback)(function (cb) { self.rollback(db, transactid, cb); });
|
|
1102
|
+
}
|
|
1103
|
+
recoverAsync(db, transactid) {
|
|
1104
|
+
var self = this;
|
|
1105
|
+
return (0, callback_1.fromCallback)(function (cb) { self.recover(db, transactid, cb); });
|
|
1106
|
+
}
|
|
1107
|
+
getStatsAsync(options) {
|
|
1108
|
+
var self = this;
|
|
1109
|
+
return (0, callback_1.fromCallback)(function (cb) { self.getStats(options, cb); });
|
|
1110
|
+
}
|
|
1111
|
+
getLogAsync(options) {
|
|
1112
|
+
var self = this;
|
|
1113
|
+
return (0, callback_1.fromCallback)(function (cb) { self.getLog(options, cb); });
|
|
1114
|
+
}
|
|
1115
|
+
getUsersAsync(username) {
|
|
1116
|
+
var self = this;
|
|
1117
|
+
return (0, callback_1.fromCallback)(function (cb) { self.getUsers(username === undefined ? null : username, cb); });
|
|
1118
|
+
}
|
|
1119
|
+
addUserAsync(username, password, options) {
|
|
1120
|
+
var self = this;
|
|
1121
|
+
return (0, callback_1.fromCallback)(function (cb) { self.addUser(username, password, options, cb); });
|
|
1122
|
+
}
|
|
1123
|
+
editUserAsync(username, options) {
|
|
1124
|
+
var self = this;
|
|
1125
|
+
return (0, callback_1.fromCallback)(function (cb) { self.editUser(username, options, cb); });
|
|
1126
|
+
}
|
|
1127
|
+
removeUserAsync(username, rolename) {
|
|
1128
|
+
var self = this;
|
|
1129
|
+
return (0, callback_1.fromCallback)(function (cb) { self.removeUser(username, rolename === undefined ? null : rolename, cb); });
|
|
1130
|
+
}
|
|
1131
|
+
getFbserverInfosAsync(infos, options) {
|
|
1132
|
+
var self = this;
|
|
1133
|
+
return (0, callback_1.fromCallback)(function (cb) { self.getFbserverInfos(infos || {}, options || {}, cb); });
|
|
1134
|
+
}
|
|
1135
|
+
startTraceAsync(options) {
|
|
1136
|
+
var self = this;
|
|
1137
|
+
return (0, callback_1.fromCallback)(function (cb) { self.startTrace(options, cb); });
|
|
1138
|
+
}
|
|
1139
|
+
suspendTraceAsync(options) {
|
|
1140
|
+
var self = this;
|
|
1141
|
+
return (0, callback_1.fromCallback)(function (cb) { self.suspendTrace(options, cb); });
|
|
1142
|
+
}
|
|
1143
|
+
resumeTraceAsync(options) {
|
|
1144
|
+
var self = this;
|
|
1145
|
+
return (0, callback_1.fromCallback)(function (cb) { self.resumeTrace(options, cb); });
|
|
1146
|
+
}
|
|
1147
|
+
stopTraceAsync(options) {
|
|
1148
|
+
var self = this;
|
|
1149
|
+
return (0, callback_1.fromCallback)(function (cb) { self.stopTrace(options, cb); });
|
|
1150
|
+
}
|
|
1151
|
+
getTraceListAsync(options) {
|
|
1152
|
+
var self = this;
|
|
1153
|
+
return (0, callback_1.fromCallback)(function (cb) { self.getTraceList(options || {}, cb); });
|
|
1154
|
+
}
|
|
1155
|
+
readlineAsync(options) {
|
|
1156
|
+
var self = this;
|
|
1157
|
+
return (0, callback_1.fromCallback)(function (cb) { self.readline(options || {}, cb); });
|
|
1158
|
+
}
|
|
1159
|
+
readeofAsync(options) {
|
|
1160
|
+
var self = this;
|
|
1161
|
+
return (0, callback_1.fromCallback)(function (cb) { self.readeof(options || {}, cb); });
|
|
1162
|
+
}
|
|
1163
|
+
hasRunningActionAsync(options) {
|
|
1164
|
+
var self = this;
|
|
1165
|
+
return (0, callback_1.fromCallback)(function (cb) { self.hasRunningAction(options || {}, cb); });
|
|
1166
|
+
}
|
|
1167
|
+
readusersAsync(options) {
|
|
1168
|
+
var self = this;
|
|
1169
|
+
return (0, callback_1.fromCallback)(function (cb) { self.readusers(options || {}, cb); });
|
|
1170
|
+
}
|
|
1171
|
+
readlimboAsync(options) {
|
|
1172
|
+
var self = this;
|
|
1173
|
+
return (0, callback_1.fromCallback)(function (cb) { self.readlimbo(options || {}, cb); });
|
|
1174
|
+
}
|
|
1030
1175
|
}
|
|
1031
1176
|
module.exports = ServiceManager;
|
package/lib/wire/socket.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ declare class Arc4 {
|
|
|
20
20
|
*/
|
|
21
21
|
declare class Socket {
|
|
22
22
|
static Arc4: typeof Arc4;
|
|
23
|
+
end: net.Socket['end'];
|
|
24
|
+
removeAllListeners: net.Socket['removeAllListeners'];
|
|
23
25
|
_socket: net.Socket;
|
|
24
26
|
compress: boolean;
|
|
25
27
|
compressor: zlib.Deflate | null;
|
|
@@ -30,7 +32,7 @@ declare class Socket {
|
|
|
30
32
|
encrypt: boolean;
|
|
31
33
|
encryptCipher: any;
|
|
32
34
|
decryptCipher: any;
|
|
33
|
-
constructor(port: number, host: string);
|
|
35
|
+
constructor(port: number, host: string, enableKeepAlive?: boolean, keepAliveInitialDelay?: number);
|
|
34
36
|
/**
|
|
35
37
|
* Decompress and/or decrypt data when received.
|
|
36
38
|
* Override on data event.
|
package/lib/wire/socket.js
CHANGED
|
@@ -82,10 +82,13 @@ class ChaChaCipher {
|
|
|
82
82
|
*/
|
|
83
83
|
class Socket {
|
|
84
84
|
static { this.Arc4 = Arc4; }
|
|
85
|
-
constructor(port, host) {
|
|
85
|
+
constructor(port, host, enableKeepAlive = true, keepAliveInitialDelay = 60000) {
|
|
86
|
+
this.compress = false;
|
|
86
87
|
this._socket = net_1.default.createConnection(port, host);
|
|
87
88
|
this._socket.setNoDelay(true);
|
|
88
|
-
|
|
89
|
+
// TCP keepalive probing detects dead/stale connections; the delay is
|
|
90
|
+
// how long the socket must be idle before the first probe.
|
|
91
|
+
this._socket.setKeepAlive(enableKeepAlive, keepAliveInitialDelay);
|
|
89
92
|
this.compressor = null;
|
|
90
93
|
this.compressorBuffer = [];
|
|
91
94
|
this.decompressor = null;
|