mssql 3.1.1 → 3.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/.travis.yml +1 -0
- package/CHANGELOG.txt +17 -1
- package/README.md +154 -125
- package/appveyor.yml +1 -0
- package/lib/connectionstring.js +15 -6
- package/lib/main.js +90 -1
- package/lib/msnodesql.js +40 -4
- package/lib/msnodesqlv8.js +40 -4
- package/lib/tds.js +11 -0
- package/lib/tedious.js +39 -3
- package/package.json +5 -3
- package/src/connectionstring.coffee +7 -3
- package/src/main.coffee +69 -2
- package/src/msnodesql.coffee +34 -2
- package/src/msnodesqlv8.coffee +34 -2
- package/src/tds.coffee +10 -0
- package/src/tedious.coffee +30 -1
package/appveyor.yml
CHANGED
package/lib/connectionstring.js
CHANGED
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
};
|
|
187
187
|
|
|
188
188
|
resolveConnectionString = function(string) {
|
|
189
|
-
var config, parsed, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, server, user;
|
|
189
|
+
var config, parsed, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, server, user;
|
|
190
190
|
if (/^(mssql|tedious|msnodesql|tds)\:\/\//i.test(string)) {
|
|
191
191
|
parsed = parseConnectionURI(string);
|
|
192
192
|
} else {
|
|
@@ -211,13 +211,22 @@
|
|
|
211
211
|
driver: parsed.driver,
|
|
212
212
|
password: (ref6 = parsed.pwd) != null ? ref6 : parsed.password,
|
|
213
213
|
database: (ref7 = parsed.database) != null ? ref7 : parsed['initial catalog'],
|
|
214
|
-
connectionTimeout: (ref8 = (ref9 = parsed.timeout) != null ? ref9 : parsed['connect timeout']) != null ? ref8 : parsed['connection timeout'],
|
|
215
|
-
requestTimeout: parsed['request timeout'],
|
|
216
|
-
stream: (
|
|
214
|
+
connectionTimeout: (ref8 = (ref9 = (ref10 = parsed.connectionTimeout) != null ? ref10 : parsed.timeout) != null ? ref9 : parsed['connect timeout']) != null ? ref8 : parsed['connection timeout'],
|
|
215
|
+
requestTimeout: (ref11 = parsed.requestTimeout) != null ? ref11 : parsed['request timeout'],
|
|
216
|
+
stream: (ref12 = (ref13 = parsed.stream) != null ? ref13.toLowerCase() : void 0) === 'true' || ref12 === 'yes' || ref12 === '1',
|
|
217
217
|
options: {
|
|
218
|
-
encrypt: (
|
|
218
|
+
encrypt: (ref14 = (ref15 = parsed.encrypt) != null ? ref15.toLowerCase() : void 0) === 'true' || ref14 === 'yes' || ref14 === '1'
|
|
219
219
|
}
|
|
220
220
|
};
|
|
221
|
+
if (parsed.useUTC != null) {
|
|
222
|
+
config.options.useUTC = (ref16 = parsed.useUTC.toLowerCase()) === 'true' || ref16 === 'yes' || ref16 === '1';
|
|
223
|
+
}
|
|
224
|
+
if (config.connectionTimeout != null) {
|
|
225
|
+
config.connectionTimeout = parseInt(config.connectionTimeout);
|
|
226
|
+
}
|
|
227
|
+
if (config.requestTimeout != null) {
|
|
228
|
+
config.requestTimeout = parseInt(config.requestTimeout);
|
|
229
|
+
}
|
|
221
230
|
if (/^(.*)\\(.*)$/.exec(user)) {
|
|
222
231
|
config.domain = RegExp.$1;
|
|
223
232
|
user = RegExp.$2;
|
|
@@ -238,7 +247,7 @@
|
|
|
238
247
|
server = RegExp.$1.trim();
|
|
239
248
|
config.port = parseInt(RegExp.$2.trim());
|
|
240
249
|
}
|
|
241
|
-
if ((
|
|
250
|
+
if ((ref17 = server.toLowerCase()) === '.' || ref17 === '(.)' || ref17 === '(localdb)' || ref17 === '(local)') {
|
|
242
251
|
server = 'localhost';
|
|
243
252
|
}
|
|
244
253
|
}
|
package/lib/main.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
5
5
|
hasProp = {}.hasOwnProperty,
|
|
6
6
|
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
|
7
|
+
slice = [].slice,
|
|
7
8
|
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
|
8
9
|
|
|
9
10
|
EventEmitter = require('events').EventEmitter;
|
|
@@ -383,6 +384,36 @@
|
|
|
383
384
|
return new Transaction(this);
|
|
384
385
|
};
|
|
385
386
|
|
|
387
|
+
|
|
388
|
+
/*
|
|
389
|
+
Creates a new query using this connection from a tagged template string.
|
|
390
|
+
|
|
391
|
+
@param {Array} strings Array of string literals.
|
|
392
|
+
@param {...*} keys Values.
|
|
393
|
+
@returns {Request}
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
Connection.prototype.query = function() {
|
|
397
|
+
var strings, values;
|
|
398
|
+
strings = arguments[0], values = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
|
399
|
+
return new Request(this)._template('query', strings, values);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
/*
|
|
404
|
+
Creates a new batch using this connection from a tagged template string.
|
|
405
|
+
|
|
406
|
+
@param {Array} strings Array of string literals.
|
|
407
|
+
@param {...*} keys Values.
|
|
408
|
+
@returns {Request}
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
Connection.prototype.batch = function() {
|
|
412
|
+
var strings, values;
|
|
413
|
+
strings = arguments[0], values = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
|
414
|
+
return new Request(this)._template('batch', strings, values);
|
|
415
|
+
};
|
|
416
|
+
|
|
386
417
|
return Connection;
|
|
387
418
|
|
|
388
419
|
})(EventEmitter);
|
|
@@ -396,6 +427,7 @@
|
|
|
396
427
|
@property {Connection} connection Reference to used connection.
|
|
397
428
|
@property {Boolean} multiple If `true`, `execute` will handle multiple recordsets.
|
|
398
429
|
@property {String} statement Prepared SQL statement.
|
|
430
|
+
@property {Request} lastRequest References instance of most recent Request created by executing a statement.
|
|
399
431
|
*/
|
|
400
432
|
|
|
401
433
|
PreparedStatement = (function(superClass) {
|
|
@@ -423,6 +455,8 @@
|
|
|
423
455
|
|
|
424
456
|
PreparedStatement.prototype.stream = null;
|
|
425
457
|
|
|
458
|
+
PreparedStatement.prototype.lastRequest = null;
|
|
459
|
+
|
|
426
460
|
|
|
427
461
|
/*
|
|
428
462
|
Create new Prepared Statement.
|
|
@@ -678,7 +712,7 @@
|
|
|
678
712
|
|
|
679
713
|
PreparedStatement.prototype._execute = function(values, callback) {
|
|
680
714
|
var name, param, ref1, req;
|
|
681
|
-
req = new Request(this);
|
|
715
|
+
req = this.lastRequest = new Request(this);
|
|
682
716
|
if (this.stream != null) {
|
|
683
717
|
req.stream = this.stream;
|
|
684
718
|
}
|
|
@@ -1119,6 +1153,22 @@
|
|
|
1119
1153
|
};
|
|
1120
1154
|
|
|
1121
1155
|
|
|
1156
|
+
/*
|
|
1157
|
+
Fetch request from tagged template string.
|
|
1158
|
+
*/
|
|
1159
|
+
|
|
1160
|
+
Request.prototype._template = function(method, strings, values) {
|
|
1161
|
+
var command, i, index, len, value;
|
|
1162
|
+
command = [strings[0]];
|
|
1163
|
+
for (index = i = 0, len = values.length; i < len; index = ++i) {
|
|
1164
|
+
value = values[index];
|
|
1165
|
+
this.input("param" + (index + 1), value);
|
|
1166
|
+
command.push("@param" + (index + 1), strings[index + 1]);
|
|
1167
|
+
}
|
|
1168
|
+
return this[method](command.join(''));
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
|
|
1122
1172
|
/*
|
|
1123
1173
|
Acquire connection for this request from connection.
|
|
1124
1174
|
*/
|
|
@@ -1810,10 +1860,49 @@
|
|
|
1810
1860
|
return global_connection != null ? global_connection.close(callback) : void 0;
|
|
1811
1861
|
};
|
|
1812
1862
|
|
|
1863
|
+
|
|
1864
|
+
/*
|
|
1865
|
+
Attach evnet handler to global connection.
|
|
1866
|
+
|
|
1867
|
+
@param {String} event Event name.
|
|
1868
|
+
@param {Function} handler Event handler.
|
|
1869
|
+
@returns {Connection}
|
|
1870
|
+
*/
|
|
1871
|
+
|
|
1813
1872
|
module.exports.on = function(event, handler) {
|
|
1814
1873
|
return global_connection != null ? global_connection.on(event, handler) : void 0;
|
|
1815
1874
|
};
|
|
1816
1875
|
|
|
1876
|
+
|
|
1877
|
+
/*
|
|
1878
|
+
Creates a new query using global connection from a tagged template string.
|
|
1879
|
+
|
|
1880
|
+
@param {Array} strings Array of string literals.
|
|
1881
|
+
@param {...*} keys Values.
|
|
1882
|
+
@returns {Request}
|
|
1883
|
+
*/
|
|
1884
|
+
|
|
1885
|
+
module.exports.query = function() {
|
|
1886
|
+
var strings, values;
|
|
1887
|
+
strings = arguments[0], values = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
|
1888
|
+
return new Request()._template('query', strings, values);
|
|
1889
|
+
};
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
/*
|
|
1893
|
+
Creates a new batch using global connection from a tagged template string.
|
|
1894
|
+
|
|
1895
|
+
@param {Array} strings Array of string literals.
|
|
1896
|
+
@param {...*} keys Values.
|
|
1897
|
+
@returns {Request}
|
|
1898
|
+
*/
|
|
1899
|
+
|
|
1900
|
+
module.exports.batch = function() {
|
|
1901
|
+
var strings, values;
|
|
1902
|
+
strings = arguments[0], values = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
|
1903
|
+
return new Request()._template('batch', strings, values);
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1817
1906
|
module.exports.Connection = Connection;
|
|
1818
1907
|
|
|
1819
1908
|
module.exports.Transaction = Transaction;
|
package/lib/msnodesql.js
CHANGED
|
@@ -429,10 +429,28 @@
|
|
|
429
429
|
_this._log("---------- response -----------");
|
|
430
430
|
}
|
|
431
431
|
req.on('meta', function(metadata) {
|
|
432
|
-
var ref1;
|
|
432
|
+
var error, ex, ref1;
|
|
433
433
|
if (row) {
|
|
434
434
|
if (isChunkedRecordset) {
|
|
435
|
-
|
|
435
|
+
if (columns[0].name === JSON_COLUMN_ID && _this.connection.config.parseJSON === true) {
|
|
436
|
+
try {
|
|
437
|
+
row = JSON.parse(chunksBuffer.join(''));
|
|
438
|
+
if (!_this.stream) {
|
|
439
|
+
recordsets[recordsets.length - 1][0] = row;
|
|
440
|
+
}
|
|
441
|
+
} catch (error) {
|
|
442
|
+
ex = error;
|
|
443
|
+
row = null;
|
|
444
|
+
ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON');
|
|
445
|
+
if (_this.stream) {
|
|
446
|
+
_this.emit('error', ex);
|
|
447
|
+
} else {
|
|
448
|
+
console.error(ex);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
row[columns[0].name] = chunksBuffer.join('');
|
|
453
|
+
}
|
|
436
454
|
chunksBuffer = null;
|
|
437
455
|
}
|
|
438
456
|
if (_this.verbose) {
|
|
@@ -528,11 +546,29 @@
|
|
|
528
546
|
return typeof callback === "function" ? callback(e) : void 0;
|
|
529
547
|
});
|
|
530
548
|
return req.once('done', function() {
|
|
531
|
-
var elapsed, last, ref1, ref2;
|
|
549
|
+
var elapsed, error, ex, last, ref1, ref2;
|
|
532
550
|
if (!_this.nested) {
|
|
533
551
|
if (row) {
|
|
534
552
|
if (isChunkedRecordset) {
|
|
535
|
-
|
|
553
|
+
if (columns[0].name === JSON_COLUMN_ID && _this.connection.config.parseJSON === true) {
|
|
554
|
+
try {
|
|
555
|
+
row = JSON.parse(chunksBuffer.join(''));
|
|
556
|
+
if (!_this.stream) {
|
|
557
|
+
recordsets[recordsets.length - 1][0] = row;
|
|
558
|
+
}
|
|
559
|
+
} catch (error) {
|
|
560
|
+
ex = error;
|
|
561
|
+
row = null;
|
|
562
|
+
ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON');
|
|
563
|
+
if (_this.stream) {
|
|
564
|
+
_this.emit('error', ex);
|
|
565
|
+
} else {
|
|
566
|
+
console.error(ex);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
row[columns[0].name] = chunksBuffer.join('');
|
|
571
|
+
}
|
|
536
572
|
chunksBuffer = null;
|
|
537
573
|
}
|
|
538
574
|
if (_this.verbose) {
|
package/lib/msnodesqlv8.js
CHANGED
|
@@ -519,10 +519,28 @@
|
|
|
519
519
|
_this._log("---------- response -----------");
|
|
520
520
|
}
|
|
521
521
|
req.on('meta', function(metadata) {
|
|
522
|
-
var ref1;
|
|
522
|
+
var error, ex, ref1;
|
|
523
523
|
if (row) {
|
|
524
524
|
if (isChunkedRecordset) {
|
|
525
|
-
|
|
525
|
+
if (columns[0].name === JSON_COLUMN_ID && _this.connection.config.parseJSON === true) {
|
|
526
|
+
try {
|
|
527
|
+
row = JSON.parse(chunksBuffer.join(''));
|
|
528
|
+
if (!_this.stream) {
|
|
529
|
+
recordsets[recordsets.length - 1][0] = row;
|
|
530
|
+
}
|
|
531
|
+
} catch (error) {
|
|
532
|
+
ex = error;
|
|
533
|
+
row = null;
|
|
534
|
+
ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON');
|
|
535
|
+
if (_this.stream) {
|
|
536
|
+
_this.emit('error', ex);
|
|
537
|
+
} else {
|
|
538
|
+
console.error(ex);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} else {
|
|
542
|
+
row[columns[0].name] = chunksBuffer.join('');
|
|
543
|
+
}
|
|
526
544
|
chunksBuffer = null;
|
|
527
545
|
}
|
|
528
546
|
if (_this.verbose) {
|
|
@@ -618,11 +636,29 @@
|
|
|
618
636
|
return typeof callback === "function" ? callback(e) : void 0;
|
|
619
637
|
});
|
|
620
638
|
return req.once('done', function() {
|
|
621
|
-
var elapsed, last, ref1, ref2;
|
|
639
|
+
var elapsed, error, ex, last, ref1, ref2;
|
|
622
640
|
if (!_this.nested) {
|
|
623
641
|
if (row) {
|
|
624
642
|
if (isChunkedRecordset) {
|
|
625
|
-
|
|
643
|
+
if (columns[0].name === JSON_COLUMN_ID && _this.connection.config.parseJSON === true) {
|
|
644
|
+
try {
|
|
645
|
+
row = JSON.parse(chunksBuffer.join(''));
|
|
646
|
+
if (!_this.stream) {
|
|
647
|
+
recordsets[recordsets.length - 1][0] = row;
|
|
648
|
+
}
|
|
649
|
+
} catch (error) {
|
|
650
|
+
ex = error;
|
|
651
|
+
row = null;
|
|
652
|
+
ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON');
|
|
653
|
+
if (_this.stream) {
|
|
654
|
+
_this.emit('error', ex);
|
|
655
|
+
} else {
|
|
656
|
+
console.error(ex);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
} else {
|
|
660
|
+
row[columns[0].name] = chunksBuffer.join('');
|
|
661
|
+
}
|
|
626
662
|
chunksBuffer = null;
|
|
627
663
|
}
|
|
628
664
|
if (_this.verbose) {
|
package/lib/tds.js
CHANGED
|
@@ -551,6 +551,17 @@
|
|
|
551
551
|
return typeof callback === "function" ? callback(error, _this.multiple || _this.nested ? recordsets : recordsets[0]) : void 0;
|
|
552
552
|
}
|
|
553
553
|
});
|
|
554
|
+
req.on('message', function(msg) {
|
|
555
|
+
return _this.emit('info', {
|
|
556
|
+
message: msg.text,
|
|
557
|
+
number: msg.number,
|
|
558
|
+
state: msg.state,
|
|
559
|
+
"class": msg.severity,
|
|
560
|
+
lineNumber: msg.lineNumber,
|
|
561
|
+
serverName: msg.serverName,
|
|
562
|
+
procName: msg.procName
|
|
563
|
+
});
|
|
564
|
+
});
|
|
554
565
|
req.on('error', function(err) {
|
|
555
566
|
var e;
|
|
556
567
|
e = RequestError(err, 'EREQUEST');
|
package/lib/tedious.js
CHANGED
|
@@ -461,9 +461,15 @@
|
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
TediousTransaction.prototype._abort = function() {
|
|
464
|
+
var pc;
|
|
464
465
|
if (!this._rollbackRequested) {
|
|
466
|
+
pc = this._pooledConnection;
|
|
467
|
+
setImmediate((function(_this) {
|
|
468
|
+
return function() {
|
|
469
|
+
return _this.connection.pool.release(pc);
|
|
470
|
+
};
|
|
471
|
+
})(this));
|
|
465
472
|
this._pooledConnection.removeListener('rollbackTransaction', this._abort);
|
|
466
|
-
this.connection.pool.release(this._pooledConnection);
|
|
467
473
|
this._pooledConnection = null;
|
|
468
474
|
this._aborted = true;
|
|
469
475
|
return this.emit('rollback', true);
|
|
@@ -545,7 +551,7 @@
|
|
|
545
551
|
*/
|
|
546
552
|
|
|
547
553
|
TediousRequest.prototype.bulk = function(table, callback) {
|
|
548
|
-
var errorHandlers, errors, handleError, hasReturned, started;
|
|
554
|
+
var errorHandlers, errors, handleError, handleInfo, hasReturned, started;
|
|
549
555
|
table._makeBulk();
|
|
550
556
|
if (!table.name) {
|
|
551
557
|
process.nextTick(function() {
|
|
@@ -587,6 +593,19 @@
|
|
|
587
593
|
return errors.push(e);
|
|
588
594
|
};
|
|
589
595
|
})(this);
|
|
596
|
+
handleInfo = (function(_this) {
|
|
597
|
+
return function(msg) {
|
|
598
|
+
return _this.emit('info', {
|
|
599
|
+
message: msg.message,
|
|
600
|
+
number: msg.number,
|
|
601
|
+
state: msg.state,
|
|
602
|
+
"class": msg["class"],
|
|
603
|
+
lineNumber: msg.lineNumber,
|
|
604
|
+
serverName: msg.serverName,
|
|
605
|
+
procName: msg.procName
|
|
606
|
+
});
|
|
607
|
+
};
|
|
608
|
+
})(this);
|
|
590
609
|
return this._acquire((function(_this) {
|
|
591
610
|
return function(err, connection) {
|
|
592
611
|
var bulk, col, done, i, j, len, len1, objectid, ref1, ref2, req, row;
|
|
@@ -607,8 +626,10 @@
|
|
|
607
626
|
}
|
|
608
627
|
return connection.cancel();
|
|
609
628
|
};
|
|
629
|
+
errorHandlers['infoMessage'] = handleInfo;
|
|
610
630
|
errorHandlers['errorMessage'] = handleError.bind(void 0, false, connection);
|
|
611
631
|
errorHandlers['error'] = handleError.bind(void 0, true, connection);
|
|
632
|
+
connection.on('infoMessage', errorHandlers['infoMessage']);
|
|
612
633
|
connection.on('errorMessage', errorHandlers['errorMessage']);
|
|
613
634
|
connection.on('error', errorHandlers['error']);
|
|
614
635
|
done = bindDomain(function(err, rowCount) {
|
|
@@ -696,7 +717,7 @@
|
|
|
696
717
|
*/
|
|
697
718
|
|
|
698
719
|
TediousRequest.prototype.query = function(command, callback) {
|
|
699
|
-
var batchHasOutput, batchLastRow, chunksBuffer, columns, errorHandlers, errors, handleError, hasReturned, isChunkedRecordset, isJSONRecordset, recordset, recordsets, started, xmlBuffer;
|
|
720
|
+
var batchHasOutput, batchLastRow, chunksBuffer, columns, errorHandlers, errors, handleError, handleInfo, hasReturned, isChunkedRecordset, isJSONRecordset, recordset, recordsets, started, xmlBuffer;
|
|
700
721
|
columns = {};
|
|
701
722
|
recordset = [];
|
|
702
723
|
recordsets = [];
|
|
@@ -736,6 +757,19 @@
|
|
|
736
757
|
return errors.push(e);
|
|
737
758
|
};
|
|
738
759
|
})(this);
|
|
760
|
+
handleInfo = (function(_this) {
|
|
761
|
+
return function(msg) {
|
|
762
|
+
return _this.emit('info', {
|
|
763
|
+
message: msg.message,
|
|
764
|
+
number: msg.number,
|
|
765
|
+
state: msg.state,
|
|
766
|
+
"class": msg["class"],
|
|
767
|
+
lineNumber: msg.lineNumber,
|
|
768
|
+
serverName: msg.serverName,
|
|
769
|
+
procName: msg.procName
|
|
770
|
+
});
|
|
771
|
+
};
|
|
772
|
+
})(this);
|
|
739
773
|
return this._acquire((function(_this) {
|
|
740
774
|
return function(err, connection) {
|
|
741
775
|
var assigns, declarations, doneHandler, name, param, ref1, ref2, req, selects, value;
|
|
@@ -756,8 +790,10 @@
|
|
|
756
790
|
}
|
|
757
791
|
return connection.cancel();
|
|
758
792
|
};
|
|
793
|
+
errorHandlers['infoMessage'] = handleInfo;
|
|
759
794
|
errorHandlers['errorMessage'] = handleError.bind(void 0, false, connection);
|
|
760
795
|
errorHandlers['error'] = handleError.bind(void 0, true, connection);
|
|
796
|
+
connection.on('infoMessage', errorHandlers['infoMessage']);
|
|
761
797
|
connection.on('errorMessage', errorHandlers['errorMessage']);
|
|
762
798
|
connection.on('error', errorHandlers['error']);
|
|
763
799
|
req = new tds.Request(command, bindDomain(function(err) {
|
package/package.json
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
"url": "https://patriksimek.cz"
|
|
5
5
|
},
|
|
6
6
|
"name": "mssql",
|
|
7
|
-
"description": "
|
|
7
|
+
"description": "Microsoft SQL Server client for Node.js.",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"database",
|
|
10
10
|
"mssql",
|
|
11
11
|
"sql",
|
|
12
|
+
"server",
|
|
12
13
|
"msnodesql",
|
|
13
14
|
"sqlserver",
|
|
14
15
|
"tds",
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
"azure",
|
|
21
22
|
"node-mssql"
|
|
22
23
|
],
|
|
23
|
-
"version": "3.
|
|
24
|
+
"version": "3.3.0",
|
|
24
25
|
"main": "index.js",
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
},
|
|
29
30
|
"license": "MIT",
|
|
30
31
|
"dependencies": {
|
|
31
|
-
"tedious": "~1.
|
|
32
|
+
"tedious": "~1.14.0",
|
|
32
33
|
"generic-pool": "^2.2.0",
|
|
33
34
|
"promise": "^7.0.1"
|
|
34
35
|
},
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"test": "node_modules/.bin/mocha test/unit",
|
|
46
47
|
"test-tedious": "node_modules/.bin/mocha test/integration -g tedious",
|
|
47
48
|
"test-msnodesql": "node_modules/.bin/mocha test/integration -g msnodesql",
|
|
49
|
+
"test-msnodesqlv8": "node_modules/.bin/mocha test/integration -g msnodesqlv8",
|
|
48
50
|
"test-tds": "node_modules/.bin/mocha test/integration -g tds",
|
|
49
51
|
"test-cli": "node_modules/.bin/mocha test/integration -g cli"
|
|
50
52
|
},
|
|
@@ -159,7 +159,7 @@ resolveConnectionString = (string) ->
|
|
|
159
159
|
parsed = parseConnectionURI string
|
|
160
160
|
else
|
|
161
161
|
parsed = parseConnectionString string
|
|
162
|
-
|
|
162
|
+
|
|
163
163
|
if parsed.driver is 'msnodesql'
|
|
164
164
|
parsed.driver = 'SQL Server Native Client 11.0'
|
|
165
165
|
parsed.__original__?.driver = name: 'Driver', escape: ['{', '}']
|
|
@@ -172,11 +172,15 @@ resolveConnectionString = (string) ->
|
|
|
172
172
|
driver: parsed.driver
|
|
173
173
|
password: parsed.pwd ? parsed.password
|
|
174
174
|
database: parsed.database ? parsed['initial catalog']
|
|
175
|
-
connectionTimeout: parsed.timeout ? parsed['connect timeout'] ? parsed['connection timeout']
|
|
176
|
-
requestTimeout: parsed['request timeout']
|
|
175
|
+
connectionTimeout: parsed.connectionTimeout ? parsed.timeout ? parsed['connect timeout'] ? parsed['connection timeout']
|
|
176
|
+
requestTimeout: parsed.requestTimeout ? parsed['request timeout']
|
|
177
177
|
stream: parsed.stream?.toLowerCase() in ['true', 'yes', '1']
|
|
178
178
|
options:
|
|
179
179
|
encrypt: parsed.encrypt?.toLowerCase() in ['true', 'yes', '1']
|
|
180
|
+
|
|
181
|
+
if parsed.useUTC? then config.options.useUTC = parsed.useUTC.toLowerCase() in ['true', 'yes', '1']
|
|
182
|
+
if config.connectionTimeout? then config.connectionTimeout = parseInt config.connectionTimeout
|
|
183
|
+
if config.requestTimeout? then config.requestTimeout = parseInt config.requestTimeout
|
|
180
184
|
|
|
181
185
|
if (/^(.*)\\(.*)$/).exec user
|
|
182
186
|
config.domain = RegExp.$1
|
package/src/main.coffee
CHANGED
|
@@ -293,6 +293,28 @@ class Connection extends EventEmitter
|
|
|
293
293
|
|
|
294
294
|
transaction: ->
|
|
295
295
|
new Transaction @
|
|
296
|
+
|
|
297
|
+
###
|
|
298
|
+
Creates a new query using this connection from a tagged template string.
|
|
299
|
+
|
|
300
|
+
@param {Array} strings Array of string literals.
|
|
301
|
+
@param {...*} keys Values.
|
|
302
|
+
@returns {Request}
|
|
303
|
+
###
|
|
304
|
+
|
|
305
|
+
query: (strings, values...) ->
|
|
306
|
+
new Request(@)._template 'query', strings, values
|
|
307
|
+
|
|
308
|
+
###
|
|
309
|
+
Creates a new batch using this connection from a tagged template string.
|
|
310
|
+
|
|
311
|
+
@param {Array} strings Array of string literals.
|
|
312
|
+
@param {...*} keys Values.
|
|
313
|
+
@returns {Request}
|
|
314
|
+
###
|
|
315
|
+
|
|
316
|
+
batch: (strings, values...) ->
|
|
317
|
+
new Request(@)._template 'batch', strings, values
|
|
296
318
|
|
|
297
319
|
###
|
|
298
320
|
Class PreparedStatement.
|
|
@@ -302,6 +324,7 @@ IMPORTANT: Rememeber that each prepared statement means one reserved connection
|
|
|
302
324
|
@property {Connection} connection Reference to used connection.
|
|
303
325
|
@property {Boolean} multiple If `true`, `execute` will handle multiple recordsets.
|
|
304
326
|
@property {String} statement Prepared SQL statement.
|
|
327
|
+
@property {Request} lastRequest References instance of most recent Request created by executing a statement.
|
|
305
328
|
###
|
|
306
329
|
|
|
307
330
|
class PreparedStatement extends EventEmitter
|
|
@@ -317,6 +340,7 @@ class PreparedStatement extends EventEmitter
|
|
|
317
340
|
parameters: null
|
|
318
341
|
multiple: false
|
|
319
342
|
stream: null
|
|
343
|
+
lastRequest: null
|
|
320
344
|
|
|
321
345
|
###
|
|
322
346
|
Create new Prepared Statement.
|
|
@@ -534,7 +558,7 @@ class PreparedStatement extends EventEmitter
|
|
|
534
558
|
resolve recordset
|
|
535
559
|
|
|
536
560
|
_execute: (values, callback) ->
|
|
537
|
-
req = new Request @
|
|
561
|
+
req = @lastRequest = new Request @
|
|
538
562
|
req.stream = @stream if @stream?
|
|
539
563
|
req.input 'handle', TYPES.Int, @_handle
|
|
540
564
|
|
|
@@ -866,6 +890,19 @@ class Request extends EventEmitter
|
|
|
866
890
|
_log: (out) ->
|
|
867
891
|
if typeof @logger is "function" then @logger out else console.log out
|
|
868
892
|
|
|
893
|
+
###
|
|
894
|
+
Fetch request from tagged template string.
|
|
895
|
+
###
|
|
896
|
+
|
|
897
|
+
_template: (method, strings, values) ->
|
|
898
|
+
command = [strings[0]]
|
|
899
|
+
|
|
900
|
+
for value, index in values
|
|
901
|
+
@input "param#{index + 1}", value
|
|
902
|
+
command.push "@param#{index + 1}", strings[index + 1]
|
|
903
|
+
|
|
904
|
+
@[method] command.join ''
|
|
905
|
+
|
|
869
906
|
###
|
|
870
907
|
Acquire connection for this request from connection.
|
|
871
908
|
###
|
|
@@ -1412,9 +1449,39 @@ Close global connection.
|
|
|
1412
1449
|
module.exports.close = (callback) ->
|
|
1413
1450
|
global_connection?.close callback
|
|
1414
1451
|
|
|
1452
|
+
###
|
|
1453
|
+
Attach evnet handler to global connection.
|
|
1454
|
+
|
|
1455
|
+
@param {String} event Event name.
|
|
1456
|
+
@param {Function} handler Event handler.
|
|
1457
|
+
@returns {Connection}
|
|
1458
|
+
###
|
|
1459
|
+
|
|
1415
1460
|
module.exports.on = (event, handler) ->
|
|
1416
1461
|
global_connection?.on event, handler
|
|
1417
1462
|
|
|
1463
|
+
###
|
|
1464
|
+
Creates a new query using global connection from a tagged template string.
|
|
1465
|
+
|
|
1466
|
+
@param {Array} strings Array of string literals.
|
|
1467
|
+
@param {...*} keys Values.
|
|
1468
|
+
@returns {Request}
|
|
1469
|
+
###
|
|
1470
|
+
|
|
1471
|
+
module.exports.query = (strings, values...) ->
|
|
1472
|
+
new Request()._template 'query', strings, values
|
|
1473
|
+
|
|
1474
|
+
###
|
|
1475
|
+
Creates a new batch using global connection from a tagged template string.
|
|
1476
|
+
|
|
1477
|
+
@param {Array} strings Array of string literals.
|
|
1478
|
+
@param {...*} keys Values.
|
|
1479
|
+
@returns {Request}
|
|
1480
|
+
###
|
|
1481
|
+
|
|
1482
|
+
module.exports.batch = (strings, values...) ->
|
|
1483
|
+
new Request()._template 'batch', strings, values
|
|
1484
|
+
|
|
1418
1485
|
module.exports.Connection = Connection
|
|
1419
1486
|
module.exports.Transaction = Transaction
|
|
1420
1487
|
module.exports.Request = Request
|
|
@@ -1439,7 +1506,7 @@ module.exports.Promise = global.Promise ? require('promise')
|
|
|
1439
1506
|
for key, value of TYPES
|
|
1440
1507
|
module.exports[key] = value
|
|
1441
1508
|
module.exports[key.toUpperCase()] = value
|
|
1442
|
-
|
|
1509
|
+
|
|
1443
1510
|
# --- DEPRECATED IN 0.3.0 ------------------------------------------
|
|
1444
1511
|
|
|
1445
1512
|
module.exports.pool =
|
package/src/msnodesql.coffee
CHANGED
|
@@ -249,7 +249,23 @@ module.exports = (Connection, Transaction, Request, ConnectionError, Transaction
|
|
|
249
249
|
req.on 'meta', (metadata) =>
|
|
250
250
|
if row
|
|
251
251
|
if isChunkedRecordset
|
|
252
|
-
|
|
252
|
+
if columns[0].name is JSON_COLUMN_ID and @connection.config.parseJSON is true
|
|
253
|
+
try
|
|
254
|
+
row = JSON.parse chunksBuffer.join('')
|
|
255
|
+
if not @stream then recordsets[recordsets.length - 1][0] = row
|
|
256
|
+
catch ex
|
|
257
|
+
row = null
|
|
258
|
+
ex = RequestError new Error("Failed to parse incoming JSON. #{ex.message}"), 'EJSON'
|
|
259
|
+
|
|
260
|
+
if @stream
|
|
261
|
+
@emit 'error', ex
|
|
262
|
+
|
|
263
|
+
else
|
|
264
|
+
console.error ex
|
|
265
|
+
|
|
266
|
+
else
|
|
267
|
+
row[columns[0].name] = chunksBuffer.join ''
|
|
268
|
+
|
|
253
269
|
chunksBuffer = null
|
|
254
270
|
|
|
255
271
|
if @verbose
|
|
@@ -341,7 +357,23 @@ module.exports = (Connection, Transaction, Request, ConnectionError, Transaction
|
|
|
341
357
|
unless @nested
|
|
342
358
|
if row
|
|
343
359
|
if isChunkedRecordset
|
|
344
|
-
|
|
360
|
+
if columns[0].name is JSON_COLUMN_ID and @connection.config.parseJSON is true
|
|
361
|
+
try
|
|
362
|
+
row = JSON.parse chunksBuffer.join('')
|
|
363
|
+
if not @stream then recordsets[recordsets.length - 1][0] = row
|
|
364
|
+
catch ex
|
|
365
|
+
row = null
|
|
366
|
+
ex = RequestError new Error("Failed to parse incoming JSON. #{ex.message}"), 'EJSON'
|
|
367
|
+
|
|
368
|
+
if @stream
|
|
369
|
+
@emit 'error', ex
|
|
370
|
+
|
|
371
|
+
else
|
|
372
|
+
console.error ex
|
|
373
|
+
|
|
374
|
+
else
|
|
375
|
+
row[columns[0].name] = chunksBuffer.join ''
|
|
376
|
+
|
|
345
377
|
chunksBuffer = null
|
|
346
378
|
|
|
347
379
|
if @verbose
|