node-firebird 2.9.0 → 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.
Files changed (49) hide show
  1. package/README.md +166 -6
  2. package/lib/index.d.ts +5 -0
  3. package/lib/index.js +32 -1
  4. package/lib/pool.js +1 -1
  5. package/lib/srp.d.ts +3 -3
  6. package/lib/types.d.ts +143 -5
  7. package/lib/uri.js +2 -2
  8. package/lib/wire/connection.d.ts +92 -59
  9. package/lib/wire/connection.js +267 -53
  10. package/lib/wire/const.d.ts +9 -1
  11. package/lib/wire/const.js +21 -9
  12. package/lib/wire/database.d.ts +51 -26
  13. package/lib/wire/database.js +26 -8
  14. package/lib/wire/eventConnection.js +5 -3
  15. package/lib/wire/query-stream.d.ts +18 -0
  16. package/lib/wire/query-stream.js +73 -0
  17. package/lib/wire/serialize.d.ts +18 -2
  18. package/lib/wire/serialize.js +7 -0
  19. package/lib/wire/service.d.ts +42 -0
  20. package/lib/wire/service.js +145 -0
  21. package/lib/wire/socket.d.ts +3 -1
  22. package/lib/wire/socket.js +5 -2
  23. package/lib/wire/statement.d.ts +31 -19
  24. package/lib/wire/statement.js +1 -5
  25. package/lib/wire/transaction.d.ts +30 -18
  26. package/lib/wire/transaction.js +23 -4
  27. package/lib/wire/wire-types.d.ts +116 -0
  28. package/lib/wire/wire-types.js +10 -0
  29. package/lib/wire/xsqlvar.d.ts +18 -18
  30. package/package.json +1 -1
  31. package/src/index.ts +36 -4
  32. package/src/messages.ts +1 -1
  33. package/src/pool.ts +1 -1
  34. package/src/srp.ts +6 -6
  35. package/src/types.ts +140 -5
  36. package/src/unix-crypt.ts +9 -9
  37. package/src/uri.ts +2 -2
  38. package/src/wire/connection.ts +464 -232
  39. package/src/wire/const.ts +21 -9
  40. package/src/wire/database.ts +75 -43
  41. package/src/wire/eventConnection.ts +8 -5
  42. package/src/wire/query-stream.ts +80 -0
  43. package/src/wire/serialize.ts +29 -0
  44. package/src/wire/service.ts +188 -6
  45. package/src/wire/socket.ts +17 -8
  46. package/src/wire/statement.ts +37 -29
  47. package/src/wire/transaction.ts +57 -32
  48. package/src/wire/wire-types.ts +127 -0
  49. package/src/wire/xsqlvar.ts +9 -7
@@ -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: any;
16
+ connection: Connection;
4
17
  eventid: number;
5
- constructor(connection: any);
18
+ constructor(connection: Connection);
6
19
  escape(value: any): string;
7
- detach(callback?: (err?: any, obj?: any) => void, force?: boolean): this;
8
- transaction(options: any, callback?: (err: any, transaction?: any) => void): this;
9
- startTransaction(options: any, callback?: (err: any, transaction?: any) => void): this;
10
- newStatement(query: string, callback: (err: any, statement?: any) => void): this;
11
- execute(query: string, params?: any, callback?: any, options?: any): this;
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: any[][], callback?: any, options?: any): this;
22
- sequentially(query: string, params?: any, on?: any, callback?: any, options?: any): this;
23
- query(query: string, params?: any, callback?: any, options?: any): this;
24
- drop(callback?: (err?: any) => void): void;
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 | ((err?: any) => void), callback?: (err?: any) => void): this;
33
- attachEvent(callback: (err: any, evt?: any) => void): this;
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?: any): this;
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?: any): this;
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?: any): this;
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 | ((err?: any) => void), callback?: any): this;
74
- queryAsync(query: string, params?: any, options?: any): Promise<any[]>;
75
- executeAsync(query: string, params?: any, options?: any): Promise<any[]>;
76
- executeBatchAsync(query: string, rows: any[][], options?: any): Promise<any>;
77
- sequentiallyAsync(query: string, params?: any, on?: any, options?: any): Promise<void>;
78
- transactionAsync(options?: any): Promise<any>;
79
- startTransactionAsync(options?: any): Promise<any>;
80
- newStatementAsync(query: string): Promise<any>;
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<any>;
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: any) => Promise<T> | T, options?: any): Promise<T>;
115
+ withTransaction<T>(work: (transaction: Transaction) => Promise<T> | T, options?: TransactionOptions | Isolation): Promise<T>;
91
116
  }
92
117
  export = Database;
@@ -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
- }, force);
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
- callback(err);
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
- callback(err);
159
+ cb(err);
156
160
  return;
157
161
  }
158
162
  transaction.commit(function (err) {
159
- callback(err, statement);
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;
@@ -27,7 +27,7 @@ export declare class BlrReader {
27
27
  constructor(buffer: Buffer);
28
28
  readByteCode(): number;
29
29
  readInt32(): number;
30
- readInt(): any;
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;
@@ -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;
@@ -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;
@@ -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;
@@ -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.
@@ -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
- this._socket.setKeepAlive(true, 60000); // 1 minute delay to detect dead/stale connections
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;