tedious 1.12.3 → 1.14.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 +1 -1
- package/appveyor.yml +9 -5
- package/benchmarks/README.md +33 -0
- package/benchmarks/common.js +82 -0
- package/benchmarks/index.js +34 -0
- package/benchmarks/query/many-result-rows.js +49 -0
- package/benchmarks/query/nvarchar-large.js +44 -0
- package/benchmarks/query/nvarchar-small.js +44 -0
- package/benchmarks/query/varbinary-4.js +42 -0
- package/benchmarks/query/varbinary-huge.js +46 -0
- package/benchmarks/query/varbinary-large.js +46 -0
- package/benchmarks/query/varbinary-small.js +42 -0
- package/benchmarks/token-parser/colmetadata-token.js +42 -0
- package/benchmarks/token-parser/done-token.js +42 -0
- package/benchmarks/token-parser/simple-tokens.js +366 -0
- package/lib/all-headers.js +9 -11
- package/lib/buffertools.js +17 -13
- package/lib/bulk-load.js +196 -169
- package/lib/collation.js +80 -2
- package/lib/connection.js +1086 -1060
- package/lib/data-type.js +450 -253
- package/lib/debug.js +57 -51
- package/lib/errors.js +40 -55
- package/lib/guid-parser.js +12 -36
- package/lib/instance-lookup.js +57 -54
- package/lib/library.js +3 -2
- package/lib/login7-payload.js +187 -180
- package/lib/message-io.js +169 -199
- package/lib/metadata-parser.js +169 -255
- package/lib/ntlm-payload.js +173 -160
- package/lib/packet.js +166 -152
- package/lib/prelogin-payload.js +170 -160
- package/lib/request.js +122 -122
- package/lib/rpcrequest-payload.js +64 -38
- package/lib/special-stored-procedure.js +3 -2
- package/lib/sqlbatch-payload.js +20 -16
- package/lib/stream-parser.js +116 -104
- package/lib/tds-versions.js +5 -8
- package/lib/tedious.js +8 -14
- package/lib/token/colmetadata-token-parser.js +79 -125
- package/lib/token/done-token-parser.js +47 -129
- package/lib/token/env-change-token-parser.js +90 -126
- package/lib/token/infoerror-token-parser.js +47 -125
- package/lib/token/loginack-token-parser.js +36 -74
- package/lib/token/nbcrow-token-parser.js +40 -64
- package/lib/token/order-token-parser.js +26 -43
- package/lib/token/returnstatus-token-parser.js +11 -23
- package/lib/token/returnvalue-token-parser.js +31 -54
- package/lib/token/row-token-parser.js +39 -52
- package/lib/token/sspi-token-parser.js +14 -32
- package/lib/token/stream-parser.js +424 -304
- package/lib/token/token-stream-parser.js +39 -34
- package/lib/token/token.js +3 -6
- package/lib/tracking-buffer/bigint.js +45 -48
- package/lib/tracking-buffer/readable-tracking-buffer.js +238 -223
- package/lib/tracking-buffer/tracking-buffer.js +3 -9
- package/lib/tracking-buffer/writable-tracking-buffer.js +272 -244
- package/lib/transaction.js +112 -102
- package/lib/value-parser.js +559 -1154
- package/package.json +10 -9
- package/benchmarks/benchmarks.coffee +0 -122
- package/benchmarks/query.coffee +0 -57
package/lib/message-io.js
CHANGED
|
@@ -1,235 +1,205 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// Generated by CoffeeScript 1.10.0
|
|
4
|
-
var EventEmitter,
|
|
5
|
-
MessageIO,
|
|
6
|
-
Packet,
|
|
7
|
-
ReadablePacketStream,
|
|
8
|
-
StreamParser,
|
|
9
|
-
TYPE,
|
|
10
|
-
crypto,
|
|
11
|
-
isPacketComplete,
|
|
12
|
-
packetHeaderLength,
|
|
13
|
-
packetLength,
|
|
14
|
-
tls,
|
|
15
|
-
extend = function (child, parent) {
|
|
16
|
-
for (var key in parent) {
|
|
17
|
-
if (hasProp.call(parent, key)) child[key] = parent[key];
|
|
18
|
-
}function ctor() {
|
|
19
|
-
this.constructor = child;
|
|
20
|
-
}ctor.prototype = parent.prototype;child.prototype = new ctor();child.__super__ = parent.prototype;return child;
|
|
21
|
-
},
|
|
22
|
-
hasProp = ({}).hasOwnProperty,
|
|
23
|
-
bind = function (fn, me) {
|
|
24
|
-
return function () {
|
|
25
|
-
return fn.apply(me, arguments);
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
tls = require('tls');
|
|
30
|
-
|
|
31
|
-
crypto = require('crypto');
|
|
1
|
+
'use strict';
|
|
32
2
|
|
|
33
|
-
require('
|
|
34
|
-
|
|
35
|
-
EventEmitter = require('events').EventEmitter;
|
|
3
|
+
var _get = require('babel-runtime/helpers/get')['default'];
|
|
36
4
|
|
|
37
|
-
|
|
5
|
+
var _inherits = require('babel-runtime/helpers/inherits')['default'];
|
|
38
6
|
|
|
39
|
-
|
|
7
|
+
var _createClass = require('babel-runtime/helpers/create-class')['default'];
|
|
40
8
|
|
|
41
|
-
|
|
9
|
+
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
|
|
42
10
|
|
|
43
|
-
|
|
11
|
+
var tls = require('tls');
|
|
12
|
+
var crypto = require('crypto');
|
|
13
|
+
var EventEmitter = require('events').EventEmitter;
|
|
14
|
+
var Transform = require('readable-stream').Transform;
|
|
44
15
|
|
|
45
|
-
|
|
16
|
+
require('./buffertools');
|
|
46
17
|
|
|
47
|
-
|
|
18
|
+
var Packet = require('./packet').Packet;
|
|
19
|
+
var TYPE = require('./packet').TYPE;
|
|
20
|
+
var packetHeaderLength = require('./packet').HEADER_LENGTH;
|
|
48
21
|
|
|
49
|
-
ReadablePacketStream = (function (
|
|
50
|
-
|
|
22
|
+
var ReadablePacketStream = (function (_Transform) {
|
|
23
|
+
_inherits(ReadablePacketStream, _Transform);
|
|
51
24
|
|
|
52
25
|
function ReadablePacketStream() {
|
|
53
|
-
|
|
26
|
+
_classCallCheck(this, ReadablePacketStream);
|
|
27
|
+
|
|
28
|
+
_get(Object.getPrototypeOf(ReadablePacketStream.prototype), 'constructor', this).call(this, { objectMode: true });
|
|
29
|
+
|
|
30
|
+
this.buffer = new Buffer(0);
|
|
31
|
+
this.position = 0;
|
|
54
32
|
}
|
|
55
33
|
|
|
56
|
-
ReadablePacketStream
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
type = context$2$0.sent;
|
|
71
|
-
context$2$0.next = 6;
|
|
72
|
-
return this.readUInt8();
|
|
73
|
-
|
|
74
|
-
case 6:
|
|
75
|
-
status = context$2$0.sent;
|
|
76
|
-
context$2$0.next = 9;
|
|
77
|
-
return this.readUInt16BE();
|
|
78
|
-
|
|
79
|
-
case 9:
|
|
80
|
-
length = context$2$0.sent;
|
|
81
|
-
context$2$0.next = 12;
|
|
82
|
-
return this.readUInt16BE();
|
|
83
|
-
|
|
84
|
-
case 12:
|
|
85
|
-
spid = context$2$0.sent;
|
|
86
|
-
context$2$0.next = 15;
|
|
87
|
-
return this.readUInt8();
|
|
88
|
-
|
|
89
|
-
case 15:
|
|
90
|
-
packetId = context$2$0.sent;
|
|
91
|
-
context$2$0.next = 18;
|
|
92
|
-
return this.readUInt8();
|
|
93
|
-
|
|
94
|
-
case 18:
|
|
95
|
-
window = context$2$0.sent;
|
|
96
|
-
context$2$0.next = 21;
|
|
97
|
-
return this.readBuffer(length - packetHeaderLength);
|
|
98
|
-
|
|
99
|
-
case 21:
|
|
100
|
-
data = context$2$0.sent;
|
|
101
|
-
|
|
102
|
-
this.push({
|
|
103
|
-
data: data,
|
|
104
|
-
isLast: status & 0x01 ? function () {
|
|
105
|
-
return true;
|
|
106
|
-
} : function () {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
context$2$0.next = 0;
|
|
111
|
-
break;
|
|
34
|
+
_createClass(ReadablePacketStream, [{
|
|
35
|
+
key: '_transform',
|
|
36
|
+
value: function _transform(chunk, encoding, callback) {
|
|
37
|
+
if (this.position === this.buffer.length) {
|
|
38
|
+
// If we have fully consumed the previous buffer,
|
|
39
|
+
// we can just replace it with the new chunk
|
|
40
|
+
this.buffer = chunk;
|
|
41
|
+
} else {
|
|
42
|
+
// If we haven't fully consumed the previous buffer,
|
|
43
|
+
// we simply concatenate the leftovers and the new chunk.
|
|
44
|
+
this.buffer = Buffer.concat([this.buffer.slice(this.position), chunk], this.buffer.length - this.position + chunk.length);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this.position = 0;
|
|
112
48
|
|
|
113
|
-
|
|
114
|
-
|
|
49
|
+
// The packet header is always 8 bytes of length.
|
|
50
|
+
while (this.buffer.length >= this.position + packetHeaderLength) {
|
|
51
|
+
// Get the full packet length
|
|
52
|
+
var _length = this.buffer.readUInt16BE(this.position + 2);
|
|
115
53
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
54
|
+
if (this.buffer.length >= this.position + _length) {
|
|
55
|
+
var data = this.buffer.slice(this.position, this.position + _length);
|
|
56
|
+
this.position += _length;
|
|
57
|
+
this.push(new Packet(data));
|
|
58
|
+
} else {
|
|
59
|
+
// Not enough data to provide the next packet. Stop here and wait for
|
|
60
|
+
// the next call to `_transform`.
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
119
63
|
}
|
|
120
|
-
|
|
121
|
-
|
|
64
|
+
|
|
65
|
+
callback();
|
|
66
|
+
}
|
|
67
|
+
}]);
|
|
122
68
|
|
|
123
69
|
return ReadablePacketStream;
|
|
124
|
-
})(
|
|
70
|
+
})(Transform);
|
|
125
71
|
|
|
126
|
-
|
|
127
|
-
|
|
72
|
+
module.exports = (function (_EventEmitter) {
|
|
73
|
+
_inherits(MessageIO, _EventEmitter);
|
|
128
74
|
|
|
129
75
|
function MessageIO(socket, _packetSize, debug) {
|
|
76
|
+
var _this = this;
|
|
77
|
+
|
|
78
|
+
_classCallCheck(this, MessageIO);
|
|
79
|
+
|
|
80
|
+
_get(Object.getPrototypeOf(MessageIO.prototype), 'constructor', this).call(this);
|
|
81
|
+
|
|
130
82
|
this.socket = socket;
|
|
131
83
|
this._packetSize = _packetSize;
|
|
132
84
|
this.debug = debug;
|
|
133
|
-
this.sendPacket =
|
|
85
|
+
this.sendPacket = this.sendPacket.bind(this);
|
|
86
|
+
|
|
134
87
|
this.packetStream = new ReadablePacketStream();
|
|
135
|
-
this.packetStream.on('data',
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
88
|
+
this.packetStream.on('data', function (packet) {
|
|
89
|
+
_this.logPacket('Received', packet);
|
|
90
|
+
_this.emit('data', packet.data());
|
|
91
|
+
if (packet.isLast()) {
|
|
92
|
+
_this.emit('message');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
143
96
|
this.socket.pipe(this.packetStream);
|
|
144
97
|
this.packetDataSize = this._packetSize - packetHeaderLength;
|
|
145
98
|
}
|
|
146
99
|
|
|
147
|
-
MessageIO
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
100
|
+
_createClass(MessageIO, [{
|
|
101
|
+
key: 'packetSize',
|
|
102
|
+
value: function packetSize(_packetSize2) {
|
|
103
|
+
if (arguments.length > 0) {
|
|
104
|
+
this.debug.log('Packet size changed from ' + this._packetSize + ' to ' + _packetSize2);
|
|
105
|
+
this._packetSize = _packetSize2;
|
|
106
|
+
this.packetDataSize = this._packetSize - packetHeaderLength;
|
|
107
|
+
}
|
|
108
|
+
return this._packetSize;
|
|
109
|
+
}
|
|
110
|
+
}, {
|
|
111
|
+
key: 'startTls',
|
|
112
|
+
value: function startTls(credentialsDetails) {
|
|
113
|
+
var _this2 = this;
|
|
114
|
+
|
|
115
|
+
var credentials = tls.createSecureContext ? tls.createSecureContext(credentialsDetails) : crypto.createCredentials(credentialsDetails);
|
|
116
|
+
|
|
117
|
+
this.securePair = tls.createSecurePair(credentials);
|
|
118
|
+
this.tlsNegotiationComplete = false;
|
|
119
|
+
|
|
120
|
+
this.securePair.on('secure', function () {
|
|
121
|
+
var cipher = _this2.securePair.cleartext.getCipher();
|
|
122
|
+
_this2.debug.log('TLS negotiated (' + cipher.name + ', ' + cipher.version + ')');
|
|
123
|
+
_this2.emit('secure', _this2.securePair.cleartext);
|
|
124
|
+
_this2.encryptAllFutureTraffic();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.securePair.encrypted.on('data', function (data) {
|
|
128
|
+
_this2.sendMessage(TYPE.PRELOGIN, data);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// On Node >= 0.12, the encrypted stream automatically starts spewing out
|
|
132
|
+
// data once we attach a `data` listener. But on Node <= 0.10.x, this is not
|
|
133
|
+
// the case. We need to kick the cleartext stream once to get the
|
|
134
|
+
// encrypted end of the secure pair to emit the TLS handshake data.
|
|
135
|
+
this.securePair.cleartext.write('');
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
key: 'encryptAllFutureTraffic',
|
|
139
|
+
value: function encryptAllFutureTraffic() {
|
|
140
|
+
this.socket.unpipe(this.packetStream);
|
|
141
|
+
this.securePair.encrypted.removeAllListeners('data');
|
|
142
|
+
this.socket.pipe(this.securePair.encrypted);
|
|
143
|
+
this.securePair.encrypted.pipe(this.socket);
|
|
144
|
+
this.securePair.cleartext.pipe(this.packetStream);
|
|
145
|
+
this.tlsNegotiationComplete = true;
|
|
152
146
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
var credentials;
|
|
158
|
-
credentials = tls.createSecureContext ? tls.createSecureContext(credentialsDetails) : crypto.createCredentials(credentialsDetails);
|
|
159
|
-
this.securePair = tls.createSecurePair(credentials);
|
|
160
|
-
this.tlsNegotiationComplete = false;
|
|
161
|
-
this.securePair.on('secure', (function (_this) {
|
|
162
|
-
return function () {
|
|
163
|
-
var cipher;
|
|
164
|
-
cipher = _this.securePair.cleartext.getCipher();
|
|
165
|
-
_this.debug.log("TLS negotiated (" + cipher.name + ", " + cipher.version + ")");
|
|
166
|
-
_this.emit('secure', _this.securePair.cleartext);
|
|
167
|
-
return _this.encryptAllFutureTraffic();
|
|
168
|
-
};
|
|
169
|
-
})(this));
|
|
170
|
-
this.securePair.encrypted.on('data', (function (_this) {
|
|
171
|
-
return function (data) {
|
|
172
|
-
return _this.sendMessage(TYPE.PRELOGIN, data);
|
|
173
|
-
};
|
|
174
|
-
})(this));
|
|
175
|
-
return this.securePair.cleartext.write('');
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
MessageIO.prototype.encryptAllFutureTraffic = function () {
|
|
179
|
-
this.socket.unpipe(this.packetStream);
|
|
180
|
-
this.securePair.encrypted.removeAllListeners('data');
|
|
181
|
-
this.socket.pipe(this.securePair.encrypted);
|
|
182
|
-
this.securePair.encrypted.pipe(this.socket);
|
|
183
|
-
this.securePair.cleartext.pipe(this.packetStream);
|
|
184
|
-
return this.tlsNegotiationComplete = true;
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
MessageIO.prototype.tlsHandshakeData = function (data) {
|
|
188
|
-
return this.securePair.encrypted.write(data);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
MessageIO.prototype.sendMessage = function (packetType, data, resetConnection) {
|
|
192
|
-
var i, numberOfPackets, packet, packetNumber, packetPayload, payloadEnd, payloadStart, ref, results;
|
|
193
|
-
if (data) {
|
|
194
|
-
numberOfPackets = Math.floor((data.length - 1) / this.packetDataSize) + 1;
|
|
195
|
-
} else {
|
|
196
|
-
numberOfPackets = 1;
|
|
197
|
-
data = new Buffer(0);
|
|
147
|
+
}, {
|
|
148
|
+
key: 'tlsHandshakeData',
|
|
149
|
+
value: function tlsHandshakeData(data) {
|
|
150
|
+
this.securePair.encrypted.write(data);
|
|
198
151
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
152
|
+
|
|
153
|
+
// TODO listen for 'drain' event when socket.write returns false.
|
|
154
|
+
// TODO implement incomplete request cancelation (2.2.1.6)
|
|
155
|
+
}, {
|
|
156
|
+
key: 'sendMessage',
|
|
157
|
+
value: function sendMessage(packetType, data, resetConnection) {
|
|
158
|
+
var numberOfPackets = undefined;
|
|
159
|
+
if (data) {
|
|
160
|
+
numberOfPackets = Math.floor((data.length - 1) / this.packetDataSize) + 1;
|
|
204
161
|
} else {
|
|
205
|
-
|
|
162
|
+
numberOfPackets = 1;
|
|
163
|
+
data = new Buffer(0);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
for (var packetNumber = 0; packetNumber < numberOfPackets; packetNumber++) {
|
|
167
|
+
var payloadStart = packetNumber * this.packetDataSize;
|
|
168
|
+
|
|
169
|
+
var payloadEnd = undefined;
|
|
170
|
+
if (packetNumber < numberOfPackets - 1) {
|
|
171
|
+
payloadEnd = payloadStart + this.packetDataSize;
|
|
172
|
+
} else {
|
|
173
|
+
payloadEnd = data.length;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
var packetPayload = data.slice(payloadStart, payloadEnd);
|
|
177
|
+
|
|
178
|
+
var packet = new Packet(packetType);
|
|
179
|
+
packet.last(packetNumber === numberOfPackets - 1);
|
|
180
|
+
packet.resetConnection(resetConnection);
|
|
181
|
+
packet.packetId(packetNumber + 1);
|
|
182
|
+
packet.addData(packetPayload);
|
|
183
|
+
this.sendPacket(packet);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}, {
|
|
187
|
+
key: 'sendPacket',
|
|
188
|
+
value: function sendPacket(packet) {
|
|
189
|
+
this.logPacket('Sent', packet);
|
|
190
|
+
if (this.securePair && this.tlsNegotiationComplete) {
|
|
191
|
+
this.securePair.cleartext.write(packet.buffer);
|
|
192
|
+
} else {
|
|
193
|
+
this.socket.write(packet.buffer);
|
|
206
194
|
}
|
|
207
|
-
packetPayload = data.slice(payloadStart, payloadEnd);
|
|
208
|
-
packet = new Packet(packetType);
|
|
209
|
-
packet.last(packetNumber === numberOfPackets - 1);
|
|
210
|
-
packet.resetConnection(resetConnection);
|
|
211
|
-
packet.packetId(packetNumber + 1);
|
|
212
|
-
packet.addData(packetPayload);
|
|
213
|
-
results.push(this.sendPacket(packet, packetType));
|
|
214
195
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (this.securePair && this.tlsNegotiationComplete) {
|
|
221
|
-
return this.securePair.cleartext.write(packet.buffer);
|
|
222
|
-
} else {
|
|
223
|
-
return this.socket.write(packet.buffer);
|
|
196
|
+
}, {
|
|
197
|
+
key: 'logPacket',
|
|
198
|
+
value: function logPacket(direction, packet) {
|
|
199
|
+
this.debug.packet(direction, packet);
|
|
200
|
+
return this.debug.data(packet);
|
|
224
201
|
}
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
MessageIO.prototype.logPacket = function (direction, packet) {
|
|
228
|
-
this.debug.packet(direction, packet);
|
|
229
|
-
return this.debug.data(packet);
|
|
230
|
-
};
|
|
202
|
+
}]);
|
|
231
203
|
|
|
232
204
|
return MessageIO;
|
|
233
|
-
})(EventEmitter);
|
|
234
|
-
|
|
235
|
-
module.exports = MessageIO;
|
|
205
|
+
})(EventEmitter);
|