node-firebird 2.0.2 → 2.3.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/.github/workflows/node.js.yml +20 -0
- package/BIGINT_MIGRATION.md +374 -0
- package/CI_DEBUGGING_GUIDE.md +148 -0
- package/FIREBIRD_LOG_FEATURE.md +145 -0
- package/MINIMAL_CHANGES_SUMMARY.md +136 -0
- package/PR_SUMMARY.md +88 -131
- package/README.md +142 -22
- package/ROADMAP.md +223 -0
- package/SRP_PROTOCOL.md +482 -0
- package/lib/ieee754-decimal.js +500 -0
- package/lib/index.d.ts +10 -6
- package/lib/srp.js +65 -50
- package/lib/wire/connection.js +257 -56
- package/lib/wire/const.js +29 -0
- package/lib/wire/database.js +78 -9
- package/lib/wire/eventConnection.js +6 -3
- package/lib/wire/fbEventManager.js +234 -41
- package/lib/wire/serialize.js +39 -0
- package/lib/wire/service.js +102 -94
- package/lib/wire/statement.js +4 -4
- package/lib/wire/transaction.js +27 -9
- package/lib/wire/xsqlvar.js +176 -0
- package/package.json +5 -5
- package/vitest.config.js +12 -1
- package/Roadmap.md +0 -80
package/lib/wire/service.js
CHANGED
|
@@ -135,102 +135,110 @@ class ServiceManager extends Events.EventEmitter {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
_processquery(buffer, callback) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
this._processdbinfo(br, res);
|
|
158
|
-
break;
|
|
159
|
-
case Const.isc_info_svc_limbo_trans:
|
|
160
|
-
// not implemented
|
|
161
|
-
for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
|
|
138
|
+
if (!Buffer.isBuffer(buffer)) {
|
|
139
|
+
doError(new Error('Malformed service-manager response: missing BLR buffer'), callback);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
var br = new BlrReader(buffer);
|
|
145
|
+
var tinfo = br.readByteCode();
|
|
146
|
+
var res = {};
|
|
147
|
+
res.result = 0;
|
|
148
|
+
for (; tinfo !== Const.isc_info_end; tinfo = br.readByteCode()) {
|
|
149
|
+
switch (tinfo) {
|
|
150
|
+
case Const.isc_info_svc_server_version:
|
|
151
|
+
case Const.isc_info_svc_implementation:
|
|
152
|
+
case Const.isc_info_svc_user_dbpath:
|
|
153
|
+
case Const.isc_info_svc_get_env:
|
|
154
|
+
case Const.isc_info_svc_get_env_lock:
|
|
155
|
+
case Const.isc_info_svc_get_env_msg:
|
|
156
|
+
res[this._infosmapping[tinfo]] = br.readString();
|
|
162
157
|
break;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
158
|
+
case Const.isc_info_svc_version:
|
|
159
|
+
res[this._infosmapping[tinfo]] = br.readInt32();
|
|
160
|
+
break;
|
|
161
|
+
case Const.isc_info_svc_svr_db_info:
|
|
162
|
+
this._processdbinfo(br, res);
|
|
163
|
+
break;
|
|
164
|
+
case Const.isc_info_svc_limbo_trans:
|
|
165
|
+
// not implemented
|
|
166
|
+
for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
|
|
167
|
+
break;
|
|
168
|
+
case Const.isc_info_svc_get_users:
|
|
169
|
+
br.pos += 2
|
|
170
|
+
res[this._infosmapping[tinfo]] = [];
|
|
171
|
+
break;
|
|
172
|
+
case Const.isc_spb_sec_username:
|
|
173
|
+
var tuser = res[this._infosmapping[68]];
|
|
174
|
+
tuser.push({});
|
|
175
|
+
tuser[tuser.length - 1].username = br.readString();
|
|
176
|
+
break;
|
|
177
|
+
case Const.isc_spb_sec_firstname:
|
|
178
|
+
var tuser = res[this._infosmapping[68]];
|
|
179
|
+
var user = tuser[tuser.length-1];
|
|
180
|
+
user.firstname = br.readString();
|
|
181
|
+
break;
|
|
182
|
+
case Const.isc_spb_sec_middlename:
|
|
183
|
+
var tuser = res[this._infosmapping[68]];
|
|
184
|
+
var user = tuser[tuser.length-1];
|
|
185
|
+
user.middlename = br.readString();
|
|
186
|
+
break;
|
|
187
|
+
case Const.isc_spb_sec_lastname:
|
|
188
|
+
var tuser = res[this._infosmapping[68]];
|
|
189
|
+
var user = tuser[tuser.length-1];
|
|
190
|
+
user.lastname = br.readString();
|
|
191
|
+
break;
|
|
192
|
+
case Const.isc_spb_sec_groupid:
|
|
193
|
+
var tuser = res[this._infosmapping[68]];
|
|
194
|
+
var user = tuser[tuser.length-1];
|
|
195
|
+
user.groupid = br.readInt32();
|
|
196
|
+
break;
|
|
197
|
+
case Const.isc_spb_sec_userid:
|
|
198
|
+
var tuser = res[this._infosmapping[68]];
|
|
199
|
+
var user = tuser[tuser.length-1];
|
|
200
|
+
user.userid = br.readInt32();
|
|
201
|
+
|
|
202
|
+
break;
|
|
203
|
+
case Const.isc_spb_sec_admin:
|
|
204
|
+
var tuser = res[this._infosmapping[68]];
|
|
205
|
+
var user = tuser[tuser.length-1];
|
|
206
|
+
user.admin = br.readInt32();
|
|
207
|
+
break;
|
|
208
|
+
|
|
209
|
+
case Const.isc_info_svc_line:
|
|
210
|
+
res.line = br.readString();
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case Const.isc_info_svc_to_eof:
|
|
214
|
+
res.line = br.readString();
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case Const.isc_info_truncated:
|
|
218
|
+
res.result = 1; // too much data for the result buffer increase size of it (buffersize parameter))
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case Const.isc_info_data_not_ready:
|
|
222
|
+
res.result = 2;
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
case Const.isc_info_svc_timeout:
|
|
226
|
+
res.result = 3;
|
|
227
|
+
break;
|
|
228
|
+
|
|
229
|
+
case Const.isc_info_svc_stdin:
|
|
230
|
+
|
|
231
|
+
break;
|
|
232
|
+
|
|
233
|
+
case Const.isc_info_svc_capabilities:
|
|
234
|
+
this._processcapabilities(br, res);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
231
237
|
}
|
|
238
|
+
callback(null, res);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
doError(new Error('Malformed service-manager response: ' + err.message), callback);
|
|
232
241
|
}
|
|
233
|
-
callback(null, res);
|
|
234
242
|
}
|
|
235
243
|
|
|
236
244
|
detach(callback, force) {
|
|
@@ -1047,4 +1055,4 @@ class ServiceManager extends Events.EventEmitter {
|
|
|
1047
1055
|
ServiceManager.ShutdownMode = ShutdownMode;
|
|
1048
1056
|
ServiceManager.ShutdownKind = ShutdownKind;
|
|
1049
1057
|
|
|
1050
|
-
module.exports = ServiceManager;
|
|
1058
|
+
module.exports = ServiceManager;
|
package/lib/wire/statement.js
CHANGED
|
@@ -25,15 +25,15 @@ class Statement {
|
|
|
25
25
|
this.connection.dropStatement(this, callback);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
execute(transaction, params, callback,
|
|
28
|
+
execute(transaction, params, callback, options) {
|
|
29
29
|
if (params instanceof Function) {
|
|
30
|
-
|
|
30
|
+
options = callback;
|
|
31
31
|
callback = params;
|
|
32
32
|
params = undefined;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
this.
|
|
36
|
-
this.connection.executeStatement(transaction, this, params, callback,
|
|
35
|
+
this.options = options;
|
|
36
|
+
this.connection.executeStatement(transaction, this, params, callback, options);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
fetch(transaction, count, callback) {
|
package/lib/wire/transaction.js
CHANGED
|
@@ -25,9 +25,9 @@ class Transaction {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
execute(query, params, callback,
|
|
28
|
+
execute(query, params, callback, options) {
|
|
29
29
|
if (params instanceof Function) {
|
|
30
|
-
|
|
30
|
+
options = callback;
|
|
31
31
|
callback = params;
|
|
32
32
|
params = undefined;
|
|
33
33
|
}
|
|
@@ -100,13 +100,13 @@ class Transaction {
|
|
|
100
100
|
break;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
},
|
|
103
|
+
}, options);
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
sequentially(query, params, on, callback,
|
|
107
|
+
sequentially(query, params, on, callback, options = {}) {
|
|
108
108
|
if (params instanceof Function) {
|
|
109
|
-
|
|
109
|
+
options = callback;
|
|
110
110
|
callback = on;
|
|
111
111
|
on = params;
|
|
112
112
|
params = undefined;
|
|
@@ -117,7 +117,7 @@ class Transaction {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
if (callback instanceof Boolean) {
|
|
120
|
-
|
|
120
|
+
options = callback;
|
|
121
121
|
callback = undefined;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -152,11 +152,23 @@ class Transaction {
|
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
// back compatibility - options parameter is a boolean
|
|
156
|
+
if (typeof options === 'boolean') {
|
|
157
|
+
options = { asObject: !options, asStream: true, on: _on };
|
|
158
|
+
} else {
|
|
159
|
+
options = {
|
|
160
|
+
asStream: true,
|
|
161
|
+
asObject: true,
|
|
162
|
+
on: _on,
|
|
163
|
+
...options,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
self.execute(query, params, callback, options);
|
|
156
168
|
return self;
|
|
157
169
|
}
|
|
158
170
|
|
|
159
|
-
query(query, params, callback) {
|
|
171
|
+
query(query, params, callback, options = {}) {
|
|
160
172
|
if (params instanceof Function) {
|
|
161
173
|
callback = params;
|
|
162
174
|
params = undefined;
|
|
@@ -165,7 +177,13 @@ class Transaction {
|
|
|
165
177
|
if (callback === undefined)
|
|
166
178
|
callback = noop;
|
|
167
179
|
|
|
168
|
-
|
|
180
|
+
options = {
|
|
181
|
+
asObject: true,
|
|
182
|
+
asStream: callback === undefined || callback === null,
|
|
183
|
+
...options,
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
this.execute(query, params, callback, options);
|
|
169
187
|
}
|
|
170
188
|
|
|
171
189
|
commit(callback) {
|
package/lib/wire/xsqlvar.js
CHANGED
|
@@ -199,6 +199,44 @@ class SQLVarInt128 {
|
|
|
199
199
|
|
|
200
200
|
//------------------------------------------------------
|
|
201
201
|
|
|
202
|
+
class SQLVarDecFloat16 {
|
|
203
|
+
decode(data, lowerV13) {
|
|
204
|
+
var ret = data.readDecFloat16();
|
|
205
|
+
|
|
206
|
+
if (!lowerV13 || !data.readInt()) {
|
|
207
|
+
return ret;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
calcBlr(blr) {
|
|
214
|
+
blr.addByte(Const.blr_dec64);
|
|
215
|
+
blr.addShort(0);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
class SQLVarDecFloat34 {
|
|
222
|
+
decode(data, lowerV13) {
|
|
223
|
+
var ret = data.readDecFloat34();
|
|
224
|
+
|
|
225
|
+
if (!lowerV13 || !data.readInt()) {
|
|
226
|
+
return ret;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
calcBlr(blr) {
|
|
233
|
+
blr.addByte(Const.blr_dec128);
|
|
234
|
+
blr.addShort(0);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
//------------------------------------------------------
|
|
239
|
+
|
|
202
240
|
class SQLVarFloat {
|
|
203
241
|
decode(data, lowerV13) {
|
|
204
242
|
var ret = data.readFloat();
|
|
@@ -295,6 +333,92 @@ class SQLVarTimeStamp {
|
|
|
295
333
|
|
|
296
334
|
//------------------------------------------------------
|
|
297
335
|
|
|
336
|
+
class SQLVarTimeTz {
|
|
337
|
+
decode(data, lowerV13) {
|
|
338
|
+
var time = data.readUInt();
|
|
339
|
+
data.readInt(); // skip timezone info
|
|
340
|
+
|
|
341
|
+
if (!lowerV13 || !data.readInt()) {
|
|
342
|
+
var d = new Date(0);
|
|
343
|
+
d.setMilliseconds(Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
344
|
+
return d;
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
calcBlr(blr) {
|
|
350
|
+
blr.addByte(Const.blr_sql_time_tz);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
//------------------------------------------------------
|
|
355
|
+
|
|
356
|
+
class SQLVarTimeTzEx extends SQLVarTimeTz {
|
|
357
|
+
decode(data, lowerV13) {
|
|
358
|
+
var time = data.readUInt();
|
|
359
|
+
data.readInt(); // skip timezone info
|
|
360
|
+
data.readInt(); // skip ext_offset
|
|
361
|
+
|
|
362
|
+
if (!lowerV13 || !data.readInt()) {
|
|
363
|
+
var d = new Date(0);
|
|
364
|
+
d.setMilliseconds(Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
365
|
+
return d;
|
|
366
|
+
}
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
calcBlr(blr) {
|
|
371
|
+
blr.addByte(Const.blr_ex_time_tz);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
//------------------------------------------------------
|
|
376
|
+
|
|
377
|
+
class SQLVarTimeStampTz {
|
|
378
|
+
decode(data, lowerV13) {
|
|
379
|
+
var date = data.readInt();
|
|
380
|
+
var time = data.readUInt();
|
|
381
|
+
data.readInt(); // skip timezone info
|
|
382
|
+
|
|
383
|
+
if (!lowerV13 || !data.readInt()) {
|
|
384
|
+
var d = new Date(0);
|
|
385
|
+
d.setMilliseconds((date - DateOffset) * TimeCoeff + Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
386
|
+
return d;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
calcBlr(blr) {
|
|
393
|
+
blr.addByte(Const.blr_timestamp_tz);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
//------------------------------------------------------
|
|
398
|
+
|
|
399
|
+
class SQLVarTimeStampTzEx extends SQLVarTimeStampTz {
|
|
400
|
+
decode(data, lowerV13) {
|
|
401
|
+
var date = data.readInt();
|
|
402
|
+
var time = data.readUInt();
|
|
403
|
+
data.readInt(); // skip timezone info
|
|
404
|
+
data.readInt(); // skip ext_offset
|
|
405
|
+
|
|
406
|
+
if (!lowerV13 || !data.readInt()) {
|
|
407
|
+
var d = new Date(0);
|
|
408
|
+
d.setMilliseconds((date - DateOffset) * TimeCoeff + Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
409
|
+
return d;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
calcBlr(blr) {
|
|
416
|
+
blr.addByte(Const.blr_ex_timestamp_tz);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
//------------------------------------------------------
|
|
421
|
+
|
|
298
422
|
class SQLVarBoolean {
|
|
299
423
|
decode(data, lowerV13) {
|
|
300
424
|
var ret = data.readInt();
|
|
@@ -378,6 +502,50 @@ class SQLParamInt128 {
|
|
|
378
502
|
|
|
379
503
|
//------------------------------------------------------
|
|
380
504
|
|
|
505
|
+
class SQLParamDecFloat16 {
|
|
506
|
+
constructor(value) {
|
|
507
|
+
this.value = value;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
calcBlr(blr) {
|
|
511
|
+
blr.addByte(Const.blr_dec64);
|
|
512
|
+
blr.addShort(0);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
encode(data) {
|
|
516
|
+
if (this.value != null) {
|
|
517
|
+
data.addDecFloat16(this.value);
|
|
518
|
+
} else {
|
|
519
|
+
data.addDecFloat16(0);
|
|
520
|
+
data.addInt(1);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
//------------------------------------------------------
|
|
526
|
+
|
|
527
|
+
class SQLParamDecFloat34 {
|
|
528
|
+
constructor(value) {
|
|
529
|
+
this.value = value;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
calcBlr(blr) {
|
|
533
|
+
blr.addByte(Const.blr_dec128);
|
|
534
|
+
blr.addShort(0);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
encode(data) {
|
|
538
|
+
if (this.value != null) {
|
|
539
|
+
data.addDecFloat34(this.value);
|
|
540
|
+
} else {
|
|
541
|
+
data.addDecFloat34(0);
|
|
542
|
+
data.addInt(1);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
//------------------------------------------------------
|
|
548
|
+
|
|
381
549
|
class SQLParamDouble {
|
|
382
550
|
constructor(value) {
|
|
383
551
|
this.value = value;
|
|
@@ -509,6 +677,8 @@ module.exports = {
|
|
|
509
677
|
SQLVarInt,
|
|
510
678
|
SQLVarInt64,
|
|
511
679
|
SQLVarInt128,
|
|
680
|
+
SQLVarDecFloat16,
|
|
681
|
+
SQLVarDecFloat34,
|
|
512
682
|
SQLVarFloat,
|
|
513
683
|
SQLVarNull,
|
|
514
684
|
SQLVarShort,
|
|
@@ -516,12 +686,18 @@ module.exports = {
|
|
|
516
686
|
SQLVarText,
|
|
517
687
|
SQLVarTime,
|
|
518
688
|
SQLVarTimeStamp,
|
|
689
|
+
SQLVarTimeTz,
|
|
690
|
+
SQLVarTimeTzEx,
|
|
691
|
+
SQLVarTimeStampTz,
|
|
692
|
+
SQLVarTimeStampTzEx,
|
|
519
693
|
SQLParamBool,
|
|
520
694
|
SQLParamDate,
|
|
521
695
|
SQLParamDouble,
|
|
522
696
|
SQLParamInt,
|
|
523
697
|
SQLParamInt64,
|
|
524
698
|
SQLParamInt128,
|
|
699
|
+
SQLParamDecFloat16,
|
|
700
|
+
SQLParamDecFloat34,
|
|
525
701
|
SQLParamQuad,
|
|
526
702
|
SQLParamString,
|
|
527
703
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-firebird",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Pure JavaScript and Asynchronous Firebird client for Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"firebird",
|
|
@@ -25,15 +25,15 @@
|
|
|
25
25
|
"types": "./lib/index.d.ts",
|
|
26
26
|
"license": "MPL-2.0",
|
|
27
27
|
"scripts": {
|
|
28
|
-
"test": "vitest run"
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"lint": "oxlint"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
|
-
"big-integer": "^1.6.51",
|
|
32
32
|
"long": "^5.2.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"coveralls-next": "^
|
|
36
|
-
"
|
|
35
|
+
"coveralls-next": "^6.0.1",
|
|
36
|
+
"oxlint": "^0.15.11",
|
|
37
37
|
"vitest": "^4.0.18"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/vitest.config.js
CHANGED
|
@@ -8,6 +8,17 @@ module.exports = defineConfig({
|
|
|
8
8
|
fileParallelism: false,
|
|
9
9
|
maxWorkers: 1,
|
|
10
10
|
isolate: false,
|
|
11
|
-
include: [
|
|
11
|
+
include: [
|
|
12
|
+
'test/arc4.js',
|
|
13
|
+
'test/protocol.js',
|
|
14
|
+
'test/srp.js',
|
|
15
|
+
'test/service.js',
|
|
16
|
+
'test/utf8-user-identification.js',
|
|
17
|
+
'test/index.js',
|
|
18
|
+
'test/db-crypt-config.js',
|
|
19
|
+
'test/timezone.js',
|
|
20
|
+
'test/decfloat.js',
|
|
21
|
+
'test/mock-server.js'
|
|
22
|
+
],
|
|
12
23
|
},
|
|
13
24
|
});
|
package/Roadmap.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Node-Firebird Roadmap
|
|
2
|
-
|
|
3
|
-
This document outlines the future development direction for the `node-firebird` library. Our primary goals are to modernize the codebase, implement support for the latest Firebird features, and improve the overall developer experience.
|
|
4
|
-
|
|
5
|
-
## Protocol Implementation Status
|
|
6
|
-
|
|
7
|
-
The following table summarizes the current and planned implementation status of the Firebird wire protocol for each major version.
|
|
8
|
-
|
|
9
|
-
| Firebird Version | Protocol Versions | Status |
|
|
10
|
-
| :--- | :--- | :--- |
|
|
11
|
-
| 2.5 | 10, 11, 12, 13 | ✅ Implemented |
|
|
12
|
-
| 3.0 | 14, 15 | ✅ Implemented |
|
|
13
|
-
| 4.0 | 16, 17 | ❌ Not Implemented |
|
|
14
|
-
| 5.0 | N/A | ❌ Not Implemented |
|
|
15
|
-
| 6.0 | N/A | ❌ Not Implemented |
|
|
16
|
-
|
|
17
|
-
## Firebird 3 Support
|
|
18
|
-
|
|
19
|
-
Firebird 3 introduced Protocol 13, which brought significant changes focusing on security and performance. The following features have been implemented:
|
|
20
|
-
|
|
21
|
-
- **Protocol Versions 14 and 15:** ✅ Implemented - newer wire protocol versions are now supported.
|
|
22
|
-
- **Enhanced Authentication:** ✅ Implemented - Srp256 (SHA-256) authentication plugin is now supported alongside Srp (SHA-1) and Legacy_Auth.
|
|
23
|
-
- **Wire Protocol Encryption:** ✅ Implemented - Arc4 (RC4) stream cipher encryption for all network traffic using SRP session keys.
|
|
24
|
-
- **Wire Protocol Compression:** ✅ Implemented - zlib compression support for protocol version 13+.
|
|
25
|
-
- **Packed (NULL-aware) Row Data:** ✅ Implemented - null bitmap support for protocol version 13+.
|
|
26
|
-
- **op_cond_accept Handling:** ✅ Implemented - proper handling of conditional accept with authentication continuation.
|
|
27
|
-
- **UTF-8 User Identification:** ✅ Implemented - all user identification is properly handled with UTF-8 encoding via `isc_dpb_utf8_filename` flag for Firebird 3+.
|
|
28
|
-
- **Database Encryption Callback:** ✅ Implemented - support for database encryption key callback (`op_crypt_key_callback`) during the connect phase, allowing connections to encrypted databases. The `dbCryptConfig` connection option supports both plain text and base64-encoded encryption keys.
|
|
29
|
-
|
|
30
|
-
The following features are planned for future implementation:
|
|
31
|
-
|
|
32
|
-
## Firebird 4 Support
|
|
33
|
-
|
|
34
|
-
Firebird 4 introduced Protocol versions 16 and 17, continuing to build upon the foundation of Firebird 3. Key features to implement include:
|
|
35
|
-
|
|
36
|
-
- **Protocol Versions 16 and 17:** Implement the latest protocol versions to support Firebird 4 features.
|
|
37
|
-
|
|
38
|
-
## Firebird 5 Support
|
|
39
|
-
|
|
40
|
-
Firebird 5 introduces a host of new SQL features and performance improvements that will require significant client-side implementation:
|
|
41
|
-
|
|
42
|
-
- **Bidirectional Cursors:** Implement support for scrollable cursors for remote database access.
|
|
43
|
-
- **`RETURNING` Multiple Rows:** Enhance DML operations to support returning multiple rows.
|
|
44
|
-
- **`SKIP LOCKED`:** Add support for the `SKIP LOCKED` clause in `SELECT WITH LOCK`, `UPDATE`, and `DELETE` statements.
|
|
45
|
-
- **New Data Types and Functions:** Add support for new built-in functions and packages.
|
|
46
|
-
|
|
47
|
-
## Firebird 6 and Beyond
|
|
48
|
-
|
|
49
|
-
As Firebird 6 and future versions are released, we will continue to monitor new features and plan for their implementation. Key areas of interest include:
|
|
50
|
-
|
|
51
|
-
- **JSON Support:** Implement client-side support for the new SQL-compliant JSON functions.
|
|
52
|
-
- **Tablespaces:** Add support for tablespaces.
|
|
53
|
-
- **SQL Schemas:** Implement support for SQL schemas.
|
|
54
|
-
|
|
55
|
-
## Codebase Refactoring
|
|
56
|
-
|
|
57
|
-
The current codebase is functional but could be significantly improved by adopting modern JavaScript and TypeScript features.
|
|
58
|
-
|
|
59
|
-
### Modern JavaScript Classes
|
|
60
|
-
|
|
61
|
-
The existing codebase is written in a prototype-based style. We plan to refactor the entire library to use modern JavaScript classes (`class` syntax). This will improve readability, maintainability, and make the code easier to understand for new contributors.
|
|
62
|
-
|
|
63
|
-
**Benefits:**
|
|
64
|
-
|
|
65
|
-
- Improved code structure and organization.
|
|
66
|
-
- Easier to reason about inheritance and object-oriented patterns.
|
|
67
|
-
- Better alignment with modern JavaScript best practices.
|
|
68
|
-
|
|
69
|
-
### TypeScript Rewrite
|
|
70
|
-
|
|
71
|
-
A full rewrite of the library in TypeScript is a long-term goal. This would bring the benefits of static typing, improved developer tooling, and a more robust codebase.
|
|
72
|
-
|
|
73
|
-
**Benefits:**
|
|
74
|
-
|
|
75
|
-
- **Type Safety:** Catch errors at compile-time instead of runtime.
|
|
76
|
-
- **Improved Autocomplete:** Better editor support and developer experience.
|
|
77
|
-
- **Self-documenting Code:** Types make the code easier to understand and use.
|
|
78
|
-
- **Easier Refactoring:** Static analysis makes it easier to refactor code with confidence.
|
|
79
|
-
|
|
80
|
-
We believe these changes will make `node-firebird` a more robust, modern, and developer-friendly library for accessing Firebird databases.
|