node-firebird 1.1.10 → 2.0.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/lib/wire/const.js CHANGED
@@ -180,6 +180,12 @@ const protocol = {
180
180
 
181
181
  // Protocol 13 has support for authentication plugins (op_cont_auth).
182
182
  PROTOCOL_VERSION13 : (FB_PROTOCOL_FLAG | 13),
183
+
184
+ // Protocol 14 has support for wire encryption.
185
+ PROTOCOL_VERSION14 : (FB_PROTOCOL_FLAG | 14),
186
+
187
+ // Protocol 15 has support for conditional accept with early wire encryption.
188
+ PROTOCOL_VERSION15 : (FB_PROTOCOL_FLAG | 15),
183
189
  };
184
190
 
185
191
  // Protocols types (accept_type)
@@ -197,19 +203,19 @@ const SUPPORTED_PROTOCOL = [
197
203
  [protocol.PROTOCOL_VERSION11, connect.ARCHITECTURE_GENERIC, acceptType.ptype_lazy_send, acceptType.ptype_lazy_send, 2],
198
204
  [protocol.PROTOCOL_VERSION12, connect.ARCHITECTURE_GENERIC, acceptType.ptype_lazy_send, acceptType.ptype_lazy_send, 3],
199
205
  [protocol.PROTOCOL_VERSION13, connect.ARCHITECTURE_GENERIC, acceptType.ptype_lazy_send, acceptType.ptype_lazy_send, 4],
206
+ [protocol.PROTOCOL_VERSION14, connect.ARCHITECTURE_GENERIC, acceptType.ptype_lazy_send, acceptType.ptype_lazy_send, 5],
207
+ [protocol.PROTOCOL_VERSION15, connect.ARCHITECTURE_GENERIC, acceptType.ptype_lazy_send, acceptType.ptype_lazy_send, 6],
200
208
  ];
201
209
 
202
210
  const authPlugin = {
203
211
  AUTH_PLUGIN_LEGACY : 'Legacy_Auth',
204
212
  AUTH_PLUGIN_SRP : 'Srp',
205
- // AUTH_PLUGIN_SRP256 : 'Srp256',
213
+ AUTH_PLUGIN_SRP256 : 'Srp256',
206
214
  };
207
215
 
