node-firebird 1.1.1 → 1.1.3
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/lib/firebird.msg.json +1371 -0
- package/lib/index.js +158 -147
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var
|
|
|
9
9
|
XdrWriter = serialize.XdrWriter,
|
|
10
10
|
BlrWriter = serialize.BlrWriter,
|
|
11
11
|
BitSet = serialize.BitSet,
|
|
12
|
-
|
|
12
|
+
MessagesError = require('./firebird.msg.json'),
|
|
13
13
|
crypt = require('./unix-crypt.js'),
|
|
14
14
|
path = require('path'),
|
|
15
15
|
srp = require('./srp'),
|
|
@@ -22,97 +22,127 @@ if (typeof(setImmediate) === 'undefined') {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
25
|
+
* Get Error Message per gdscode
|
|
26
|
+
* @param {{gdscode: Number, params: Any[]}[]} status
|
|
27
|
+
* @returns {String} - Error message
|
|
27
28
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
arr[0] = tmp;
|
|
29
|
+
const lookupMessages = (status) => {
|
|
30
|
+
const messages = status.map((item) => {
|
|
31
|
+
let text = MessagesError[item.gdscode];
|
|
32
|
+
if (text === undefined) {
|
|
33
|
+
return 'Unknow error';
|
|
34
|
+
}
|
|
35
|
+
if (item.params !== undefined) {
|
|
36
|
+
item.params.forEach((param, i) => {
|
|
37
|
+
text = text.replace('@' + (i + 1), param);
|
|
38
|
+
});
|
|
39
39
|
}
|
|
40
|
+
return text;
|
|
41
|
+
});
|
|
42
|
+
return messages.join(', ');
|
|
43
|
+
}
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Parse date from string
|
|
47
|
+
* @param {String} str
|
|
48
|
+
* @return {Date}
|
|
49
|
+
*/
|
|
50
|
+
const parseDate = (str) => {
|
|
51
|
+
const self = str.trim();
|
|
52
|
+
const arr = self.indexOf(' ') === -1 ? self.split('T') : self.split(' ');
|
|
53
|
+
let index = arr[0].indexOf(':');
|
|
54
|
+
const length = arr[0].length;
|
|
55
|
+
|
|
56
|
+
if (index !== -1) {
|
|
57
|
+
const tmp = arr[1];
|
|
58
|
+
arr[1] = arr[0];
|
|
59
|
+
arr[0] = tmp;
|
|
60
|
+
}
|
|
43
61
|
|
|
44
|
-
|
|
62
|
+
if (arr[0] === undefined) {
|
|
63
|
+
arr[0] = '';
|
|
64
|
+
}
|
|
45
65
|
|
|
46
|
-
|
|
47
|
-
var c = arr[0].charCodeAt(i);
|
|
48
|
-
if (c > 47 && c < 58)
|
|
49
|
-
continue;
|
|
50
|
-
if (c === 45 || c === 46)
|
|
51
|
-
continue;
|
|
66
|
+
const noTime = arr[1] === undefined || arr[1].length === 0;
|
|
52
67
|
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
for (let i = 0; i < length; i++) {
|
|
69
|
+
const c = arr[0].charCodeAt(i);
|
|
70
|
+
if (c > 47 && c < 58) {
|
|
71
|
+
continue;
|
|
55
72
|
}
|
|
73
|
+
if (c === 45 || c === 46) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (noTime) {
|
|
77
|
+
return new Date(self);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
56
80
|
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
if (arr[1] === undefined) {
|
|
82
|
+
arr[1] = '00:00:00';
|
|
83
|
+
}
|
|
59
84
|
|
|
60
|
-
|
|
85
|
+
const firstDay = arr[0].indexOf('-') === -1;
|
|
61
86
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
var parsed = [];
|
|
87
|
+
const date = (arr[0] || '').split(firstDay ? '.' : '-');
|
|
88
|
+
const time = (arr[1] || '').split(':');
|
|
65
89
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
90
|
+
if (date.length < 4 && time.length < 2) {
|
|
91
|
+
return new Date(self);
|
|
92
|
+
}
|
|
69
93
|
|
|
70
|
-
|
|
94
|
+
index = (time[2] || '').indexOf('.');
|
|
71
95
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
96
|
+
// milliseconds
|
|
97
|
+
if (index !== -1) {
|
|
98
|
+
time[3] = time[2].substring(index + 1);
|
|
99
|
+
time[2] = time[2].substring(0, index);
|
|
100
|
+
} else {
|
|
101
|
+
time[3] = '0';
|
|
102
|
+
}
|
|
79
103
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
const parsed = [
|
|
105
|
+
parseInt(date[firstDay ? 2 : 0], 10), // year
|
|
106
|
+
parseInt(date[1], 10), // month
|
|
107
|
+
parseInt(date[firstDay ? 0 : 2], 10), // day
|
|
108
|
+
parseInt(time[0], 10), // hours
|
|
109
|
+
parseInt(time[1], 10), // minutes
|
|
110
|
+
parseInt(time[2], 10), // seconds
|
|
111
|
+
parseInt(time[3], 10) // miliseconds
|
|
112
|
+
];
|
|
87
113
|
|
|
88
|
-
|
|
114
|
+
const def = new Date();
|
|
89
115
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
117
|
+
if (isNaN(parsed[i])) {
|
|
118
|
+
parsed[i] = 0;
|
|
119
|
+
}
|
|
93
120
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
121
|
+
const value = parsed[i];
|
|
122
|
+
if (value !== 0) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
97
125
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
switch (i) {
|
|
127
|
+
case 0:
|
|
128
|
+
if (value <= 0) {
|
|
129
|
+
parsed[i] = def.getFullYear();
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
case 1:
|
|
133
|
+
if (value <= 0) {
|
|
134
|
+
parsed[i] = def.getMonth() + 1;
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
case 2:
|
|
138
|
+
if (value <= 0) {
|
|
139
|
+
parsed[i] = def.getDate();
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
112
142
|
}
|
|
143
|
+
}
|
|
113
144
|
|
|
114
|
-
|
|
115
|
-
};
|
|
145
|
+
return new Date(parsed[0], parsed[1] - 1, parsed[2], parsed[3], parsed[4], parsed[5]);
|
|
116
146
|
}
|
|
117
147
|
|
|
118
148
|
function noop() {}
|
|
@@ -883,8 +913,12 @@ const
|
|
|
883
913
|
function SQLVarText() {}
|
|
884
914
|
|
|
885
915
|
SQLVarText.prototype.decode = function(data, lowerV13) {
|
|
886
|
-
|
|
916
|
+
let ret;
|
|
887
917
|
if (this.subType > 1) {
|
|
918
|
+
// ToDo: with column charset
|
|
919
|
+
ret = data.readText(this.length, DEFAULT_ENCODING);
|
|
920
|
+
} else if (this.subType === 0) {
|
|
921
|
+
// without charset definition
|
|
888
922
|
ret = data.readText(this.length, DEFAULT_ENCODING);
|
|
889
923
|
} else {
|
|
890
924
|
ret = data.readBuffer(this.length);
|
|
@@ -913,16 +947,21 @@ SQLVarNull.prototype.constructor = SQLVarNull;
|
|
|
913
947
|
function SQLVarString() {}
|
|
914
948
|
|
|
915
949
|
SQLVarString.prototype.decode = function(data, lowerV13) {
|
|
916
|
-
|
|
950
|
+
let ret;
|
|
917
951
|
if (this.subType > 1) {
|
|
918
|
-
|
|
952
|
+
// ToDo: with column charset
|
|
953
|
+
ret = data.readString(DEFAULT_ENCODING);
|
|
954
|
+
} else if (this.subType === 0) {
|
|
955
|
+
// without charset definition
|
|
956
|
+
ret = data.readString(DEFAULT_ENCODING);
|
|
919
957
|
} else {
|
|
920
|
-
ret = data.readBuffer()
|
|
958
|
+
ret = data.readBuffer();
|
|
921
959
|
}
|
|
922
960
|
|
|
923
961
|
if (!lowerV13 || !data.readInt()) {
|
|
924
962
|
return ret;
|
|
925
963
|
}
|
|
964
|
+
|
|
926
965
|
return null;
|
|
927
966
|
};
|
|
928
967
|
|
|
@@ -3095,11 +3134,8 @@ exports.Connection.prototype._bind_events = function(host, port, callback) {
|
|
|
3095
3134
|
self._pending.shift();
|
|
3096
3135
|
|
|
3097
3136
|
if (obj && obj.status) {
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
doCallback(obj, cb);
|
|
3101
|
-
});
|
|
3102
|
-
|
|
3137
|
+
obj.message = lookupMessages(obj.status);
|
|
3138
|
+
doCallback(obj, cb);
|
|
3103
3139
|
} else {
|
|
3104
3140
|
doCallback(obj, cb);
|
|
3105
3141
|
}
|
|
@@ -3194,81 +3230,60 @@ function decodeResponse(data, callback, cnx, lowercase_keys, cb) {
|
|
|
3194
3230
|
data.frows = data.frows || [];
|
|
3195
3231
|
|
|
3196
3232
|
if (custom.asObject && !data.fcols) {
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3233
|
+
if (lowercase_keys) {
|
|
3234
|
+
data.fcols = output.map((column) => column.alias.toLowerCase());
|
|
3235
|
+
} else {
|
|
3236
|
+
data.fcols = output.map((column) => column.alias);
|
|
3200
3237
|
}
|
|
3201
3238
|
}
|
|
3202
3239
|
|
|
3203
3240
|
const arrBlob = [];
|
|
3241
|
+
const lowerV13 = statement.connection.accept.protocolVersion < PROTOCOL_VERSION13;
|
|
3204
3242
|
|
|
3205
3243
|
while (data.fcount && (data.fstatus !== 100)) {
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
} else {
|
|
3222
|
-
value = fetch_blob_async(statement, value, key, row);
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
-
data.frow[key] = value;
|
|
3226
|
-
} catch (e) {
|
|
3227
|
-
// uncomplete packet read
|
|
3228
|
-
data.pos = _xdrpos;
|
|
3229
|
-
data.r = r;
|
|
3230
|
-
return cb(new Error("Packet is not complete"));
|
|
3244
|
+
let nullBitSet;
|
|
3245
|
+
if (!lowerV13) {
|
|
3246
|
+
const nullBitsLen = Math.floor((output.length + 7) / 8);
|
|
3247
|
+
nullBitSet = new BitSet(data.readBuffer(nullBitsLen, false));
|
|
3248
|
+
data.readBuffer((4 - nullBitsLen) & 3, false); // Skip padding
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
for (length = output.length; data.fcolumn < length; data.fcolumn++) {
|
|
3252
|
+
item = output[data.fcolumn];
|
|
3253
|
+
|
|
3254
|
+
if (!lowerV13 && nullBitSet.get(data.fcolumn)) {
|
|
3255
|
+
if (custom.asObject) {
|
|
3256
|
+
data.frow[data.fcols[data.fcolumn]] = null;
|
|
3257
|
+
} else {
|
|
3258
|
+
data.frow[data.fcolumn] = null;
|
|
3231
3259
|
}
|
|
3232
3260
|
|
|
3261
|
+
continue;
|
|
3233
3262
|
}
|
|
3234
|
-
} else {
|
|
3235
|
-
var nullBitsLen = Math.floor((output.length + 7) / 8);
|
|
3236
|
-
var nullBitSet = new BitSet(data.readBuffer(nullBitsLen, false));
|
|
3237
|
-
data.readBuffer((4 - nullBitsLen) & 3, false); // Skip padding
|
|
3238
3263
|
|
|
3239
|
-
|
|
3240
|
-
|
|
3264
|
+
try {
|
|
3265
|
+
_xdrpos = data.pos;
|
|
3266
|
+
const key = custom.asObject ? data.fcols[data.fcolumn] : data.fcolumn;
|
|
3267
|
+
const row = data.frows.length;
|
|
3268
|
+
let value = item.decode(data, lowerV13);
|
|
3241
3269
|
|
|
3242
|
-
if (
|
|
3243
|
-
if (
|
|
3244
|
-
|
|
3270
|
+
if (item.type === SQL_BLOB && value !== null) {
|
|
3271
|
+
if (item.subType === isc_blob_text && cnx.options.blobAsText) {
|
|
3272
|
+
value = fetch_blob_async_transaction(statement, value, key, row);
|
|
3273
|
+
arrBlob.push(value);
|
|
3245
3274
|
} else {
|
|
3246
|
-
|
|
3275
|
+
value = fetch_blob_async(statement, value, key, row);
|
|
3247
3276
|
}
|
|
3248
|
-
|
|
3249
|
-
continue;
|
|
3250
3277
|
}
|
|
3251
3278
|
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
value = fetch_blob_async_transaction(statement, value, key, data);
|
|
3259
|
-
arrBlob.push(value);
|
|
3260
|
-
} else {
|
|
3261
|
-
value = fetch_blob_async(statement, value, key);
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
data.frow[key] = value;
|
|
3265
|
-
} catch (e) {
|
|
3266
|
-
// uncomplete packet read
|
|
3267
|
-
data.pos = _xdrpos;
|
|
3268
|
-
data.r = r;
|
|
3269
|
-
return cb(new Error("Packet is not complete"));
|
|
3270
|
-
}
|
|
3279
|
+
data.frow[key] = value;
|
|
3280
|
+
} catch (e) {
|
|
3281
|
+
// uncomplete packet read
|
|
3282
|
+
data.pos = _xdrpos;
|
|
3283
|
+
data.r = r;
|
|
3284
|
+
return cb(new Error('Packet is not complete'));
|
|
3271
3285
|
}
|
|
3286
|
+
|
|
3272
3287
|
}
|
|
3273
3288
|
|
|
3274
3289
|
data.fcolumn = 0;
|
|
@@ -4297,7 +4312,7 @@ Connection.prototype.executeStatement = function(transaction, statement, params,
|
|
|
4297
4312
|
if (value instanceof Date)
|
|
4298
4313
|
ret[i] = new SQLParamDate(value);
|
|
4299
4314
|
else if (typeof(value) === 'string')
|
|
4300
|
-
ret[i] = new SQLParamDate(
|
|
4315
|
+
ret[i] = new SQLParamDate(parseDate(value));
|
|
4301
4316
|
else
|
|
4302
4317
|
ret[i] = new SQLParamDate(new Date(value));
|
|
4303
4318
|
|
|
@@ -4430,12 +4445,8 @@ Connection.prototype.sendExecute = function (op, statement, transaction, callbac
|
|
|
4430
4445
|
this._queueEvent(callback);
|
|
4431
4446
|
}
|
|
4432
4447
|
|
|
4433
|
-
function fetch_blob_async_transaction(statement, id,
|
|
4434
|
-
const infoValue = {
|
|
4435
|
-
row,
|
|
4436
|
-
column: name,
|
|
4437
|
-
value: ''
|
|
4438
|
-
};
|
|
4448
|
+
function fetch_blob_async_transaction(statement, id, column, row) {
|
|
4449
|
+
const infoValue = { row, column, value: '' };
|
|
4439
4450
|
|
|
4440
4451
|
return (transactionArg) => {
|
|
4441
4452
|
const singleTransaction = transactionArg === undefined;
|