node-firebird 2.3.4 → 2.4.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 +544 -6
- 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
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import net from "net";
|
|
2
|
+
import zlib from "zlib";
|
|
3
|
+
/**
|
|
4
|
+
* Arc4 stream cipher for Firebird wire encryption.
|
|
5
|
+
* Uses the SRP session key to create RC4 encryption/decryption streams.
|
|
6
|
+
*/
|
|
7
|
+
declare class Arc4 {
|
|
8
|
+
_s: Uint8Array;
|
|
9
|
+
_i: number;
|
|
10
|
+
_j: number;
|
|
11
|
+
constructor(key: Buffer | Uint8Array);
|
|
12
|
+
/**
|
|
13
|
+
* Transform (encrypt/decrypt) data in place.
|
|
14
|
+
* RC4 is symmetric - encrypt and decrypt are the same operation.
|
|
15
|
+
*/
|
|
16
|
+
transform(data: Buffer | Uint8Array): Buffer;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Socket proxy.
|
|
20
|
+
*/
|
|
21
|
+
declare class Socket {
|
|
22
|
+
static Arc4: typeof Arc4;
|
|
23
|
+
_socket: net.Socket;
|
|
24
|
+
compress: boolean;
|
|
25
|
+
compressor: zlib.Deflate | null;
|
|
26
|
+
compressorBuffer: Buffer[];
|
|
27
|
+
decompressor: zlib.Inflate | null;
|
|
28
|
+
decompressorBuffer: Buffer[];
|
|
29
|
+
buffer: Buffer | null;
|
|
30
|
+
encrypt: boolean;
|
|
31
|
+
encryptCipher: any;
|
|
32
|
+
decryptCipher: any;
|
|
33
|
+
constructor(port: number, host: string);
|
|
34
|
+
/**
|
|
35
|
+
* Decompress and/or decrypt data when received.
|
|
36
|
+
* Override on data event.
|
|
37
|
+
*/
|
|
38
|
+
on(event: string, cb: (...args: any[]) => void): void;
|
|
39
|
+
/**
|
|
40
|
+
* Compress and/or encrypt data before sending to socket.
|
|
41
|
+
*/
|
|
42
|
+
write(data: Buffer | Uint8Array, defer?: boolean): void;
|
|
43
|
+
/**
|
|
44
|
+
* Enable compression/decompression on the fly.
|
|
45
|
+
*/
|
|
46
|
+
enableCompression(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Enable encryption/decryption.
|
|
49
|
+
* @param {Buffer} sessionKey - The session key from SRP authentication.
|
|
50
|
+
* @param {string} [pluginName='Arc4'] - The selected encryption plugin.
|
|
51
|
+
* @param {Buffer} [iv] - The initialization vector (needed for ChaCha/ChaCha64).
|
|
52
|
+
*/
|
|
53
|
+
enableEncryption(sessionKey: Buffer, pluginName?: string, iv?: Buffer): void;
|
|
54
|
+
/**
|
|
55
|
+
* Proxy trap.
|
|
56
|
+
*/
|
|
57
|
+
get(target: any, field: string | symbol): any;
|
|
58
|
+
}
|
|
59
|
+
export = Socket;
|
package/lib/wire/socket.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
const net_1 = __importDefault(require("net"));
|
|
6
|
+
const zlib_1 = __importDefault(require("zlib"));
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
4
8
|
/**
|
|
5
9
|
* Arc4 stream cipher for Firebird wire encryption.
|
|
6
10
|
* Uses the SRP session key to create RC4 encryption/decryption streams.
|
|
@@ -10,12 +14,10 @@ class Arc4 {
|
|
|
10
14
|
this._s = new Uint8Array(256);
|
|
11
15
|
this._i = 0;
|
|
12
16
|
this._j = 0;
|
|
13
|
-
|
|
14
17
|
// KSA (Key-Scheduling Algorithm)
|
|
15
18
|
for (var i = 0; i < 256; i++) {
|
|
16
19
|
this._s[i] = i;
|
|
17
20
|
}
|
|
18
|
-
|
|
19
21
|
var j = 0;
|
|
20
22
|
for (var i = 0; i < 256; i++) {
|
|
21
23
|
j = (j + this._s[i] + key[i % key.length]) & 0xFF;
|
|
@@ -25,7 +27,6 @@ class Arc4 {
|
|
|
25
27
|
this._s[j] = tmp;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
|
|
29
30
|
/**
|
|
30
31
|
* Transform (encrypt/decrypt) data in place.
|
|
31
32
|
* RC4 is symmetric - encrypt and decrypt are the same operation.
|
|
@@ -35,25 +36,54 @@ class Arc4 {
|
|
|
35
36
|
for (var n = 0; n < data.length; n++) {
|
|
36
37
|
this._i = (this._i + 1) & 0xFF;
|
|
37
38
|
this._j = (this._j + this._s[this._i]) & 0xFF;
|
|
38
|
-
|
|
39
39
|
// Swap
|
|
40
40
|
var tmp = this._s[this._i];
|
|
41
41
|
this._s[this._i] = this._s[this._j];
|
|
42
42
|
this._s[this._j] = tmp;
|
|
43
|
-
|
|
44
43
|
var k = this._s[(this._s[this._i] + this._s[this._j]) & 0xFF];
|
|
45
44
|
out[n] = data[n] ^ k;
|
|
46
45
|
}
|
|
47
46
|
return out;
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* ChaChaCipher wrapper around Node.js crypto.createCipheriv / createDecipheriv.
|
|
51
|
+
*/
|
|
52
|
+
class ChaChaCipher {
|
|
53
|
+
constructor(key, iv, ivlen, isEncrypt) {
|
|
54
|
+
const opensslIv = Buffer.alloc(16);
|
|
55
|
+
if (ivlen === 8) {
|
|
56
|
+
iv.copy(opensslIv, 8, 0, 8);
|
|
57
|
+
}
|
|
58
|
+
else if (ivlen === 16) {
|
|
59
|
+
const ctr = (iv[12] << 24) + (iv[13] << 16) + (iv[14] << 8) + iv[15];
|
|
60
|
+
opensslIv.writeUInt32LE(ctr, 0);
|
|
61
|
+
iv.copy(opensslIv, 4, 0, 12);
|
|
62
|
+
}
|
|
63
|
+
else if (ivlen === 12) {
|
|
64
|
+
iv.copy(opensslIv, 4, 0, 12);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error('Wrong IV length: ' + ivlen);
|
|
68
|
+
}
|
|
69
|
+
if (isEncrypt) {
|
|
70
|
+
this._cipher = crypto_1.default.createCipheriv('chacha20', key, opensslIv);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this._cipher = crypto_1.default.createDecipheriv('chacha20', key, opensslIv);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
transform(data) {
|
|
77
|
+
return this._cipher.update(data);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
51
80
|
/**
|
|
52
81
|
* Socket proxy.
|
|
53
82
|
*/
|
|
54
83
|
class Socket {
|
|
84
|
+
static { this.Arc4 = Arc4; }
|
|
55
85
|
constructor(port, host) {
|
|
56
|
-
this._socket =
|
|
86
|
+
this._socket = net_1.default.createConnection(port, host);
|
|
57
87
|
this._socket.setNoDelay(true);
|
|
58
88
|
this._socket.setKeepAlive(true, 60000); // 1 minute delay to detect dead/stale connections
|
|
59
89
|
this.compressor = null;
|
|
@@ -64,10 +94,8 @@ class Socket {
|
|
|
64
94
|
this.encrypt = false;
|
|
65
95
|
this.encryptCipher = null;
|
|
66
96
|
this.decryptCipher = null;
|
|
67
|
-
|
|
68
97
|
return new Proxy(this._socket, this);
|
|
69
98
|
}
|
|
70
|
-
|
|
71
99
|
/**
|
|
72
100
|
* Decompress and/or decrypt data when received.
|
|
73
101
|
* Override on data event.
|
|
@@ -79,26 +107,31 @@ class Socket {
|
|
|
79
107
|
// Decrypt first if encryption is enabled
|
|
80
108
|
if (this.encrypt) {
|
|
81
109
|
data = this.decryptCipher.transform(data);
|
|
110
|
+
if (process.env.FIREBIRD_DEBUG) {
|
|
111
|
+
console.log('[fb-debug] socket.read decrypted: length=%d RX-cipher-offset=%d', data.length, this.decryptCipher._i);
|
|
112
|
+
console.log('[fb-debug] socket.read decrypted hex: %s', data.toString('hex'));
|
|
113
|
+
}
|
|
82
114
|
}
|
|
83
|
-
|
|
84
115
|
if (this.compress) {
|
|
85
116
|
this.decompressor.write(data, () => {
|
|
86
117
|
mainCb(Buffer.concat(this.decompressorBuffer));
|
|
87
118
|
this.decompressorBuffer = []; // Reset buffer
|
|
88
119
|
});
|
|
89
|
-
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
90
122
|
mainCb(data);
|
|
91
123
|
}
|
|
92
124
|
};
|
|
93
125
|
}
|
|
94
|
-
|
|
95
126
|
this._socket.on(event, cb);
|
|
96
127
|
}
|
|
97
|
-
|
|
98
128
|
/**
|
|
99
129
|
* Compress and/or encrypt data before sending to socket.
|
|
100
130
|
*/
|
|
101
131
|
write(data, defer = false) {
|
|
132
|
+
if (process.env.FIREBIRD_DEBUG) {
|
|
133
|
+
console.log('[fb-debug] socket.write: length=%d bytes=%s encrypt=%s defer=%s', data.length, Buffer.from(data).toString('hex'), this.encrypt, defer);
|
|
134
|
+
}
|
|
102
135
|
if (defer) {
|
|
103
136
|
// Accumulate deferred packets instead of overwriting. Multiple
|
|
104
137
|
// deferred ops (e.g. op_close_blob followed immediately by
|
|
@@ -110,63 +143,73 @@ class Socket {
|
|
|
110
143
|
: Buffer.from(data);
|
|
111
144
|
return;
|
|
112
145
|
}
|
|
113
|
-
|
|
114
146
|
if (!defer && this.buffer) {
|
|
115
147
|
data = Buffer.concat([this.buffer, data]);
|
|
116
148
|
this.buffer = null;
|
|
117
149
|
}
|
|
118
|
-
|
|
119
150
|
if (this.compress) {
|
|
120
151
|
this.compressor.write(data, () => {
|
|
121
152
|
var compressedData = Buffer.concat(this.compressorBuffer);
|
|
122
153
|
this.compressorBuffer = []; // Reset buffer
|
|
123
|
-
|
|
124
154
|
// Encrypt after compression if encryption is enabled
|
|
125
155
|
if (this.encrypt) {
|
|
126
156
|
compressedData = this.encryptCipher.transform(compressedData);
|
|
127
157
|
}
|
|
128
|
-
|
|
129
158
|
this._socket.write(compressedData);
|
|
130
159
|
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
160
|
+
}
|
|
161
|
+
else if (this.encrypt) {
|
|
162
|
+
const out = this.encryptCipher.transform(data);
|
|
163
|
+
if (process.env.FIREBIRD_DEBUG) {
|
|
164
|
+
console.log('[fb-debug] socket.write encrypted: length=%d TX-cipher-offset=%d', out.length, this.encryptCipher._i);
|
|
165
|
+
}
|
|
166
|
+
this._socket.write(out);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
134
169
|
this._socket.write(data);
|
|
135
170
|
}
|
|
136
171
|
}
|
|
137
|
-
|
|
138
172
|
/**
|
|
139
173
|
* Enable compression/decompression on the fly.
|
|
140
174
|
*/
|
|
141
175
|
enableCompression() {
|
|
142
176
|
this.compress = true;
|
|
143
|
-
|
|
144
177
|
// Create decompressor instance
|
|
145
|
-
this.decompressor =
|
|
178
|
+
this.decompressor = zlib_1.default.createInflate();
|
|
146
179
|
this.decompressor.on('data', (inflate) => {
|
|
147
180
|
this.decompressorBuffer.push(inflate);
|
|
148
181
|
});
|
|
149
|
-
|
|
150
182
|
// Create compressor instance
|
|
151
|
-
this.compressor =
|
|
152
|
-
flush:
|
|
153
|
-
finishFlush:
|
|
183
|
+
this.compressor = zlib_1.default.createDeflate({
|
|
184
|
+
flush: zlib_1.default.constants.Z_FULL_FLUSH,
|
|
185
|
+
finishFlush: zlib_1.default.constants.Z_SYNC_FLUSH
|
|
154
186
|
});
|
|
155
187
|
this.compressor.on('data', (deflate) => {
|
|
156
188
|
this.compressorBuffer.push(deflate);
|
|
157
189
|
});
|
|
158
190
|
}
|
|
159
|
-
|
|
160
191
|
/**
|
|
161
|
-
* Enable encryption/decryption
|
|
192
|
+
* Enable encryption/decryption.
|
|
162
193
|
* @param {Buffer} sessionKey - The session key from SRP authentication.
|
|
194
|
+
* @param {string} [pluginName='Arc4'] - The selected encryption plugin.
|
|
195
|
+
* @param {Buffer} [iv] - The initialization vector (needed for ChaCha/ChaCha64).
|
|
163
196
|
*/
|
|
164
|
-
enableEncryption(sessionKey) {
|
|
197
|
+
enableEncryption(sessionKey, pluginName = 'Arc4', iv) {
|
|
165
198
|
this.encrypt = true;
|
|
166
|
-
|
|
167
|
-
|
|
199
|
+
if (pluginName === 'Arc4') {
|
|
200
|
+
this.encryptCipher = new Arc4(sessionKey);
|
|
201
|
+
this.decryptCipher = new Arc4(sessionKey);
|
|
202
|
+
}
|
|
203
|
+
else if (pluginName === 'ChaCha' || pluginName === 'ChaCha64') {
|
|
204
|
+
const stretchedKey = crypto_1.default.createHash('sha256').update(sessionKey).digest();
|
|
205
|
+
const ivlen = pluginName === 'ChaCha64' ? 8 : (iv ? iv.length : 16);
|
|
206
|
+
this.encryptCipher = new ChaChaCipher(stretchedKey, iv, ivlen, true);
|
|
207
|
+
this.decryptCipher = new ChaChaCipher(stretchedKey, iv, ivlen, false);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
throw new Error('Unsupported encryption plugin: ' + pluginName);
|
|
211
|
+
}
|
|
168
212
|
}
|
|
169
|
-
|
|
170
213
|
/**
|
|
171
214
|
* Proxy trap.
|
|
172
215
|
*/
|
|
@@ -174,14 +217,10 @@ class Socket {
|
|
|
174
217
|
if (field in this) {
|
|
175
218
|
return this[field].bind(this);
|
|
176
219
|
}
|
|
177
|
-
|
|
178
220
|
if (typeof target[field] === 'function') {
|
|
179
221
|
return target[field].bind(target);
|
|
180
222
|
}
|
|
181
|
-
|
|
182
223
|
return target[field];
|
|
183
224
|
}
|
|
184
225
|
}
|
|
185
|
-
|
|
186
226
|
module.exports = Socket;
|
|
187
|
-
module.exports.Arc4 = Arc4;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* Statement
|
|
4
|
+
*
|
|
5
|
+
***************************************/
|
|
6
|
+
declare class Statement {
|
|
7
|
+
connection: any;
|
|
8
|
+
query: string;
|
|
9
|
+
type: number;
|
|
10
|
+
output: any[];
|
|
11
|
+
input: any[];
|
|
12
|
+
options: any;
|
|
13
|
+
handle: number;
|
|
14
|
+
plan: string;
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
constructor(connection: any);
|
|
17
|
+
close(callback?: (err?: any) => void): void;
|
|
18
|
+
drop(callback?: (err?: any) => void): void;
|
|
19
|
+
release(callback?: (err?: any) => void): void;
|
|
20
|
+
execute(transaction: any, params?: any, callback?: any, options?: any): void;
|
|
21
|
+
fetch(transaction: any, count: number | string, callback: (err: any, result?: any) => void): void;
|
|
22
|
+
fetchScroll(transaction: any, direction: string | number, offset?: any, count?: any, callback?: any): void;
|
|
23
|
+
fetchAll(transaction: any, callback: (err: any, result?: any) => void): void;
|
|
24
|
+
}
|
|
25
|
+
export = Statement;
|
package/lib/wire/statement.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/***************************************
|
|
2
3
|
*
|
|
3
4
|
* Statement
|
|
4
5
|
*
|
|
5
6
|
***************************************/
|
|
6
|
-
|
|
7
7
|
class Statement {
|
|
8
8
|
constructor(connection) {
|
|
9
9
|
this.connection = connection;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
close(callback) {
|
|
13
12
|
this.connection.closeStatement(this, callback);
|
|
14
13
|
}
|
|
15
|
-
|
|
16
14
|
drop(callback) {
|
|
17
15
|
this.connection.dropStatement(this, callback);
|
|
18
16
|
}
|
|
19
|
-
|
|
20
17
|
release(callback) {
|
|
21
18
|
var cache_query = this.connection.getCachedQuery(this.query);
|
|
22
19
|
if (cache_query)
|
|
@@ -24,25 +21,32 @@ class Statement {
|
|
|
24
21
|
else
|
|
25
22
|
this.connection.dropStatement(this, callback);
|
|
26
23
|
}
|
|
27
|
-
|
|
28
24
|
execute(transaction, params, callback, options) {
|
|
29
25
|
if (params instanceof Function) {
|
|
30
26
|
options = callback;
|
|
31
27
|
callback = params;
|
|
32
28
|
params = undefined;
|
|
33
29
|
}
|
|
34
|
-
|
|
35
30
|
this.options = options;
|
|
36
31
|
this.connection.executeStatement(transaction, this, params, callback, options);
|
|
37
32
|
}
|
|
38
|
-
|
|
39
33
|
fetch(transaction, count, callback) {
|
|
40
34
|
this.connection.fetch(this, transaction, count, callback);
|
|
41
35
|
}
|
|
42
|
-
|
|
36
|
+
fetchScroll(transaction, direction, offset, count, callback) {
|
|
37
|
+
if (typeof count === 'function') {
|
|
38
|
+
callback = count;
|
|
39
|
+
count = undefined;
|
|
40
|
+
}
|
|
41
|
+
if (typeof offset === 'function') {
|
|
42
|
+
callback = offset;
|
|
43
|
+
offset = undefined;
|
|
44
|
+
count = undefined;
|
|
45
|
+
}
|
|
46
|
+
this.connection.fetchScroll(this, transaction, direction, offset, count, callback);
|
|
47
|
+
}
|
|
43
48
|
fetchAll(transaction, callback) {
|
|
44
49
|
this.connection.fetchAll(this, transaction, callback);
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
|
-
|
|
48
52
|
module.exports = Statement;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/***************************************
|
|
2
|
+
*
|
|
3
|
+
* Transaction
|
|
4
|
+
*
|
|
5
|
+
***************************************/
|
|
6
|
+
declare class Transaction {
|
|
7
|
+
connection: any;
|
|
8
|
+
db: any;
|
|
9
|
+
handle: number;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
constructor(connection: any);
|
|
12
|
+
newStatement(query: string, callback: (err: any, statement?: any) => void): void;
|
|
13
|
+
execute(query: string, params?: any, callback?: any, options?: any): void;
|
|
14
|
+
sequentially(query: string, params?: any, on?: any, callback?: any, options?: any): this;
|
|
15
|
+
query(query: string, params?: any, callback?: any, options?: any): void;
|
|
16
|
+
commit(callback?: (err?: any) => void): void;
|
|
17
|
+
rollback(callback?: (err?: any) => void): void;
|
|
18
|
+
commitRetaining(callback?: (err?: any) => void): void;
|
|
19
|
+
rollbackRetaining(callback?: (err?: any) => void): void;
|
|
20
|
+
}
|
|
21
|
+
export = Transaction;
|
package/lib/wire/transaction.js
CHANGED
|
@@ -1,109 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
const callback_1 = require("../callback");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const const_1 = __importDefault(require("./const"));
|
|
4
8
|
/***************************************
|
|
5
9
|
*
|
|
6
10
|
* Transaction
|
|
7
11
|
*
|
|
8
12
|
***************************************/
|
|
9
|
-
|
|
10
13
|
class Transaction {
|
|
11
14
|
constructor(connection) {
|
|
12
15
|
this.connection = connection;
|
|
13
16
|
this.db = connection.db;
|
|
14
17
|
}
|
|
15
|
-
|
|
16
18
|
newStatement(query, callback) {
|
|
17
19
|
var cnx = this.connection;
|
|
18
20
|
var self = this;
|
|
19
21
|
var query_cache = cnx.getCachedQuery(query);
|
|
20
|
-
|
|
21
22
|
if (query_cache) {
|
|
22
23
|
callback(null, query_cache);
|
|
23
|
-
}
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
24
26
|
cnx.prepare(self, query, false, callback);
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
|
-
|
|
28
29
|
execute(query, params, callback, options) {
|
|
29
30
|
if (params instanceof Function) {
|
|
30
31
|
options = callback;
|
|
31
32
|
callback = params;
|
|
32
33
|
params = undefined;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
35
|
var self = this;
|
|
36
|
-
this.newStatement(query, function(err, statement) {
|
|
37
|
-
|
|
36
|
+
this.newStatement(query, function (err, statement) {
|
|
38
37
|
if (err) {
|
|
39
|
-
doError(err, callback);
|
|
38
|
+
(0, callback_1.doError)(err, callback);
|
|
40
39
|
return;
|
|
41
40
|
}
|
|
42
|
-
|
|
43
41
|
function dropError(err) {
|
|
44
42
|
statement.release();
|
|
45
|
-
doCallback(err, callback);
|
|
43
|
+
(0, callback_1.doCallback)(err, callback);
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
statement.execute(self, params, function(err, ret) {
|
|
45
|
+
statement.execute(self, params, function (err, ret) {
|
|
49
46
|
if (err) {
|
|
50
47
|
dropError(err);
|
|
51
48
|
return;
|
|
52
49
|
}
|
|
53
|
-
|
|
54
50
|
switch (statement.type) {
|
|
55
|
-
case
|
|
56
|
-
statement.fetchAll(self, function(err, r) {
|
|
51
|
+
case const_1.default.isc_info_sql_stmt_select:
|
|
52
|
+
statement.fetchAll(self, function (err, r) {
|
|
57
53
|
if (err) {
|
|
58
54
|
dropError(err);
|
|
59
55
|
return;
|
|
60
56
|
}
|
|
61
|
-
|
|
62
57
|
statement.release();
|
|
63
|
-
|
|
64
58
|
if (callback)
|
|
65
59
|
callback(undefined, r, statement.output, true);
|
|
66
|
-
|
|
67
60
|
});
|
|
68
|
-
|
|
69
61
|
break;
|
|
70
|
-
|
|
71
|
-
case Const.isc_info_sql_stmt_exec_procedure:
|
|
62
|
+
case const_1.default.isc_info_sql_stmt_exec_procedure:
|
|
72
63
|
if (ret && ret.data && ret.data.length > 0) {
|
|
73
64
|
statement.release();
|
|
74
|
-
|
|
75
65
|
if (callback)
|
|
76
66
|
callback(undefined, ret.data[0], statement.output, true);
|
|
77
|
-
|
|
78
67
|
break;
|
|
79
|
-
}
|
|
80
|
-
|
|
68
|
+
}
|
|
69
|
+
else if (statement.output.length) {
|
|
70
|
+
statement.fetch(self, 1, function (err, ret) {
|
|
81
71
|
if (err) {
|
|
82
72
|
dropError(err);
|
|
83
73
|
return;
|
|
84
74
|
}
|
|
85
|
-
|
|
86
75
|
statement.release();
|
|
87
|
-
|
|
88
76
|
if (callback)
|
|
89
77
|
callback(undefined, ret.data[0], statement.output, false);
|
|
90
78
|
});
|
|
91
|
-
|
|
92
79
|
break;
|
|
93
80
|
}
|
|
94
|
-
|
|
95
81
|
// Fall through is normal
|
|
96
82
|
default:
|
|
97
83
|
statement.release();
|
|
98
84
|
if (callback)
|
|
99
|
-
callback()
|
|
85
|
+
callback();
|
|
100
86
|
break;
|
|
101
87
|
}
|
|
102
|
-
|
|
103
88
|
}, options);
|
|
104
89
|
});
|
|
105
90
|
}
|
|
106
|
-
|
|
107
91
|
sequentially(query, params, on, callback, options = {}) {
|
|
108
92
|
if (params instanceof Function) {
|
|
109
93
|
options = callback;
|
|
@@ -111,51 +95,49 @@ class Transaction {
|
|
|
111
95
|
on = params;
|
|
112
96
|
params = undefined;
|
|
113
97
|
}
|
|
114
|
-
|
|
115
|
-
if (on === undefined){
|
|
98
|
+
if (on === undefined) {
|
|
116
99
|
throw new Error('Expected "on" delegate.');
|
|
117
100
|
}
|
|
118
|
-
|
|
119
101
|
if (callback instanceof Boolean) {
|
|
120
102
|
options = callback;
|
|
121
103
|
callback = undefined;
|
|
122
104
|
}
|
|
123
|
-
|
|
124
105
|
var self = this;
|
|
125
|
-
var _on = function(row, i, meta, next) {
|
|
106
|
+
var _on = function (row, i, meta, next) {
|
|
126
107
|
var done = false;
|
|
127
|
-
var finish = function(err) {
|
|
108
|
+
var finish = function (err) {
|
|
128
109
|
if (done) {
|
|
129
110
|
return;
|
|
130
111
|
}
|
|
131
112
|
done = true;
|
|
132
113
|
next(err);
|
|
133
114
|
};
|
|
134
|
-
|
|
135
115
|
try {
|
|
136
116
|
var ret;
|
|
137
117
|
if (on.length >= 3) {
|
|
138
118
|
ret = on(row, i, finish);
|
|
139
|
-
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
140
121
|
ret = on(row, i);
|
|
141
122
|
}
|
|
142
|
-
|
|
143
123
|
if (ret && typeof ret.then === 'function') {
|
|
144
|
-
ret.then(function() {
|
|
124
|
+
ret.then(function () {
|
|
145
125
|
finish();
|
|
146
126
|
}).catch(finish);
|
|
147
|
-
}
|
|
127
|
+
}
|
|
128
|
+
else if (on.length < 3) {
|
|
148
129
|
finish();
|
|
149
130
|
}
|
|
150
|
-
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
151
133
|
finish(err);
|
|
152
134
|
}
|
|
153
135
|
};
|
|
154
|
-
|
|
155
136
|
// back compatibility - options parameter is a boolean
|
|
156
137
|
if (typeof options === 'boolean') {
|
|
157
138
|
options = { asObject: !options, asStream: true, on: _on };
|
|
158
|
-
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
159
141
|
options = {
|
|
160
142
|
asStream: true,
|
|
161
143
|
asObject: true,
|
|
@@ -163,44 +145,34 @@ class Transaction {
|
|
|
163
145
|
...options,
|
|
164
146
|
};
|
|
165
147
|
}
|
|
166
|
-
|
|
167
148
|
self.execute(query, params, callback, options);
|
|
168
149
|
return self;
|
|
169
150
|
}
|
|
170
|
-
|
|
171
151
|
query(query, params, callback, options = {}) {
|
|
172
152
|
if (params instanceof Function) {
|
|
173
153
|
callback = params;
|
|
174
154
|
params = undefined;
|
|
175
155
|
}
|
|
176
|
-
|
|
177
156
|
if (callback === undefined)
|
|
178
|
-
callback = noop;
|
|
179
|
-
|
|
157
|
+
callback = utils_1.noop;
|
|
180
158
|
options = {
|
|
181
159
|
asObject: true,
|
|
182
160
|
asStream: callback === undefined || callback === null,
|
|
183
161
|
...options,
|
|
184
162
|
};
|
|
185
|
-
|
|
186
163
|
this.execute(query, params, callback, options);
|
|
187
164
|
}
|
|
188
|
-
|
|
189
165
|
commit(callback) {
|
|
190
166
|
this.connection.commit(this, callback);
|
|
191
167
|
}
|
|
192
|
-
|
|
193
168
|
rollback(callback) {
|
|
194
169
|
this.connection.rollback(this, callback);
|
|
195
170
|
}
|
|
196
|
-
|
|
197
171
|
commitRetaining(callback) {
|
|
198
172
|
this.connection.commitRetaining(this, callback);
|
|
199
173
|
}
|
|
200
|
-
|
|
201
174
|
rollbackRetaining(callback) {
|
|
202
175
|
this.connection.rollbackRetaining(this, callback);
|
|
203
176
|
}
|
|
204
177
|
}
|
|
205
|
-
|
|
206
178
|
module.exports = Transaction;
|