208
216
  const authOptions = {
209
- // AUTH_PLUGIN_LIST : [authPlugin.AUTH_PLUGIN_SRP256, authPlugin.AUTH_PLUGIN_SRP, authPlugin.AUTH_PLUGIN_LEGACY],
210
- AUTH_PLUGIN_LIST : [authPlugin.AUTH_PLUGIN_SRP, authPlugin.AUTH_PLUGIN_LEGACY],
211
- // AUTH_PLUGIN_SRP_LIST : [authPlugin.AUTH_PLUGIN_SRP256, authPlugin.AUTH_PLUGIN_SRP],
212
- AUTH_PLUGIN_SRP_LIST : [authPlugin.AUTH_PLUGIN_SRP],
217
+ AUTH_PLUGIN_LIST : [authPlugin.AUTH_PLUGIN_SRP256, authPlugin.AUTH_PLUGIN_SRP, authPlugin.AUTH_PLUGIN_LEGACY],
218
+ AUTH_PLUGIN_SRP_LIST : [authPlugin.AUTH_PLUGIN_SRP256, authPlugin.AUTH_PLUGIN_SRP],
213
219
  LEGACY_AUTH_SALT : '9z',
214
220
  WIRE_CRYPT_DISABLE : 0,
215
221
  WIRE_CRYPT_ENABLE : 1,
@@ -1,6 +1,7 @@
1
1
  const Events = require('events');
2
2
  const { doError } = require('../callback');
3
3
  const { escape } = require('../utils');
4
+ const Const = require('./const');
4
5
  const EventConnection = require('./eventConnection');
5
6
  const FbEventManager = require('./fbEventManager');
6
7
 
@@ -10,189 +11,294 @@ const FbEventManager = require('./fbEventManager');
10
11
  *
11
12
  ***************************************/
12
13
 
13
- function Database(connection) {
14
- this.connection = connection;
15
- connection.db = this;
16
- this.eventid = 1;
17
- }
14
+ function readblob(blob, callback) {
15
+ if (blob === undefined || blob === null) {
16
+ callback(null, blob);
17
+ return;
18
+ }
18
19
 
19
- Database.prototype.__proto__ = Object.create(Events.EventEmitter.prototype, {
20
- constructor: {
21
- value: Database,
22
- enumberable: false
20
+ if (typeof blob !== 'function') {
21
+ callback(null, blob);
22
+ return;
23
23
  }
24
- });
25
24
 
26
- Database.prototype.escape = function(value) {
27
- return escape(value, this.connection.accept.protocolVersion);
28
- };
25
+ blob(function(err, name, e) {
26
+ if (err) {
27
+ callback(err);
28
+ return;
29
+ }
29
30
 
30
- Database.prototype.detach = function(callback, force) {
31
+ if (!e) {
32
+ callback(null, null);
33
+ return;
34
+ }
31
35
 
32
- var self = this;
36
+ const chunks = [];
37
+ let chunksLength = 0;
33
38
 
34
- if (!force && self.connection._pending.length > 0) {
35
- self.connection._detachAuto = true;
36
- self.connection._detachCallback = callback;
37
- return self;
39
+ e.on('data', function(chunk) {
40
+ chunksLength += chunk.length;
41
+ chunks.push(chunk);
42
+ });
43
+
44
+ e.on('end', function() {
45
+ callback(null, Buffer.concat(chunks, chunksLength));
46
+ });
47
+
48
+ e.on('error', function(streamErr) {
49
+ callback(streamErr);
50
+ });
51
+ });
52
+ }
53
+
54
+ function fetchBlobSyncRow(row, meta, callback) {
55
+ if (!row || !meta || !meta.length) {
56
+ callback(null, row);
57
+ return;
38
58
  }
39
59
 
40
- if (self.connection._pooled === false) {
41
- self.connection.detach(function (err, obj) {
60
+ const rowKeys = Object.keys(row);
61
+ const blobColumns = [];
42
62
 
43
- self.connection.disconnect();
44
- self.emit('detach', false);
63
+ for (let i = 0; i < meta.length; i++) {
64
+ if (meta[i] && meta[i].type === Const.SQL_BLOB && rowKeys[i] !== undefined) {
65
+ blobColumns.push(rowKeys[i]);
66
+ }
67
+ }
45
68
 
46
- if (callback)
47
- callback(err, obj);
69
+ if (!blobColumns.length) {
70
+ callback(null, row);
71
+ return;
72
+ }
48
73
 
49
- }, force);
50
- } else {
51
- self.emit('detach', false);
52
- if (callback)
53
- callback();
74
+ let pending = blobColumns.length;
75
+ let blobErr;
76
+
77
+ blobColumns.forEach(function(columnName) {
78
+ readblob(row[columnName], function(err, data) {
79
+ if (err && !blobErr) {
80
+ blobErr = err;
81
+ }
82
+ row[columnName] = data;
83
+ pending--;
84
+ if (pending === 0) {
85
+ callback(blobErr, row);
86
+ }
87
+ });
88
+ });
89
+ }
90
+
91
+ class Database extends Events.EventEmitter {
92
+ constructor(connection) {
93
+ super();
94
+ this.connection = connection;
95
+ connection.db = this;
96
+ this.eventid = 1;
97
+ }
98
+
99
+ escape(value) {
100
+ return escape(value, this.connection.accept.protocolVersion);
54
101
  }
55
102
 
56
- return self;
57
- };
103
+ detach(callback, force) {
104
+ var self = this;
58
105
 
59
- Database.prototype.transaction = function(options, callback) {
60
- return this.startTransaction(options, callback);
61
- };
106
+ if (!force && self.connection._pending.length > 0) {
107
+ self.connection._detachAuto = true;
108
+ self.connection._detachCallback = callback;
109
+ return self;
110
+ }
62
111
 
63
- Database.prototype.startTransaction = function(options, callback) {
64
- this.connection.startTransaction(options, callback);
65
- return this;
66
- };
112
+ if (self.connection._pooled === false) {
113
+ self.connection.detach(function (err, obj) {
67
114
 
68
- Database.prototype.newStatement = function (query, callback) {
115
+ self.connection.disconnect();
116
+ self.emit('detach', false);
69
117
 
70
- this.startTransaction(function(err, transaction) {
118
+ if (callback)
119
+ callback(err, obj);
71
120
 
72
- if (err) {
73
- callback(err);
74
- return;
121
+ }, force);
122
+ } else {
123
+ self.emit('detach', false);
124
+ if (callback)
125
+ callback();
75
126
  }
76
127
 
77
- transaction.newStatement(query, function(err, statement) {
128
+ return self;
129
+ }
130
+
131
+ transaction(options, callback) {
132
+ return this.startTransaction(options, callback);
133
+ }
134
+
135
+ startTransaction(options, callback) {
136
+ this.connection.startTransaction(options, callback);
137
+ return this;
138
+ }
139
+
140
+ newStatement(query, callback) {
141
+ this.startTransaction(function(err, transaction) {
78
142
 
79
143
  if (err) {
80
144
  callback(err);
81
145
  return;
82
146
  }
83
147
 
84
- transaction.commit(function(err) {
85
- callback(err, statement);
86
- });
87
- });
88
- });
148
+ transaction.newStatement(query, function(err, statement) {
89
149
 
90
- return this;
91
- };
150
+ if (err) {
151
+ callback(err);
152
+ return;
153
+ }
92
154
 
93
- Database.prototype.execute = function(query, params, callback, custom) {
155
+ transaction.commit(function(err) {
156
+ callback(err, statement);
157
+ });
158
+ });
159
+ });
94
160
 
95
- if (params instanceof Function) {
96
- custom = callback;
97
- callback = params;
98
- params = undefined;
161
+ return this;
99
162
  }
100
163
 
101
- var self = this;
102
-
103
- self.connection.startTransaction(function(err, transaction) {
104
-
105
- if (err) {
106
- doError(err, callback);
107
- return;
164
+ execute(query, params, callback, custom) {
165
+ if (params instanceof Function) {
166
+ custom = callback;
167
+ callback = params;
168
+ params = undefined;
108
169
  }
109
170
 
110
- transaction.execute(query, params, function(err, result, meta, isSelect) {
171
+ var self = this;
172
+
173
+ self.connection.startTransaction(function(err, transaction) {
111
174
 
112
175
  if (err) {
113
- transaction.rollback(function() {
114
- doError(err, callback);
115
- });
176
+ doError(err, callback);
116
177
  return;
117
178
  }
118
179
 
119
- transaction.commit(function(err) {
120
- if (callback)
121
- callback(err, result, meta, isSelect);
122
- });
180
+ transaction.execute(query, params, function(err, result, meta, isSelect) {
123
181
 
124
- }, custom);
125
- });
182
+ if (err) {
183
+ transaction.rollback(function() {
184
+ doError(err, callback);
185
+ });
186
+ return;
187
+ }
126
188
 
127
- return self;
128
- };
189
+ transaction.commit(function(err) {
190
+ if (callback)
191
+ callback(err, result, meta, isSelect);
192
+ });
129
193
 
130
- Database.prototype.sequentially = function(query, params, on, callback, asArray) {
194
+ }, custom);
195
+ });
131
196
 
132
- if (params instanceof Function) {
133
- asArray = callback;
134
- callback = on;
135
- on = params;
136
- params = undefined;
197
+ return self;
137
198
  }
138
199
 
139
- if (on === undefined){
140
- throw new Error('Expected "on" delegate.');
141
- }
200
+ sequentially(query, params, on, callback, asArray) {
201
+ if (params instanceof Function) {
202
+ asArray = callback;
203
+ callback = on;
204
+ on = params;
205
+ params = undefined;
206
+ }
142
207
 
143
- if (callback instanceof Boolean) {
144
- asArray = callback;
145
- callback = undefined;
146
- }
208
+ if (on === undefined){
209
+ throw new Error('Expected "on" delegate.');
210
+ }
211
+
212
+ if (callback instanceof Boolean) {
213
+ asArray = callback;
214
+ callback = undefined;
215
+ }
216
+
217
+ var self = this;
218
+ var _on = function(row, i, meta, next) {
219
+ var done = false;
220
+ var finish = function(err) {
221
+ if (done) {
222
+ return;
223
+ }
224
+ done = true;
225
+ next(err);
226
+ };
147
227
 
148
- var self = this;
149
- self.execute(query, params, callback, { asObject: !asArray, asStream: true, on: on });
150
- return self;
151
- };
228
+ fetchBlobSyncRow(row, meta, function(blobErr) {
229
+ if (blobErr) {
230
+ finish(blobErr);
231
+ return;
232
+ }
152
233
 
153
- Database.prototype.query = function(query, params, callback) {
234
+ try {
235
+ var ret;
236
+ if (on.length >= 3) {
237
+ ret = on(row, i, finish);
238
+ } else {
239
+ ret = on(row, i);
240
+ }
241
+
242
+ if (ret && typeof ret.then === 'function') {
243
+ ret.then(function() {
244
+ finish();
245
+ }).catch(finish);
246
+ } else if (on.length < 3) {
247
+ finish();
248
+ }
249
+ } catch (err) {
250
+ finish(err);
251
+ }
252
+ });
253
+ };
154
254
 
155
- if (params instanceof Function) {
156
- callback = params;
157
- params = undefined;
255
+ self.execute(query, params, callback, { asObject: !asArray, asStream: true, on: _on });
256
+ return self;
158
257
  }
159
258
 
160
- var self = this;
161
- self.execute(query, params, callback, { asObject: true, asStream: callback === undefined || callback === null });
162
- return self;
163
- };
259
+ query(query, params, callback) {
260
+ if (params instanceof Function) {
261
+ callback = params;
262
+ params = undefined;
263
+ }
164
264
 
165
- Database.prototype.drop = function(callback) {
166
- return this.connection.dropDatabase(callback);
167
- };
265
+ var self = this;
266
+ self.execute(query, params, callback, { asObject: true, asStream: callback === undefined || callback === null });
267
+ return self;
268
+ }
168
269
 
169
- Database.prototype.attachEvent = function (callback) {
170
- var self = this;
171
- this.connection.auxConnection(function (err, socket_info) {
270
+ drop(callback) {
271
+ return this.connection.dropDatabase(callback);
272
+ }
172
273
 
173
- if (err) {
174
- doError(err, callback);
175
- return;
176
- }
274
+ attachEvent(callback) {
275
+ var self = this;
276
+ this.connection.auxConnection(function (err, socket_info) {
177
277
 
178
- const eventConnection = new EventConnection(self.connection.host, socket_info.port, function (err) {
179
278
  if (err) {
180
279
  doError(err, callback);
181
280
  return;
182
281
  }
183
282
 
184
- const evt = new FbEventManager(self, eventConnection, self.eventid++, function (err) {
283
+ const eventConnection = new EventConnection(socket_info.host, socket_info.port, function (err) {
185
284
  if (err) {
186
285
  doError(err, callback);
187
286
  return;
188
287
  }
189
288
 
190
- callback(err, evt);
191
- });
192
- }, self);
193
- });
289
+ const evt = new FbEventManager(self, eventConnection, self.eventid++, function (err) {
290
+ if (err) {
291
+ doError(err, callback);
292
+ return;
293
+ }
294
+
295
+ callback(err, evt);
296
+ });
297
+ }, self);
298
+ });
194
299
 
195
- return this;
300
+ return this;
301
+ }
196
302
  }
197
303
 
198
304
  module.exports = Database;
@@ -3,111 +3,113 @@ const { XdrReader } = require('./serialize');
3
3
  const DEFAULT_ENCODING = 'utf8';
4
4
  const Const = require('./const');
5
5
 
6
- var EventConnection = function (host, port, callback, db) {
7
- var self = this;
8
- this.db = db;
9
- this.emgr = null;
10
- this._isClosed = false;
11
- this._isOpened = false;
12
- this._socket = net.createConnection(port, host);
13
- this._bind_events(host, port, callback);
14
- this.error;
15
- this.eventcallback;
16
- };
6
+ class EventConnection {
7
+ constructor(host, port, callback, db) {
8
+ var self = this;
9
+ this.db = db;
10
+ this.emgr = null;
11
+ this._isClosed = false;
12
+ this._isOpened = false;
13
+ this._socket = net.createConnection(port, host);
14
+ this._bind_events(host, port, callback);
15
+ this.error;
16
+ this.eventcallback;
17
+ }
17
18
 
18
- EventConnection.prototype._bind_events = function (host, port, callback) {
19
- var self = this;
19
+ _bind_events(host, port, callback) {
20
+ var self = this;
20
21
 
21
- self._socket.on('close', function () {
22
+ self._socket.on('close', function () {
22
23
 
23
- self._isClosed = true;
24
- })
24
+ self._isClosed = true;
25
+ })
25
26
 
26
- self._socket.on('error', function (e) {
27
+ self._socket.on('error', function (e) {
27
28
 
28
- self.error = e;
29
- })
29
+ self.error = e;
30
+ })
30
31
 
31
- self._socket.on('connect', function () {
32
- self._isClosed = false;
33
- self._isOpened = true;
34
- if (callback)
35
- callback();
36
- });
32
+ self._socket.on('connect', function () {
33
+ self._isClosed = false;
34
+ self._isOpened = true;
35
+ if (callback)
36
+ callback();
37
+ });
37
38
 
38
- self._socket.on('data', function (data) {
39
- var xdr, buf;
39
+ self._socket.on('data', function (data) {
40
+ var xdr, buf;
40
41
 
41
- if (!self._xdr) {
42
- xdr = new XdrReader(data);
43
- } else {
44
- xdr = self._xdr;
45
- delete (self._xdr);
46
- buf = Buffer.from(data.length + xdr.buffer.length);
47
- xdr.buffer.copy(buf);
48
- data.copy(buf, xdr.buffer.length);
49
- xdr.buffer = buf;
50
- }
42
+ if (!self._xdr) {
43
+ xdr = new XdrReader(data);
44
+ } else {
45
+ xdr = self._xdr;
46
+ delete (self._xdr);
47
+ buf = Buffer.from(data.length + xdr.buffer.length);
48
+ xdr.buffer.copy(buf);
49
+ data.copy(buf, xdr.buffer.length);
50
+ xdr.buffer = buf;
51
+ }
51
52
 
52
- try {
53
- var item, op;
54
- var op_pos = xdr.pos;
55
- var tmp_event;
56
- while (xdr.pos < xdr.buffer.length) {
57
- do {
58
- var r = xdr.readInt();
59
- } while (r === Const.op_dummy);
53
+ try {
54
+ var item, op;
55
+ var op_pos = xdr.pos;
56
+ var tmp_event;
57
+ while (xdr.pos < xdr.buffer.length) {
58
+ do {
59
+ var r = xdr.readInt();
60
+ } while (r === Const.op_dummy);
60
61
 
61
- switch (r) {
62
- case Const.op_event:
63
- xdr.readInt(); // db handle
64
- var buf = xdr.readArray();
65
- // first byte is always set to 1
66
- tmp_event = {};
67
- var lst_event = [];
68
- var eventname = '';
69
- var eventcount = 0;
70
- var pos = 1;
71
- while (pos < buf.length) {
72
- var len = buf.readInt8(pos++);
73
- eventname = buf.toString(DEFAULT_ENCODING, pos, pos + len);
74
- var prevcount = self.emgr.events[eventname] || 0;
75
- pos += len;
76
- eventcount = buf.readInt32LE(pos);
77
- tmp_event[eventname] = eventcount;
78
- pos += 4;
79
- if (prevcount !== eventcount)
80
- lst_event.push({ name: eventname, count: eventcount });
81
- }
82
- xdr.readInt64(); // ignore AST INFO
83
- var event_id = xdr.readInt();
84
- // set the new count in global event hash
85
- for (var evt in tmp_event) {
86
- self.emgr.events[evt] = tmp_event[evt];
87
- }
88
- if (self.eventcallback)
89
- return self.eventcallback(null, { eventid: event_id, events: lst_event });
62
+ switch (r) {
63
+ case Const.op_event:
64
+ xdr.readInt(); // db handle
65
+ var buf = xdr.readArray();
66
+ // first byte is always set to 1
67
+ tmp_event = {};
68
+ var lst_event = [];
69
+ var eventname = '';
70
+ var eventcount = 0;
71
+ var pos = 1;
72
+ while (pos < buf.length) {
73
+ var len = buf.readInt8(pos++);
74
+ eventname = buf.toString(DEFAULT_ENCODING, pos, pos + len);
75
+ var prevcount = self.emgr.events[eventname] || 0;
76
+ pos += len;
77
+ eventcount = buf.readInt32LE(pos);
78
+ tmp_event[eventname] = eventcount;
79
+ pos += 4;
80
+ if (prevcount !== eventcount)
81
+ lst_event.push({ name: eventname, count: eventcount });
82
+ }
83
+ xdr.readInt64(); // ignore AST INFO
84
+ var event_id = xdr.readInt();
85
+ // set the new count in global event hash
86
+ for (var evt in tmp_event) {
87
+ self.emgr.events[evt] = tmp_event[evt];
88
+ }
89
+ if (self.eventcallback)
90
+ return self.eventcallback(null, { eventid: event_id, events: lst_event });
90
91
 
91
- default:
92
- return cb(new Error('Unexpected:' + r));
92
+ default:
93
+ return cb(new Error('Unexpected:' + r));
94
+ }
95
+ }
96
+ } catch (err) {
97
+ if (err instanceof RangeError) { // incomplete packet case
98
+ xdr.buffer = xdr.buffer = xdr.buffer.slice(op_pos);
99
+ xdr.pos = 0;
100
+ self._xdr = xdr;
93
101
  }
94
102
  }
95
- } catch (err) {
96
- if (err instanceof RangeError) { // incomplete packet case
97
- xdr.buffer = xdr.buffer = xdr.buffer.slice(op_pos);
98
- xdr.pos = 0;
99
- self._xdr = xdr;
100
- }
101
- }
102
- })
103
- }
103
+ })
104
+ }
104
105
 
105
- EventConnection.prototype.throwClosed = function (callback) {
106
- var err = new Error('Event Connection is closed.');
107
- this.db.emit('error', err);
108
- if (callback)
109
- callback(err);
110
- return this;
111
- };
106
+ throwClosed(callback) {
107
+ var err = new Error('Event Connection is closed.');
108
+ this.db.emit('error', err);
109
+ if (callback)
110
+ callback(err);
111
+ return this;
112
+ }
113
+ }
112
114
 
113
115
  module.exports = EventConnection;