node-firebird 2.3.4 → 2.4.1
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 +574 -20
- package/lib/callback.d.ts +20 -0
- package/lib/callback.js +6 -16
- package/lib/firebird.msg.json +1370 -1370
- package/lib/gdscodes.d.ts +1519 -1520
- package/lib/gdscodes.js +5 -5
- package/lib/ieee754-decimal.d.ts +38 -0
- package/lib/ieee754-decimal.js +71 -118
- package/lib/index.d.ts +37 -338
- package/lib/index.js +97 -86
- package/lib/messages.d.ts +6 -0
- package/lib/messages.js +135 -162
- package/lib/pool.d.ts +23 -0
- package/lib/pool.js +34 -47
- package/lib/srp.d.ts +51 -0
- package/lib/srp.js +62 -72
- package/lib/types.d.ts +375 -0
- package/lib/types.js +22 -0
- package/lib/unix-crypt.d.ts +1 -0
- package/lib/unix-crypt.js +126 -152
- package/lib/utils.d.ts +16 -0
- package/lib/utils.js +24 -48
- package/lib/wire/connection.d.ts +100 -0
- package/lib/wire/connection.js +1029 -1009
- package/lib/wire/const.d.ts +567 -0
- package/lib/wire/const.js +620 -599
- package/lib/wire/database.d.ts +57 -0
- package/lib/wire/database.js +111 -108
- package/lib/wire/eventConnection.d.ts +16 -0
- package/lib/wire/eventConnection.js +29 -31
- package/lib/wire/fbEventManager.d.ts +45 -0
- package/lib/wire/fbEventManager.js +38 -57
- package/lib/wire/serialize.d.ts +97 -0
- package/lib/wire/serialize.js +42 -141
- package/lib/wire/service.d.ts +66 -0
- package/lib/wire/service.js +374 -401
- package/lib/wire/socket.d.ts +59 -0
- package/lib/wire/socket.js +79 -40
- package/lib/wire/statement.d.ts +25 -0
- package/lib/wire/statement.js +13 -9
- package/lib/wire/transaction.d.ts +21 -0
- package/lib/wire/transaction.js +33 -61
- package/lib/wire/xsqlvar.d.ts +175 -0
- package/lib/wire/xsqlvar.js +169 -269
- package/package.json +12 -4
- package/src/callback.ts +55 -0
- package/{poc/node_modules/node-firebird/lib/gdscodes.js → src/gdscodes.ts} +3 -3
- package/{poc/node_modules/node-firebird/lib/ieee754-decimal.js → src/ieee754-decimal.ts} +7 -14
- package/src/index.ts +157 -0
- package/{poc/node_modules/node-firebird/lib/messages.js → src/messages.ts} +163 -162
- package/src/pool.ts +209 -0
- package/{poc/node_modules/node-firebird/lib/srp.js → src/srp.ts} +74 -33
- package/src/types.ts +419 -0
- package/{poc/node_modules/node-firebird/lib/unix-crypt.js → src/unix-crypt.ts} +6 -12
- package/{poc/node_modules/node-firebird/lib/utils.js → src/utils.ts} +11 -20
- package/{poc/node_modules/node-firebird/lib/wire/connection.js → src/wire/connection.ts} +611 -129
- package/{poc/node_modules/node-firebird/lib/wire/const.js → src/wire/const.ts} +96 -9
- package/{poc/node_modules/node-firebird/lib/wire/database.js → src/wire/database.ts} +110 -44
- package/{poc/node_modules/node-firebird/lib/wire/eventConnection.js → src/wire/eventConnection.ts} +29 -14
- package/{poc/node_modules/node-firebird/lib/wire/fbEventManager.js → src/wire/fbEventManager.ts} +39 -30
- package/{poc/node_modules/node-firebird/lib/wire/serialize.js → src/wire/serialize.ts} +78 -59
- package/{poc/node_modules/node-firebird/lib/wire/service.js → src/wire/service.ts} +90 -88
- package/src/wire/socket.ts +262 -0
- package/src/wire/statement.ts +71 -0
- package/{poc/node_modules/node-firebird/lib/wire/transaction.js → src/wire/transaction.ts} +25 -19
- package/{poc/node_modules/node-firebird/lib/wire/xsqlvar.js → src/wire/xsqlvar.ts} +244 -143
- package/.eslintrc.json +0 -12
- package/.github/workflows/codeql.yml +0 -76
- package/.github/workflows/node.js.yml +0 -95
- package/BIGINT_MIGRATION.md +0 -374
- package/CI_DEBUGGING_GUIDE.md +0 -148
- package/ENCRYPTION_CALLBACK.md +0 -152
- package/FIREBIRD_LOG_FEATURE.md +0 -145
- package/MINIMAL_CHANGES_SUMMARY.md +0 -136
- package/PR_SUMMARY.md +0 -96
- package/ROADMAP.md +0 -223
- package/SRP_PROTOCOL.md +0 -482
- package/poc/README.md +0 -160
- package/poc/helpers.js +0 -59
- package/poc/node_modules/.package-lock.json +0 -14
- package/poc/node_modules/node-firebird/.eslintrc.json +0 -12
- package/poc/node_modules/node-firebird/.github/workflows/codeql.yml +0 -76
- package/poc/node_modules/node-firebird/.github/workflows/node.js.yml +0 -95
- package/poc/node_modules/node-firebird/BIGINT_MIGRATION.md +0 -374
- package/poc/node_modules/node-firebird/CI_DEBUGGING_GUIDE.md +0 -148
- package/poc/node_modules/node-firebird/ENCRYPTION_CALLBACK.md +0 -152
- package/poc/node_modules/node-firebird/FIREBIRD_LOG_FEATURE.md +0 -145
- package/poc/node_modules/node-firebird/LICENSE +0 -373
- package/poc/node_modules/node-firebird/MINIMAL_CHANGES_SUMMARY.md +0 -136
- package/poc/node_modules/node-firebird/PR_SUMMARY.md +0 -96
- package/poc/node_modules/node-firebird/README.md +0 -794
- package/poc/node_modules/node-firebird/ROADMAP.md +0 -223
- package/poc/node_modules/node-firebird/SRP_PROTOCOL.md +0 -482
- package/poc/node_modules/node-firebird/lib/callback.js +0 -38
- package/poc/node_modules/node-firebird/lib/gdscodes.d.ts +0 -1524
- package/poc/node_modules/node-firebird/lib/index.d.ts +0 -316
- package/poc/node_modules/node-firebird/lib/index.js +0 -128
- package/poc/node_modules/node-firebird/lib/pool.js +0 -108
- package/poc/node_modules/node-firebird/lib/wire/socket.js +0 -175
- package/poc/node_modules/node-firebird/lib/wire/statement.js +0 -48
- package/poc/node_modules/node-firebird/package.json +0 -38
- package/poc/node_modules/node-firebird/vitest.config.js +0 -24
- package/poc/package-lock.json +0 -21
- package/poc/package.json +0 -12
- package/poc/reproduce-fixed.js +0 -150
- package/poc/reproduce.js +0 -133
- package/vitest.config.js +0 -27
- /package/{poc/node_modules/node-firebird/lib → src}/firebird.msg +0 -0
- /package/{poc/node_modules/node-firebird/lib → src}/firebird.msg.json +0 -0
package/lib/messages.js
CHANGED
|
@@ -1,162 +1,135 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return (code &
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return (code &
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
function readIndex(stackSize, position) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
ret.
|
|
42
|
-
ret
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
levels = buffer.readUInt16LE(12);
|
|
137
|
-
buffer = Buffer.alloc(bucket_size);
|
|
138
|
-
|
|
139
|
-
var i = 0;
|
|
140
|
-
var text;
|
|
141
|
-
|
|
142
|
-
function loop() {
|
|
143
|
-
lookup(status[i], function(line) {
|
|
144
|
-
if (text)
|
|
145
|
-
text = text + ', ' + line
|
|
146
|
-
else
|
|
147
|
-
text = line;
|
|
148
|
-
|
|
149
|
-
if (i === status.length - 1) {
|
|
150
|
-
fs.closeSync(handle);
|
|
151
|
-
callback(text);
|
|
152
|
-
} else {
|
|
153
|
-
i++;
|
|
154
|
-
loop();
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
loop(0);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.lookupMessages = exports.getClass = exports.getFacility = exports.getCode = exports.msgNumber = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const
|
|
9
|
+
//ISC_MASK = 0x14000000, // Defines the code as a valid ISC code
|
|
10
|
+
FAC_MASK = 0x00FF0000, // Specifies the facility where the code is located
|
|
11
|
+
CODE_MASK = 0x0000FFFF, // Specifies the code in the message file
|
|
12
|
+
CLASS_MASK = 0xF0000000; // Defines the code as warning, error, info, or other
|
|
13
|
+
const msgNumber = function (facility, code) {
|
|
14
|
+
return (facility * 10000 + code);
|
|
15
|
+
};
|
|
16
|
+
exports.msgNumber = msgNumber;
|
|
17
|
+
const getCode = function (code) {
|
|
18
|
+
return (code & CODE_MASK);
|
|
19
|
+
};
|
|
20
|
+
exports.getCode = getCode;
|
|
21
|
+
const getFacility = function (code) {
|
|
22
|
+
return (code & FAC_MASK) >> 16;
|
|
23
|
+
};
|
|
24
|
+
exports.getFacility = getFacility;
|
|
25
|
+
const getClass = function (code) {
|
|
26
|
+
return (code & CLASS_MASK) >> 28;
|
|
27
|
+
};
|
|
28
|
+
exports.getClass = getClass;
|
|
29
|
+
const lookupMessages = function (status, messageFile, callback) {
|
|
30
|
+
var handle;
|
|
31
|
+
var bucket_size;
|
|
32
|
+
var top_tree;
|
|
33
|
+
var levels;
|
|
34
|
+
var buffer;
|
|
35
|
+
function lookup(item, callback) {
|
|
36
|
+
var code = (0, exports.msgNumber)((0, exports.getFacility)(item.gdscode), (0, exports.getCode)(item.gdscode));
|
|
37
|
+
function readIndex(stackSize, position) {
|
|
38
|
+
function readNode(from) {
|
|
39
|
+
var ret = {};
|
|
40
|
+
ret.code = buffer.readUInt32LE(from);
|
|
41
|
+
ret.seek = buffer.readUInt32LE(from + 4);
|
|
42
|
+
return ret;
|
|
43
|
+
}
|
|
44
|
+
fs_1.default.read(handle, buffer, 0, bucket_size, position, function (err, bufferSize) {
|
|
45
|
+
if (bufferSize <= 0) {
|
|
46
|
+
callback();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (stackSize === levels) {
|
|
50
|
+
search();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var from = 0;
|
|
54
|
+
var node = readNode(from);
|
|
55
|
+
while (true) {
|
|
56
|
+
if (node.code >= code) {
|
|
57
|
+
readIndex(stackSize + 1, node.seek);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
from += 8;
|
|
61
|
+
if (from >= bufferSize) {
|
|
62
|
+
callback();
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
node = readNode(from);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function search() {
|
|
70
|
+
function readRec(from) {
|
|
71
|
+
function align(v) {
|
|
72
|
+
return (v + 3) & ~3;
|
|
73
|
+
}
|
|
74
|
+
var ret = {};
|
|
75
|
+
ret.code = buffer.readUInt32LE(from);
|
|
76
|
+
ret.length = buffer.readUInt16LE(from + 4);
|
|
77
|
+
if (ret.code == code) {
|
|
78
|
+
from += 8;
|
|
79
|
+
ret.text = buffer.toString(undefined, from, from + ret.length);
|
|
80
|
+
}
|
|
81
|
+
else
|
|
82
|
+
ret.seek = from + align(8 + ret.length);
|
|
83
|
+
return ret;
|
|
84
|
+
}
|
|
85
|
+
var rec = readRec(0);
|
|
86
|
+
while (rec.seek) {
|
|
87
|
+
if (rec.seek >= buffer.length)
|
|
88
|
+
break;
|
|
89
|
+
else
|
|
90
|
+
rec = readRec(rec.seek);
|
|
91
|
+
}
|
|
92
|
+
var str = rec.text;
|
|
93
|
+
if (item.params) {
|
|
94
|
+
for (var i = 0; i < item.params.length; i++)
|
|
95
|
+
str = str.replace('@' + String(i + 1), item.params[i]);
|
|
96
|
+
}
|
|
97
|
+
callback(str);
|
|
98
|
+
}
|
|
99
|
+
readIndex(1, top_tree);
|
|
100
|
+
}
|
|
101
|
+
fs_1.default.open(messageFile, 'r', function (err, h) {
|
|
102
|
+
if (!h) {
|
|
103
|
+
callback();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
buffer = Buffer.alloc(14);
|
|
107
|
+
fs_1.default.read(h, buffer, 0, 14, 0, function () {
|
|
108
|
+
handle = h;
|
|
109
|
+
bucket_size = buffer.readUInt16LE(2);
|
|
110
|
+
top_tree = buffer.readUInt32LE(4);
|
|
111
|
+
levels = buffer.readUInt16LE(12);
|
|
112
|
+
buffer = Buffer.alloc(bucket_size);
|
|
113
|
+
var i = 0;
|
|
114
|
+
var text;
|
|
115
|
+
function loop() {
|
|
116
|
+
lookup(status[i], function (line) {
|
|
117
|
+
if (text)
|
|
118
|
+
text = text + ', ' + line;
|
|
119
|
+
else
|
|
120
|
+
text = line;
|
|
121
|
+
if (i === status.length - 1) {
|
|
122
|
+
fs_1.default.closeSync(handle);
|
|
123
|
+
callback(text);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
i++;
|
|
127
|
+
loop();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
loop();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
exports.lookupMessages = lookupMessages;
|
package/lib/pool.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* Simple Pooling
|
|
4
|
+
*
|
|
5
|
+
***************************************/
|
|
6
|
+
import type { Callback } from './callback';
|
|
7
|
+
type AttachFn = (options: any, callback: Callback) => void;
|
|
8
|
+
declare class Pool {
|
|
9
|
+
attach: AttachFn;
|
|
10
|
+
internaldb: any[];
|
|
11
|
+
pooldb: any[];
|
|
12
|
+
dbinuse: number;
|
|
13
|
+
_creating: number;
|
|
14
|
+
max: number;
|
|
15
|
+
pending: Callback[];
|
|
16
|
+
options: any;
|
|
17
|
+
_destroyed: boolean;
|
|
18
|
+
constructor(attach: AttachFn, max: number, options: any);
|
|
19
|
+
get(callback: Callback): this;
|
|
20
|
+
check(): this;
|
|
21
|
+
destroy(callback?: (err?: any) => void): void;
|
|
22
|
+
}
|
|
23
|
+
export = Pool;
|
package/lib/pool.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/***************************************
|
|
2
3
|
*
|
|
3
4
|
* Simple Pooling
|
|
4
5
|
*
|
|
5
6
|
***************************************/
|
|
6
|
-
|
|
7
7
|
class Pool {
|
|
8
8
|
constructor(attach, max, options) {
|
|
9
|
-
this.attach
|
|
9
|
+
this.attach = attach;
|
|
10
10
|
this.internaldb = []; // connections created by the pool (for destroy)
|
|
11
|
-
this.pooldb
|
|
12
|
-
this.dbinuse
|
|
13
|
-
this._creating = 0;
|
|
14
|
-
this.max
|
|
15
|
-
this.pending
|
|
16
|
-
this.options
|
|
11
|
+
this.pooldb = []; // connections available in the pool (idle)
|
|
12
|
+
this.dbinuse = 0; // connections currently handed out to callers
|
|
13
|
+
this._creating = 0; // connections currently being created (attach in flight)
|
|
14
|
+
this.max = max || 4;
|
|
15
|
+
this.pending = []; // callbacks waiting for a free slot
|
|
16
|
+
this.options = options;
|
|
17
17
|
this._destroyed = false; // true after destroy() — prevents further use
|
|
18
18
|
}
|
|
19
|
-
|
|
20
19
|
get(callback) {
|
|
21
20
|
// [Fix 2] Reject immediately if the pool has already been destroyed.
|
|
22
21
|
if (this._destroyed) {
|
|
@@ -28,16 +27,13 @@ class Pool {
|
|
|
28
27
|
self.check();
|
|
29
28
|
return self;
|
|
30
29
|
}
|
|
31
|
-
|
|
32
30
|
check() {
|
|
33
31
|
var self = this;
|
|
34
|
-
|
|
35
32
|
// [Fix 2] Do not serve requests on a destroyed pool.
|
|
36
|
-
if (self._destroyed)
|
|
37
|
-
|
|
33
|
+
if (self._destroyed)
|
|
34
|
+
return self;
|
|
38
35
|
if ((self.dbinuse + self._creating) >= self.max)
|
|
39
36
|
return self;
|
|
40
|
-
|
|
41
37
|
var cb = self.pending.shift();
|
|
42
38
|
if (!cb)
|
|
43
39
|
return self;
|
|
@@ -46,7 +42,8 @@ class Pool {
|
|
|
46
42
|
// Discard connections that have been closed or destroyed while idle
|
|
47
43
|
if (db.connection && (db.connection._isClosed || db.connection._isDetach || !db.connection._socket || db.connection._socket.destroyed)) {
|
|
48
44
|
var idx = self.internaldb.indexOf(db);
|
|
49
|
-
if (idx !== -1)
|
|
45
|
+
if (idx !== -1)
|
|
46
|
+
self.internaldb.splice(idx, 1);
|
|
50
47
|
self.pending.unshift(cb);
|
|
51
48
|
setImmediate(function () { self.check(); });
|
|
52
49
|
return self;
|
|
@@ -54,13 +51,12 @@ class Pool {
|
|
|
54
51
|
// Idle connection available — hand it out immediately.
|
|
55
52
|
self.dbinuse++;
|
|
56
53
|
cb(null, db);
|
|
57
|
-
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
58
56
|
// No idle connection — create a new one via attach().
|
|
59
57
|
self._creating++;
|
|
60
|
-
|
|
61
58
|
var timedOut = false;
|
|
62
|
-
var timer
|
|
63
|
-
|
|
59
|
+
var timer = null;
|
|
64
60
|
// [Fix 1] Optional per-attach timeout.
|
|
65
61
|
// If attach() does not call back within connectTimeout ms (e.g. because
|
|
66
62
|
// the server accepted TCP but stalled on the Firebird wire protocol), we
|
|
@@ -70,16 +66,12 @@ class Pool {
|
|
|
70
66
|
timer = setTimeout(function () {
|
|
71
67
|
timedOut = true;
|
|
72
68
|
self._creating--;
|
|
73
|
-
cb(new Error(
|
|
74
|
-
'Connection timeout after ' + self.options.connectTimeout + 'ms'
|
|
75
|
-
), null);
|
|
69
|
+
cb(new Error('Connection timeout after ' + self.options.connectTimeout + 'ms'), null);
|
|
76
70
|
// Free the slot so the next pending request can be served.
|
|
77
71
|
setImmediate(function () { self.check(); });
|
|
78
72
|
}, self.options.connectTimeout);
|
|
79
73
|
}
|
|
80
|
-
|
|
81
74
|
this.attach(self.options, function (err, db) {
|
|
82
|
-
|
|
83
75
|
// [Fix 1] Timeout already fired — discard this late connection.
|
|
84
76
|
// Without this guard the socket would stay open until the OS-level
|
|
85
77
|
// TCP timeout (potentially minutes), leaking a file descriptor.
|
|
@@ -88,28 +80,30 @@ class Pool {
|
|
|
88
80
|
try {
|
|
89
81
|
// _pooled = false forces a real op_detach / socket close
|
|
90
82
|
// instead of a silent pool-return emit.
|
|
91
|
-
if (db.connection)
|
|
83
|
+
if (db.connection)
|
|
84
|
+
db.connection._pooled = false;
|
|
92
85
|
db.detach();
|
|
93
|
-
}
|
|
86
|
+
}
|
|
87
|
+
catch (e) { /* ignore cleanup errors */ }
|
|
94
88
|
}
|
|
95
89
|
return;
|
|
96
90
|
}
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
if (timer)
|
|
92
|
+
clearTimeout(timer);
|
|
99
93
|
self._creating--;
|
|
100
|
-
|
|
101
94
|
// [Fix 3] Pool was destroyed while attach() was in flight.
|
|
102
95
|
if (self._destroyed) {
|
|
103
96
|
if (db) {
|
|
104
97
|
try {
|
|
105
|
-
if (db.connection)
|
|
98
|
+
if (db.connection)
|
|
99
|
+
db.connection._pooled = false;
|
|
106
100
|
db.detach();
|
|
107
|
-
}
|
|
101
|
+
}
|
|
102
|
+
catch (e) { /* ignore cleanup errors */ }
|
|
108
103
|
}
|
|
109
104
|
cb(new Error('Pool has been destroyed'), null);
|
|
110
105
|
return;
|
|
111
106
|
}
|
|
112
|
-
|
|
113
107
|
if (!err) {
|
|
114
108
|
self.dbinuse++;
|
|
115
109
|
self.internaldb.push(db);
|
|
@@ -122,41 +116,36 @@ class Pool {
|
|
|
122
116
|
self.internaldb.splice(self.internaldb.indexOf(db), 1);
|
|
123
117
|
else
|
|
124
118
|
self.pooldb.push(db);
|
|
125
|
-
|
|
126
119
|
self.dbinuse--;
|
|
127
120
|
self.check();
|
|
128
121
|
});
|
|
129
122
|
}
|
|
130
|
-
|
|
131
123
|
cb(err, db);
|
|
132
124
|
});
|
|
133
125
|
}
|
|
134
|
-
setImmediate(function() {
|
|
126
|
+
setImmediate(function () {
|
|
135
127
|
self.check();
|
|
136
128
|
});
|
|
137
|
-
|
|
138
129
|
return self;
|
|
139
130
|
}
|
|
140
|
-
|
|
141
131
|
destroy(callback) {
|
|
142
132
|
var self = this;
|
|
143
133
|
self._destroyed = true;
|
|
144
|
-
|
|
145
134
|
// [Fix 4] Drain pending callbacks so callers are not left hanging.
|
|
146
135
|
// This is critical when destroy() is called as a recovery measure after
|
|
147
136
|
// a timeout: without draining, every concurrent pool.get() that had not
|
|
148
137
|
// yet received a slot would hang until the process exits.
|
|
149
138
|
var draining = self.pending.splice(0);
|
|
150
139
|
draining.forEach(function (cb) {
|
|
151
|
-
try {
|
|
140
|
+
try {
|
|
141
|
+
cb(new Error('Pool is being destroyed'), null);
|
|
142
|
+
}
|
|
143
|
+
catch (e) { /* ignore */ }
|
|
152
144
|
});
|
|
153
|
-
|
|
154
145
|
var connectionCount = this.internaldb.length;
|
|
155
|
-
|
|
156
146
|
if (connectionCount === 0 && callback) {
|
|
157
147
|
callback();
|
|
158
148
|
}
|
|
159
|
-
|
|
160
149
|
function detachCallback(err) {
|
|
161
150
|
if (err) {
|
|
162
151
|
if (callback) {
|
|
@@ -164,14 +153,12 @@ class Pool {
|
|
|
164
153
|
}
|
|
165
154
|
return;
|
|
166
155
|
}
|
|
167
|
-
|
|
168
156
|
connectionCount--;
|
|
169
157
|
if (connectionCount === 0 && callback) {
|
|
170
158
|
callback();
|
|
171
159
|
}
|
|
172
160
|
}
|
|
173
|
-
|
|
174
|
-
this.internaldb.forEach(function(db) {
|
|
161
|
+
this.internaldb.forEach(function (db) {
|
|
175
162
|
if (db.connection._pooled === false) {
|
|
176
163
|
detachCallback();
|
|
177
164
|
return;
|
|
@@ -182,7 +169,8 @@ class Pool {
|
|
|
182
169
|
self.pooldb.splice(_db_in_pool, 1);
|
|
183
170
|
db.connection._pooled = false;
|
|
184
171
|
db.detach(detachCallback);
|
|
185
|
-
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
186
174
|
// [Fix 5] Connection is currently in use (dbinuse > 0).
|
|
187
175
|
// The caller is responsible for releasing it via detach().
|
|
188
176
|
// Count it down here so the destroy() callback is not blocked forever.
|
|
@@ -191,5 +179,4 @@ class Pool {
|
|
|
191
179
|
});
|
|
192
180
|
}
|
|
193
181
|
}
|
|
194
|
-
|
|
195
182
|
module.exports = Pool;
|
package/lib/srp.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface KeyPair {
|
|
2
|
+
public: bigint;
|
|
3
|
+
private: bigint;
|
|
4
|
+
}
|
|
5
|
+
export interface ClientProof {
|
|
6
|
+
clientSessionKey: bigint;
|
|
7
|
+
authData: bigint;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a client key pair.
|
|
11
|
+
*
|
|
12
|
+
* @param a BigInt Client private key.
|
|
13
|
+
* @returns {{private: BigInt, public: BigInt}}
|
|
14
|
+
*/
|
|
15
|
+
export declare function clientSeed(a?: bigint): KeyPair;
|
|
16
|
+
/**
|
|
17
|
+
* Generate a server key pair.
|
|
18
|
+
*
|
|
19
|
+
* @param user string Connection username.
|
|
20
|
+
* @param password string Connection password.
|
|
21
|
+
* @param salt BigInt Connection salt.
|
|
22
|
+
* @param b BigInt Server private key.
|
|
23
|
+
* @returns {{private: BigInt, public: BigInt}}
|
|
24
|
+
*/
|
|
25
|
+
export declare function serverSeed(user: string, password: string, salt: Buffer, b?: bigint | string, hashAlgo?: string): KeyPair;
|
|
26
|
+
/**
|
|
27
|
+
* Server session secret.
|
|
28
|
+
*
|
|
29
|
+
* @param user string Connection username.
|
|
30
|
+
* @param password string Connection password.
|
|
31
|
+
* @param salt BigInt Connection salt.
|
|
32
|
+
* @param A BigInt Client public key.
|
|
33
|
+
* @param B BigInt Server public key.
|
|
34
|
+
* @param b BigInt Server private key.
|
|
35
|
+
* @returns {BigInt}
|
|
36
|
+
*/
|
|
37
|
+
export declare function serverSession(user: string, password: string, salt: Buffer, A: bigint, B: bigint, b: bigint, hashAlgo?: string): bigint;
|
|
38
|
+
/**
|
|
39
|
+
* M = H(H(N) xor H(g), H(I), s, A, B, K)
|
|
40
|
+
*/
|
|
41
|
+
export declare function clientProof(user: string, password: string, salt: Buffer, A: bigint, B: bigint, a: bigint, hashAlgo?: string): ClientProof;
|
|
42
|
+
/**
|
|
43
|
+
* Pad hex string.
|
|
44
|
+
*/
|
|
45
|
+
export declare function hexPad(hex: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* The SRP prime modulus N (1024-bit, same value used by Firebird).
|
|
48
|
+
* Exported so tests and tooling can assert key-size invariants without
|
|
49
|
+
* duplicating the constant.
|
|
50
|
+
*/
|
|
51
|
+
export declare const PRIME_N: bigint;
|