mssql 6.2.2 → 6.3.2
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/CHANGELOG.txt +27 -0
- package/README.md +187 -2
- package/lib/base/connection-pool.js +1 -0
- package/lib/base/prepared-statement.js +1 -0
- package/lib/base/request.js +24 -12
- package/lib/global-connection.js +12 -1
- package/lib/msnodesqlv8/request.js +112 -45
- package/lib/tedious/request.js +54 -27
- package/lib/udt.js +1 -1
- package/package.json +5 -5
- package/test.js +20 -23
package/CHANGELOG.txt
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
v6.3.2 (2021-05-13)
|
|
2
|
+
-------------------
|
|
3
|
+
[fix] Bump various dependencies for security fixes
|
|
4
|
+
|
|
5
|
+
v6.3.1 (2021-01-01)
|
|
6
|
+
-------------------
|
|
7
|
+
[fix] Ensure line endings are unix style (LF)
|
|
8
|
+
|
|
9
|
+
v6.3.0 (2020-12-14)
|
|
10
|
+
-------------------
|
|
11
|
+
[new] Result sets with duplicate keys can now be handled using `request.arrayRowMode` ([#1130](https://github.com/tediousjs/node-mssql/pull/1130))
|
|
12
|
+
[fix] Issue with geography v2 parsing resolve ([#1138](https://github.com/tediousjs/node-mssql/pull/1138))
|
|
13
|
+
[fix] Fixed issue where msnodesqlv8 could sometimes terminate queries before all errors has been emitted causing queries to hang ([#1145](https://github.com/tediousjs/node-mssql/pull/1145))
|
|
14
|
+
|
|
15
|
+
v6.2.3 (2020-09-25)
|
|
16
|
+
-------------------
|
|
17
|
+
[fix] Remove reference to global pool on connection error ([#1107](https://github.com/tediousjs/node-mssql/pull/1107))
|
|
18
|
+
[fix] Trailing rows from request streams using msnodesqlv8 driver fail to be emitted ([#1109](https://github.com/tediousjs/node-mssql/pull/1109))
|
|
19
|
+
|
|
1
20
|
v6.2.2 (2020-09-18)
|
|
2
21
|
-------------------
|
|
3
22
|
[fix] Avoid using deprecated `.inspect` on Objects ([#1071](https://github.com/tediousjs/node-mssql/pull/1071))
|
|
@@ -48,6 +67,14 @@ v6.0.0 (2019-11-05)
|
|
|
48
67
|
[change] Replaced pool library (`generic-pool`) with `tarn.js` ([#808](https://github.com/tediousjs/node-mssql/pull/808))
|
|
49
68
|
[removed] Backoff try strategy for creating connections removed, `tarn.js` built-in retry strategy used instead
|
|
50
69
|
|
|
70
|
+
v5.1.5 (2021-05-13)
|
|
71
|
+
-------------------
|
|
72
|
+
[fix] Bump various dependencies for security fixes
|
|
73
|
+
|
|
74
|
+
v5.1.4 (2021-01-01)
|
|
75
|
+
-------------------
|
|
76
|
+
[fix] Ensure line endings are unix style (LF)
|
|
77
|
+
|
|
51
78
|
v5.1.3 (2020-09-18)
|
|
52
79
|
-------------------
|
|
53
80
|
[fix] Avoid using deprecated `.inspect` on Objects ([#1071](https://github.com/tediousjs/node-mssql/pull/1071))
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Microsoft SQL Server client for Node.js
|
|
|
6
6
|
|
|
7
7
|
Supported TDS drivers:
|
|
8
8
|
- [Tedious][tedious-url] (pure JavaScript - Windows/macOS/Linux, default)
|
|
9
|
-
- [Microsoft / Contributors Node V8 Driver for Node.js for SQL Server][msnodesqlv8-url] (native - Windows only)
|
|
9
|
+
- [Microsoft / Contributors Node V8 Driver for Node.js for SQL Server][msnodesqlv8-url] (v1 native - Windows only)
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
@@ -96,6 +96,7 @@ Parts of the connection URI should be correctly URL encoded so that the URI can
|
|
|
96
96
|
* [Table-Valued Parameter](#table-valued-parameter-tvp)
|
|
97
97
|
* [Affected Rows](#affected-rows)
|
|
98
98
|
* [JSON support](#json-support)
|
|
99
|
+
* [Handling Duplicate Column Names](#handling-duplicate-column-names)
|
|
99
100
|
* [Errors](#errors)
|
|
100
101
|
* [Informational messages](#informational-messages)
|
|
101
102
|
* [Metadata](#metadata)
|
|
@@ -611,6 +612,7 @@ const config = {
|
|
|
611
612
|
- **pool.max** - The maximum number of connections there can be in the pool (default: `10`).
|
|
612
613
|
- **pool.min** - The minimum of connections there can be in the pool (default: `0`).
|
|
613
614
|
- **pool.idleTimeoutMillis** - The Number of milliseconds before closing an unused connection (default: `30000`).
|
|
615
|
+
- **arrayRowMode** - Return row results as a an array instead of a keyed object. Also adds `columns` array. See [Handling Duplicate Column Names](#handling-duplicate-column-names)
|
|
614
616
|
|
|
615
617
|
Complete list of pool options can be found [here](https://github.com/vincit/tarn.js/#usage).
|
|
616
618
|
|
|
@@ -658,7 +660,7 @@ More information about Tedious specific options: http://tediousjs.github.io/tedi
|
|
|
658
660
|
|
|
659
661
|
### Microsoft / Contributors Node V8 Driver for Node.js for SQL Server
|
|
660
662
|
|
|
661
|
-
**Requires Node.js
|
|
663
|
+
**Requires Node.js v10+ or newer. Windows only.** This driver is not part of the default package and must be installed separately by `npm install msnodesqlv8@^1`. To use this driver, use this require syntax: `const sql = require('mssql/msnodesqlv8')`.
|
|
662
664
|
|
|
663
665
|
**Extra options:**
|
|
664
666
|
|
|
@@ -1566,6 +1568,189 @@ recordset = [ { a: { b: { c: 1, d: 2 }, x: 3, y: 4 } } ]
|
|
|
1566
1568
|
|
|
1567
1569
|
More information about JSON support can be found in [official documentation](https://msdn.microsoft.com/en-us/library/dn921882.aspx).
|
|
1568
1570
|
|
|
1571
|
+
## Handling Duplicate Column Names
|
|
1572
|
+
|
|
1573
|
+
If your queries contain output columns with identical names, the default behaviour of `mssql` will only return column metadata for the last column with that name. You will also not always be able to re-assemble the order of output columns requested.
|
|
1574
|
+
|
|
1575
|
+
Default behaviour:
|
|
1576
|
+
```javascript
|
|
1577
|
+
const request = new sql.Request()
|
|
1578
|
+
request
|
|
1579
|
+
.query("select 'asdf' as name, 'qwerty' as other_name, 'jkl' as name")
|
|
1580
|
+
.then(result => {
|
|
1581
|
+
console.log(result)
|
|
1582
|
+
});
|
|
1583
|
+
```
|
|
1584
|
+
Results in:
|
|
1585
|
+
```javascript
|
|
1586
|
+
{
|
|
1587
|
+
recordsets: [
|
|
1588
|
+
[ { name: [ 'asdf', 'jkl' ], other_name: 'qwerty' } ]
|
|
1589
|
+
],
|
|
1590
|
+
recordset: [ { name: [ 'asdf', 'jkl' ], other_name: 'qwerty' } ],
|
|
1591
|
+
output: {},
|
|
1592
|
+
rowsAffected: [ 1 ]
|
|
1593
|
+
}
|
|
1594
|
+
```
|
|
1595
|
+
|
|
1596
|
+
You can use the `arrayRowMode` configuration parameter to return the row values as arrays and add a separate array of column values. `arrayRowMode` can be set globally during the initial connection, or per-request.
|
|
1597
|
+
|
|
1598
|
+
```javascript
|
|
1599
|
+
const request = new sql.Request()
|
|
1600
|
+
request.arrayRowMode = true
|
|
1601
|
+
request
|
|
1602
|
+
.query("select 'asdf' as name, 'qwerty' as other_name, 'jkl' as name")
|
|
1603
|
+
.then(result => {
|
|
1604
|
+
console.log(result)
|
|
1605
|
+
});
|
|
1606
|
+
```
|
|
1607
|
+
|
|
1608
|
+
Results in:
|
|
1609
|
+
```javascript
|
|
1610
|
+
{
|
|
1611
|
+
recordsets: [ [ [ 'asdf', 'qwerty', 'jkl' ] ] ],
|
|
1612
|
+
recordset: [ [ 'asdf', 'qwerty', 'jkl' ] ],
|
|
1613
|
+
output: {},
|
|
1614
|
+
rowsAffected: [ 1 ],
|
|
1615
|
+
columns: [
|
|
1616
|
+
[
|
|
1617
|
+
{
|
|
1618
|
+
index: 0,
|
|
1619
|
+
name: 'name',
|
|
1620
|
+
length: 4,
|
|
1621
|
+
type: [sql.VarChar],
|
|
1622
|
+
scale: undefined,
|
|
1623
|
+
precision: undefined,
|
|
1624
|
+
nullable: false,
|
|
1625
|
+
caseSensitive: false,
|
|
1626
|
+
identity: false,
|
|
1627
|
+
readOnly: true
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
index: 1,
|
|
1631
|
+
name: 'other_name',
|
|
1632
|
+
length: 6,
|
|
1633
|
+
type: [sql.VarChar],
|
|
1634
|
+
scale: undefined,
|
|
1635
|
+
precision: undefined,
|
|
1636
|
+
nullable: false,
|
|
1637
|
+
caseSensitive: false,
|
|
1638
|
+
identity: false,
|
|
1639
|
+
readOnly: true
|
|
1640
|
+
},
|
|
1641
|
+
{
|
|
1642
|
+
index: 2,
|
|
1643
|
+
name: 'name',
|
|
1644
|
+
length: 3,
|
|
1645
|
+
type: [sql.VarChar],
|
|
1646
|
+
scale: undefined,
|
|
1647
|
+
precision: undefined,
|
|
1648
|
+
nullable: false,
|
|
1649
|
+
caseSensitive: false,
|
|
1650
|
+
identity: false,
|
|
1651
|
+
readOnly: true
|
|
1652
|
+
}
|
|
1653
|
+
]
|
|
1654
|
+
]
|
|
1655
|
+
}
|
|
1656
|
+
```
|
|
1657
|
+
|
|
1658
|
+
__Streaming Duplicate Column Names__
|
|
1659
|
+
|
|
1660
|
+
When using `arrayRowMode` with `stream` enabled, the output from the `recordset` event (as described in [Streaming](#streaming)) is returned as an array of column metadata, instead of as a keyed object. The order of the column metadata provided by the `recordset` event will match the order of row values when `arrayRowMode` is enabled.
|
|
1661
|
+
|
|
1662
|
+
Default behaviour (without `arrayRowMode`):
|
|
1663
|
+
```javascript
|
|
1664
|
+
const request = new sql.Request()
|
|
1665
|
+
request.stream = true
|
|
1666
|
+
request.query("select 'asdf' as name, 'qwerty' as other_name, 'jkl' as name")
|
|
1667
|
+
request.on('recordset', recordset => console.log(recordset))
|
|
1668
|
+
```
|
|
1669
|
+
|
|
1670
|
+
|
|
1671
|
+
Results in:
|
|
1672
|
+
|
|
1673
|
+
```javascript
|
|
1674
|
+
{
|
|
1675
|
+
name: {
|
|
1676
|
+
index: 2,
|
|
1677
|
+
name: 'name',
|
|
1678
|
+
length: 3,
|
|
1679
|
+
type: [sql.VarChar],
|
|
1680
|
+
scale: undefined,
|
|
1681
|
+
precision: undefined,
|
|
1682
|
+
nullable: false,
|
|
1683
|
+
caseSensitive: false,
|
|
1684
|
+
identity: false,
|
|
1685
|
+
readOnly: true
|
|
1686
|
+
},
|
|
1687
|
+
other_name: {
|
|
1688
|
+
index: 1,
|
|
1689
|
+
name: 'other_name',
|
|
1690
|
+
length: 6,
|
|
1691
|
+
type: [sql.VarChar],
|
|
1692
|
+
scale: undefined,
|
|
1693
|
+
precision: undefined,
|
|
1694
|
+
nullable: false,
|
|
1695
|
+
caseSensitive: false,
|
|
1696
|
+
identity: false,
|
|
1697
|
+
readOnly: true
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
```
|
|
1701
|
+
|
|
1702
|
+
With `arrayRowMode`:
|
|
1703
|
+
```javascript
|
|
1704
|
+
const request = new sql.Request()
|
|
1705
|
+
request.stream = true
|
|
1706
|
+
request.arrayRowMode = true
|
|
1707
|
+
request.query("select 'asdf' as name, 'qwerty' as other_name, 'jkl' as name")
|
|
1708
|
+
|
|
1709
|
+
request.on('recordset', recordset => console.log(recordset))
|
|
1710
|
+
```
|
|
1711
|
+
|
|
1712
|
+
Results in:
|
|
1713
|
+
```javascript
|
|
1714
|
+
[
|
|
1715
|
+
{
|
|
1716
|
+
index: 0,
|
|
1717
|
+
name: 'name',
|
|
1718
|
+
length: 4,
|
|
1719
|
+
type: [sql.VarChar],
|
|
1720
|
+
scale: undefined,
|
|
1721
|
+
precision: undefined,
|
|
1722
|
+
nullable: false,
|
|
1723
|
+
caseSensitive: false,
|
|
1724
|
+
identity: false,
|
|
1725
|
+
readOnly: true
|
|
1726
|
+
},
|
|
1727
|
+
{
|
|
1728
|
+
index: 1,
|
|
1729
|
+
name: 'other_name',
|
|
1730
|
+
length: 6,
|
|
1731
|
+
type: [sql.VarChar],
|
|
1732
|
+
scale: undefined,
|
|
1733
|
+
precision: undefined,
|
|
1734
|
+
nullable: false,
|
|
1735
|
+
caseSensitive: false,
|
|
1736
|
+
identity: false,
|
|
1737
|
+
readOnly: true
|
|
1738
|
+
},
|
|
1739
|
+
{
|
|
1740
|
+
index: 2,
|
|
1741
|
+
name: 'name',
|
|
1742
|
+
length: 3,
|
|
1743
|
+
type: [sql.VarChar],
|
|
1744
|
+
scale: undefined,
|
|
1745
|
+
precision: undefined,
|
|
1746
|
+
nullable: false,
|
|
1747
|
+
caseSensitive: false,
|
|
1748
|
+
identity: false,
|
|
1749
|
+
readOnly: true
|
|
1750
|
+
}
|
|
1751
|
+
]
|
|
1752
|
+
```
|
|
1753
|
+
|
|
1569
1754
|
## Errors
|
|
1570
1755
|
|
|
1571
1756
|
There are 4 types of errors you can handle:
|
|
@@ -59,6 +59,7 @@ class ConnectionPool extends EventEmitter {
|
|
|
59
59
|
this.config.options = this.config.options || {}
|
|
60
60
|
this.config.stream = this.config.stream || false
|
|
61
61
|
this.config.parseJSON = this.config.parseJSON || false
|
|
62
|
+
this.config.arrayRowMode = this.config.arrayRowMode || false
|
|
62
63
|
|
|
63
64
|
if (/^(.*)\\(.*)$/.exec(this.config.server)) {
|
|
64
65
|
this.config.server = RegExp.$1
|
|
@@ -292,6 +292,7 @@ class PreparedStatement extends EventEmitter {
|
|
|
292
292
|
_execute (values, callback) {
|
|
293
293
|
const req = new shared.driver.Request(this)
|
|
294
294
|
req.stream = this.stream
|
|
295
|
+
req.arrayRowMode = this.arrayRowMode
|
|
295
296
|
req.input('handle', TYPES.Int, this._handle)
|
|
296
297
|
|
|
297
298
|
// copy parameters with new values
|
package/lib/base/request.js
CHANGED
|
@@ -224,6 +224,7 @@ class Request extends EventEmitter {
|
|
|
224
224
|
|
|
225
225
|
batch (batch, callback) {
|
|
226
226
|
if (this.stream == null && this.connection) this.stream = this.connection.config.stream
|
|
227
|
+
if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
|
|
227
228
|
this.rowsAffected = 0
|
|
228
229
|
|
|
229
230
|
if (typeof callback === 'function') {
|
|
@@ -316,6 +317,7 @@ class Request extends EventEmitter {
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
if (this.stream == null && this.connection) this.stream = this.connection.config.stream
|
|
320
|
+
if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
|
|
319
321
|
|
|
320
322
|
if (this.stream || typeof callback === 'function') {
|
|
321
323
|
this._bulk(table, options, (err, rowsAffected) => {
|
|
@@ -392,10 +394,11 @@ class Request extends EventEmitter {
|
|
|
392
394
|
|
|
393
395
|
query (command, callback) {
|
|
394
396
|
if (this.stream == null && this.connection) this.stream = this.connection.config.stream
|
|
397
|
+
if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
|
|
395
398
|
this.rowsAffected = 0
|
|
396
399
|
|
|
397
400
|
if (typeof callback === 'function') {
|
|
398
|
-
this._query(command, (err, recordsets, output, rowsAffected) => {
|
|
401
|
+
this._query(command, (err, recordsets, output, rowsAffected, columns) => {
|
|
399
402
|
if (this.stream) {
|
|
400
403
|
if (err) this.emit('error', err)
|
|
401
404
|
err = null
|
|
@@ -407,12 +410,14 @@ class Request extends EventEmitter {
|
|
|
407
410
|
}
|
|
408
411
|
|
|
409
412
|
if (err) return callback(err)
|
|
410
|
-
|
|
413
|
+
const result = {
|
|
411
414
|
recordsets,
|
|
412
415
|
recordset: recordsets && recordsets[0],
|
|
413
416
|
output,
|
|
414
417
|
rowsAffected
|
|
415
|
-
}
|
|
418
|
+
}
|
|
419
|
+
if (this.arrayRowMode) result.columns = columns
|
|
420
|
+
callback(null, result)
|
|
416
421
|
})
|
|
417
422
|
return this
|
|
418
423
|
}
|
|
@@ -425,7 +430,7 @@ class Request extends EventEmitter {
|
|
|
425
430
|
}
|
|
426
431
|
|
|
427
432
|
return new shared.Promise((resolve, reject) => {
|
|
428
|
-
this._query(command, (err, recordsets, output, rowsAffected) => {
|
|
433
|
+
this._query(command, (err, recordsets, output, rowsAffected, columns) => {
|
|
429
434
|
if (this.stream) {
|
|
430
435
|
if (err) this.emit('error', err)
|
|
431
436
|
err = null
|
|
@@ -437,12 +442,14 @@ class Request extends EventEmitter {
|
|
|
437
442
|
}
|
|
438
443
|
|
|
439
444
|
if (err) return reject(err)
|
|
440
|
-
|
|
445
|
+
const result = {
|
|
441
446
|
recordsets,
|
|
442
447
|
recordset: recordsets && recordsets[0],
|
|
443
448
|
output,
|
|
444
449
|
rowsAffected
|
|
445
|
-
}
|
|
450
|
+
}
|
|
451
|
+
if (this.arrayRowMode) result.columns = columns
|
|
452
|
+
resolve(result)
|
|
446
453
|
})
|
|
447
454
|
})
|
|
448
455
|
}
|
|
@@ -476,10 +483,11 @@ class Request extends EventEmitter {
|
|
|
476
483
|
|
|
477
484
|
execute (command, callback) {
|
|
478
485
|
if (this.stream == null && this.connection) this.stream = this.connection.config.stream
|
|
486
|
+
if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
|
|
479
487
|
this.rowsAffected = 0
|
|
480
488
|
|
|
481
489
|
if (typeof callback === 'function') {
|
|
482
|
-
this._execute(command, (err, recordsets, output, returnValue, rowsAffected) => {
|
|
490
|
+
this._execute(command, (err, recordsets, output, returnValue, rowsAffected, columns) => {
|
|
483
491
|
if (this.stream) {
|
|
484
492
|
if (err) this.emit('error', err)
|
|
485
493
|
err = null
|
|
@@ -492,19 +500,21 @@ class Request extends EventEmitter {
|
|
|
492
500
|
}
|
|
493
501
|
|
|
494
502
|
if (err) return callback(err)
|
|
495
|
-
|
|
503
|
+
const result = {
|
|
496
504
|
recordsets,
|
|
497
505
|
recordset: recordsets && recordsets[0],
|
|
498
506
|
output,
|
|
499
507
|
rowsAffected,
|
|
500
508
|
returnValue
|
|
501
|
-
}
|
|
509
|
+
}
|
|
510
|
+
if (this.arrayRowMode) result.columns = columns
|
|
511
|
+
callback(null, result)
|
|
502
512
|
})
|
|
503
513
|
return this
|
|
504
514
|
}
|
|
505
515
|
|
|
506
516
|
return new shared.Promise((resolve, reject) => {
|
|
507
|
-
this._execute(command, (err, recordsets, output, returnValue, rowsAffected) => {
|
|
517
|
+
this._execute(command, (err, recordsets, output, returnValue, rowsAffected, columns) => {
|
|
508
518
|
if (this.stream) {
|
|
509
519
|
if (err) this.emit('error', err)
|
|
510
520
|
err = null
|
|
@@ -517,13 +527,15 @@ class Request extends EventEmitter {
|
|
|
517
527
|
}
|
|
518
528
|
|
|
519
529
|
if (err) return reject(err)
|
|
520
|
-
|
|
530
|
+
const result = {
|
|
521
531
|
recordsets,
|
|
522
532
|
recordset: recordsets && recordsets[0],
|
|
523
533
|
output,
|
|
524
534
|
rowsAffected,
|
|
525
535
|
returnValue
|
|
526
|
-
}
|
|
536
|
+
}
|
|
537
|
+
if (this.arrayRowMode) result.columns = columns
|
|
538
|
+
resolve(result)
|
|
527
539
|
})
|
|
528
540
|
})
|
|
529
541
|
}
|
package/lib/global-connection.js
CHANGED
|
@@ -48,7 +48,18 @@ function connect (config, callback) {
|
|
|
48
48
|
|
|
49
49
|
globalConnection.close = globalClose.bind(globalConnection)
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
if (typeof callback === 'function') {
|
|
52
|
+
return globalConnection.connect((err, connection) => {
|
|
53
|
+
if (err) {
|
|
54
|
+
globalConnection = null
|
|
55
|
+
}
|
|
56
|
+
callback(err, connection)
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
return globalConnection.connect().catch((err) => {
|
|
60
|
+
globalConnection = null
|
|
61
|
+
return shared.Promise.reject(err)
|
|
62
|
+
})
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
/**
|
|
@@ -88,11 +88,13 @@ const castParameter = function (value, type) {
|
|
|
88
88
|
return value
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
const createColumns = function (metadata) {
|
|
92
|
-
|
|
91
|
+
const createColumns = function (metadata, arrayRowMode) {
|
|
92
|
+
let out = {}
|
|
93
|
+
if (arrayRowMode) out = []
|
|
93
94
|
for (let index = 0, length = metadata.length; index < length; index++) {
|
|
94
95
|
const column = metadata[index]
|
|
95
|
-
|
|
96
|
+
const colName = column.name
|
|
97
|
+
const outColumn = {
|
|
96
98
|
index,
|
|
97
99
|
name: column.name,
|
|
98
100
|
length: column.size,
|
|
@@ -101,14 +103,19 @@ const createColumns = function (metadata) {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
if (column.udtType != null) {
|
|
104
|
-
|
|
106
|
+
outColumn.udt = {
|
|
105
107
|
name: column.udtType
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
if (DECLARATIONS[column.udtType]) {
|
|
109
|
-
|
|
111
|
+
outColumn.type = DECLARATIONS[column.udtType]
|
|
110
112
|
}
|
|
111
113
|
}
|
|
114
|
+
if (arrayRowMode) {
|
|
115
|
+
out.push(outColumn)
|
|
116
|
+
} else {
|
|
117
|
+
out[colName] = outColumn
|
|
118
|
+
}
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
return out
|
|
@@ -236,6 +243,7 @@ class Request extends BaseRequest {
|
|
|
236
243
|
}
|
|
237
244
|
|
|
238
245
|
const recordsets = []
|
|
246
|
+
const recordsetcolumns = []
|
|
239
247
|
const errors = []
|
|
240
248
|
const errorHandlers = {}
|
|
241
249
|
const output = {}
|
|
@@ -396,11 +404,10 @@ class Request extends BaseRequest {
|
|
|
396
404
|
}
|
|
397
405
|
|
|
398
406
|
chunksBuffer = null
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (this.stream && !this.paused) this.emit('row', row)
|
|
407
|
+
if (row && row.___return___ == null) {
|
|
408
|
+
// row with ___return___ col is the last row
|
|
409
|
+
if (this.stream && !this.paused) this.emit('row', row)
|
|
410
|
+
}
|
|
404
411
|
}
|
|
405
412
|
}
|
|
406
413
|
|
|
@@ -411,7 +418,7 @@ class Request extends BaseRequest {
|
|
|
411
418
|
Object.defineProperty(recordset, 'columns', {
|
|
412
419
|
enumerable: false,
|
|
413
420
|
configurable: true,
|
|
414
|
-
value: createColumns(metadata)
|
|
421
|
+
value: createColumns(metadata, this.arrayRowMode)
|
|
415
422
|
})
|
|
416
423
|
|
|
417
424
|
Object.defineProperty(recordset, 'toTable', {
|
|
@@ -426,27 +433,36 @@ class Request extends BaseRequest {
|
|
|
426
433
|
chunksBuffer = []
|
|
427
434
|
}
|
|
428
435
|
|
|
436
|
+
let hasReturnColumn = false
|
|
437
|
+
if (recordset.columns.___return___ != null) {
|
|
438
|
+
hasReturnColumn = true
|
|
439
|
+
} else if (this.arrayRowMode) {
|
|
440
|
+
for (let i = 0; i < columns.length; i++) {
|
|
441
|
+
if (columns[i].name === '___return___') {
|
|
442
|
+
hasReturnColumn = true
|
|
443
|
+
break
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
429
447
|
if (this.stream) {
|
|
430
|
-
if (
|
|
448
|
+
if (!hasReturnColumn) {
|
|
431
449
|
this.emit('recordset', recordset.columns)
|
|
432
450
|
}
|
|
433
451
|
} else {
|
|
434
452
|
recordsets.push(recordset)
|
|
435
453
|
}
|
|
454
|
+
if (this.arrayRowMode) recordsetcolumns.push(recordset.columns)
|
|
436
455
|
})
|
|
437
456
|
|
|
438
457
|
req.on('row', rownumber => {
|
|
439
|
-
if (row)
|
|
440
|
-
if (isChunkedRecordset) return
|
|
458
|
+
if (row && isChunkedRecordset) return
|
|
441
459
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
460
|
+
if (this.arrayRowMode) {
|
|
461
|
+
row = []
|
|
462
|
+
} else {
|
|
463
|
+
row = {}
|
|
446
464
|
}
|
|
447
465
|
|
|
448
|
-
row = {}
|
|
449
|
-
|
|
450
466
|
if (!this.stream) recordset.push(row)
|
|
451
467
|
})
|
|
452
468
|
|
|
@@ -456,15 +472,35 @@ class Request extends BaseRequest {
|
|
|
456
472
|
} else {
|
|
457
473
|
data = valueCorrection(data, columns[idx])
|
|
458
474
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
475
|
+
if (this.arrayRowMode) {
|
|
476
|
+
row.push(data)
|
|
477
|
+
} else {
|
|
478
|
+
const exi = row[columns[idx].name]
|
|
479
|
+
if (exi != null) {
|
|
480
|
+
if (exi instanceof Array) {
|
|
481
|
+
exi.push(data)
|
|
482
|
+
} else {
|
|
483
|
+
row[columns[idx].name] = [exi, data]
|
|
484
|
+
}
|
|
463
485
|
} else {
|
|
464
|
-
row[columns[idx].name] =
|
|
486
|
+
row[columns[idx].name] = data
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
let hasReturnColumn = false
|
|
490
|
+
if (row && row.___return___ != null) {
|
|
491
|
+
hasReturnColumn = true
|
|
492
|
+
} else if (this.arrayRowMode) {
|
|
493
|
+
for (let i = 0; i < columns.length; i++) {
|
|
494
|
+
if (columns[i].name === '___return___') {
|
|
495
|
+
hasReturnColumn = true
|
|
496
|
+
break
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (!hasReturnColumn) {
|
|
501
|
+
if (this.stream && !this.paused && idx === columns.length - 1) {
|
|
502
|
+
this.emit('row', row)
|
|
465
503
|
}
|
|
466
|
-
} else {
|
|
467
|
-
row[columns[idx].name] = data
|
|
468
504
|
}
|
|
469
505
|
}
|
|
470
506
|
})
|
|
@@ -487,6 +523,14 @@ class Request extends BaseRequest {
|
|
|
487
523
|
serverName: msg.serverName,
|
|
488
524
|
procName: msg.procName
|
|
489
525
|
})
|
|
526
|
+
|
|
527
|
+
// query terminated
|
|
528
|
+
if (msg.code === 3621 && !hasReturned) {
|
|
529
|
+
// if the query has been terminated it's probably best to throw the last meaningful error if there was one
|
|
530
|
+
// pop it off the errors array so it doesn't get put in twice
|
|
531
|
+
const error = errors.length > 0 ? errors.pop() : msg
|
|
532
|
+
handleError(req, connection, error.originalError || error, false)
|
|
533
|
+
}
|
|
490
534
|
})
|
|
491
535
|
|
|
492
536
|
req.on('error', errorHandlers.error = handleError.bind(null, req, connection))
|
|
@@ -525,11 +569,10 @@ class Request extends BaseRequest {
|
|
|
525
569
|
}
|
|
526
570
|
|
|
527
571
|
chunksBuffer = null
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (this.stream && !this.paused) { this.emit('row', row) }
|
|
572
|
+
if (row && row.___return___ == null) {
|
|
573
|
+
// row with ___return___ col is the last row
|
|
574
|
+
if (this.stream && !this.paused) { this.emit('row', row) }
|
|
575
|
+
}
|
|
533
576
|
}
|
|
534
577
|
}
|
|
535
578
|
|
|
@@ -555,9 +598,9 @@ class Request extends BaseRequest {
|
|
|
555
598
|
debug('request(%d): completed', IDS.get(this))
|
|
556
599
|
|
|
557
600
|
if (this.stream) {
|
|
558
|
-
callback(null, this._nested ? row : null, output, rowsAffected)
|
|
601
|
+
callback(null, this._nested ? row : null, output, rowsAffected, recordsetcolumns)
|
|
559
602
|
} else {
|
|
560
|
-
callback(null, recordsets, output, rowsAffected)
|
|
603
|
+
callback(null, recordsets, output, rowsAffected, recordsetcolumns)
|
|
561
604
|
}
|
|
562
605
|
})
|
|
563
606
|
})
|
|
@@ -614,7 +657,7 @@ class Request extends BaseRequest {
|
|
|
614
657
|
|
|
615
658
|
this._nested = true
|
|
616
659
|
|
|
617
|
-
this._query(cmd, (err, recordsets, output, rowsAffected) => {
|
|
660
|
+
this._query(cmd, (err, recordsets, output, rowsAffected, recordsetcolumns) => {
|
|
618
661
|
this._nested = false
|
|
619
662
|
|
|
620
663
|
if (err) return callback(err)
|
|
@@ -626,25 +669,49 @@ class Request extends BaseRequest {
|
|
|
626
669
|
last = recordsets.pop()
|
|
627
670
|
if (last) last = last[0]
|
|
628
671
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
672
|
+
const lastColumns = recordsetcolumns.pop()
|
|
673
|
+
|
|
674
|
+
if (last && this.arrayRowMode && lastColumns) {
|
|
675
|
+
let returnColumnIdx = null
|
|
676
|
+
const parametersNameToLastIdxDict = {}
|
|
677
|
+
for (let i = 0; i < lastColumns.length; i++) {
|
|
678
|
+
if (lastColumns[i].name === '___return___') {
|
|
679
|
+
returnColumnIdx = i
|
|
680
|
+
} else if (objectHasProperty(this.parameters, lastColumns[i].name)) {
|
|
681
|
+
parametersNameToLastIdxDict[lastColumns[i].name] = i
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (returnColumnIdx != null) {
|
|
685
|
+
returnValue = last[returnColumnIdx]
|
|
686
|
+
}
|
|
687
|
+
for (const name in parametersNameToLastIdxDict) {
|
|
688
|
+
if (!objectHasProperty(parametersNameToLastIdxDict, name)) {
|
|
635
689
|
continue
|
|
636
690
|
}
|
|
637
691
|
const param = this.parameters[name]
|
|
638
692
|
if (param.io === 2) {
|
|
639
|
-
output[param.name] = last[
|
|
693
|
+
output[param.name] = last[parametersNameToLastIdxDict[name]]
|
|
640
694
|
}
|
|
641
695
|
}
|
|
642
|
-
}
|
|
696
|
+
} else {
|
|
697
|
+
if (last && (last.___return___ != null)) {
|
|
698
|
+
returnValue = last.___return___
|
|
643
699
|
|
|
700
|
+
for (const name in this.parameters) {
|
|
701
|
+
if (!objectHasProperty(this.parameters, name)) {
|
|
702
|
+
continue
|
|
703
|
+
}
|
|
704
|
+
const param = this.parameters[name]
|
|
705
|
+
if (param.io === 2) {
|
|
706
|
+
output[param.name] = last[param.name]
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
644
711
|
if (this.stream) {
|
|
645
|
-
callback(null, null, output, returnValue, rowsAffected)
|
|
712
|
+
callback(null, null, output, returnValue, rowsAffected, recordsetcolumns)
|
|
646
713
|
} else {
|
|
647
|
-
callback(null, recordsets, output, returnValue, rowsAffected)
|
|
714
|
+
callback(null, recordsets, output, returnValue, rowsAffected, recordsetcolumns)
|
|
648
715
|
}
|
|
649
716
|
})
|
|
650
717
|
})
|
package/lib/tedious/request.js
CHANGED
|
@@ -117,11 +117,12 @@ const getMssqlType = function (type, length) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
const createColumns = function (metadata) {
|
|
121
|
-
|
|
120
|
+
const createColumns = function (metadata, arrayRowMode) {
|
|
121
|
+
let out = {}
|
|
122
|
+
if (arrayRowMode) out = []
|
|
122
123
|
for (let index = 0, length = metadata.length; index < length; index++) {
|
|
123
124
|
const column = metadata[index]
|
|
124
|
-
|
|
125
|
+
const outColumn = {
|
|
125
126
|
index,
|
|
126
127
|
name: column.colName,
|
|
127
128
|
length: column.dataLength,
|
|
@@ -135,7 +136,7 @@ const createColumns = function (metadata) {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
if (column.udtInfo) {
|
|
138
|
-
|
|
139
|
+
outColumn.udt = {
|
|
139
140
|
name: column.udtInfo.typeName,
|
|
140
141
|
database: column.udtInfo.dbname,
|
|
141
142
|
schema: column.udtInfo.owningSchema,
|
|
@@ -143,9 +144,15 @@ const createColumns = function (metadata) {
|
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
if (DECLARATIONS[column.udtInfo.typeName]) {
|
|
146
|
-
|
|
147
|
+
outColumn.type = DECLARATIONS[column.udtInfo.typeName]
|
|
147
148
|
}
|
|
148
149
|
}
|
|
150
|
+
|
|
151
|
+
if (arrayRowMode) {
|
|
152
|
+
out.push(outColumn)
|
|
153
|
+
} else {
|
|
154
|
+
out[column.colName] = outColumn
|
|
155
|
+
}
|
|
149
156
|
}
|
|
150
157
|
|
|
151
158
|
return out
|
|
@@ -347,6 +354,7 @@ class Request extends BaseRequest {
|
|
|
347
354
|
if (err) return callback(err)
|
|
348
355
|
|
|
349
356
|
const recordsets = []
|
|
357
|
+
const recordsetcolumns = []
|
|
350
358
|
const errors = []
|
|
351
359
|
const errorHandlers = {}
|
|
352
360
|
const output = {}
|
|
@@ -466,9 +474,9 @@ class Request extends BaseRequest {
|
|
|
466
474
|
}
|
|
467
475
|
|
|
468
476
|
if (this.stream) {
|
|
469
|
-
callback(null, null, output, rowsAffected)
|
|
477
|
+
callback(null, null, output, rowsAffected, recordsetcolumns)
|
|
470
478
|
} else {
|
|
471
|
-
callback(error, recordsets, output, rowsAffected)
|
|
479
|
+
callback(error, recordsets, output, rowsAffected, recordsetcolumns)
|
|
472
480
|
}
|
|
473
481
|
}
|
|
474
482
|
})
|
|
@@ -476,7 +484,7 @@ class Request extends BaseRequest {
|
|
|
476
484
|
this._setCurrentRequest(req)
|
|
477
485
|
|
|
478
486
|
req.on('columnMetadata', metadata => {
|
|
479
|
-
columns = createColumns(metadata)
|
|
487
|
+
columns = createColumns(metadata, this.arrayRowMode)
|
|
480
488
|
|
|
481
489
|
isChunkedRecordset = false
|
|
482
490
|
if (metadata.length === 1 && (metadata[0].colName === JSON_COLUMN_ID || metadata[0].colName === XML_COLUMN_ID)) {
|
|
@@ -494,6 +502,7 @@ class Request extends BaseRequest {
|
|
|
494
502
|
this.emit('recordset', columns)
|
|
495
503
|
}
|
|
496
504
|
}
|
|
505
|
+
if (this.arrayRowMode) recordsetcolumns.push(columns)
|
|
497
506
|
})
|
|
498
507
|
|
|
499
508
|
const doneHandler = (rowCount, more) => {
|
|
@@ -568,19 +577,27 @@ class Request extends BaseRequest {
|
|
|
568
577
|
return chunksBuffer.push(columns[0].value)
|
|
569
578
|
}
|
|
570
579
|
|
|
571
|
-
|
|
580
|
+
if (this.arrayRowMode) {
|
|
581
|
+
row = []
|
|
582
|
+
} else {
|
|
583
|
+
row = {}
|
|
584
|
+
}
|
|
572
585
|
for (const col of columns) {
|
|
573
586
|
col.value = valueCorrection(col.value, col.metadata)
|
|
574
587
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
588
|
+
if (this.arrayRowMode) {
|
|
589
|
+
row.push(col.value)
|
|
590
|
+
} else {
|
|
591
|
+
const exi = row[col.metadata.colName]
|
|
592
|
+
if (exi != null) {
|
|
593
|
+
if (exi instanceof Array) {
|
|
594
|
+
exi.push(col.value)
|
|
595
|
+
} else {
|
|
596
|
+
row[col.metadata.colName] = [exi, col.value]
|
|
597
|
+
}
|
|
579
598
|
} else {
|
|
580
|
-
row[col.metadata.colName] =
|
|
599
|
+
row[col.metadata.colName] = col.value
|
|
581
600
|
}
|
|
582
|
-
} else {
|
|
583
|
-
row[col.metadata.colName] = col.value
|
|
584
601
|
}
|
|
585
602
|
}
|
|
586
603
|
|
|
@@ -684,6 +701,7 @@ class Request extends BaseRequest {
|
|
|
684
701
|
if (err) return callback(err)
|
|
685
702
|
|
|
686
703
|
const recordsets = []
|
|
704
|
+
const recordsetcolumns = []
|
|
687
705
|
const errors = []
|
|
688
706
|
const errorHandlers = {}
|
|
689
707
|
const output = {}
|
|
@@ -800,9 +818,9 @@ class Request extends BaseRequest {
|
|
|
800
818
|
}
|
|
801
819
|
|
|
802
820
|
if (this.stream) {
|
|
803
|
-
callback(null, null, output, returnValue, rowsAffected)
|
|
821
|
+
callback(null, null, output, returnValue, rowsAffected, recordsetcolumns)
|
|
804
822
|
} else {
|
|
805
|
-
callback(error, recordsets, output, returnValue, rowsAffected)
|
|
823
|
+
callback(error, recordsets, output, returnValue, rowsAffected, recordsetcolumns)
|
|
806
824
|
}
|
|
807
825
|
}
|
|
808
826
|
})
|
|
@@ -810,7 +828,7 @@ class Request extends BaseRequest {
|
|
|
810
828
|
this._setCurrentRequest(req)
|
|
811
829
|
|
|
812
830
|
req.on('columnMetadata', metadata => {
|
|
813
|
-
columns = createColumns(metadata)
|
|
831
|
+
columns = createColumns(metadata, this.arrayRowMode)
|
|
814
832
|
|
|
815
833
|
isChunkedRecordset = false
|
|
816
834
|
if ((metadata.length === 1) && (metadata[0].colName === JSON_COLUMN_ID || metadata[0].colName === XML_COLUMN_ID)) {
|
|
@@ -819,6 +837,7 @@ class Request extends BaseRequest {
|
|
|
819
837
|
}
|
|
820
838
|
|
|
821
839
|
if (this.stream) this.emit('recordset', columns)
|
|
840
|
+
if (this.arrayRowMode) recordsetcolumns.push(columns)
|
|
822
841
|
})
|
|
823
842
|
|
|
824
843
|
req.on('row', columns => {
|
|
@@ -828,19 +847,27 @@ class Request extends BaseRequest {
|
|
|
828
847
|
return chunksBuffer.push(columns[0].value)
|
|
829
848
|
}
|
|
830
849
|
|
|
831
|
-
|
|
850
|
+
if (this.arrayRowMode) {
|
|
851
|
+
row = []
|
|
852
|
+
} else {
|
|
853
|
+
row = {}
|
|
854
|
+
}
|
|
832
855
|
for (const col of columns) {
|
|
833
856
|
col.value = valueCorrection(col.value, col.metadata)
|
|
834
857
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
858
|
+
if (this.arrayRowMode) {
|
|
859
|
+
row.push(col.value)
|
|
860
|
+
} else {
|
|
861
|
+
const exi = row[col.metadata.colName]
|
|
862
|
+
if (exi != null) {
|
|
863
|
+
if (exi instanceof Array) {
|
|
864
|
+
exi.push(col.value)
|
|
865
|
+
} else {
|
|
866
|
+
row[col.metadata.colName] = [exi, col.value]
|
|
867
|
+
}
|
|
839
868
|
} else {
|
|
840
|
-
row[col.metadata.colName] =
|
|
869
|
+
row[col.metadata.colName] = col.value
|
|
841
870
|
}
|
|
842
|
-
} else {
|
|
843
|
-
row[col.metadata.colName] = col.value
|
|
844
871
|
}
|
|
845
872
|
}
|
|
846
873
|
|
package/lib/udt.js
CHANGED
|
@@ -271,7 +271,7 @@ const parseGeography = buffer => {
|
|
|
271
271
|
|
|
272
272
|
// console.log( "shapes", shapes)
|
|
273
273
|
|
|
274
|
-
if (value.version === 2) {
|
|
274
|
+
if (value.version === 2 && buffer.position < buffer.length) {
|
|
275
275
|
const numberOfSegments = buffer.readUInt32LE(buffer.position)
|
|
276
276
|
buffer.position += 4
|
|
277
277
|
|
package/package.json
CHANGED
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
"azure",
|
|
22
22
|
"node-mssql"
|
|
23
23
|
],
|
|
24
|
-
"version": "6.
|
|
24
|
+
"version": "6.3.2",
|
|
25
25
|
"main": "index.js",
|
|
26
26
|
"repository": "github:tediousjs/node-mssql",
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"debug": "^4",
|
|
29
|
+
"debug": "^4.3.1",
|
|
30
30
|
"tarn": "^1.1.5",
|
|
31
|
-
"tedious": "^6.
|
|
31
|
+
"tedious": "^6.7.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"mocha": "^6.2.
|
|
35
|
-
"standard": "^14"
|
|
34
|
+
"mocha": "^6.2.3",
|
|
35
|
+
"standard": "^14.3.4"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=6"
|
package/test.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const mssql = require('./')
|
|
4
|
+
const wtf = require('wtfnode');
|
|
4
5
|
|
|
5
6
|
const sqlConfig = {
|
|
6
|
-
password: '
|
|
7
|
+
password: '&r8wrucH',
|
|
7
8
|
database: 'StockDB',
|
|
8
9
|
stream: false,
|
|
9
10
|
options: {
|
|
10
|
-
trustServerCertificate: true,
|
|
11
|
+
// trustServerCertificate: true,
|
|
11
12
|
enableArithAbort: true,
|
|
12
13
|
encrypt: true,
|
|
13
14
|
abortTransactionOnError: false,
|
|
@@ -17,27 +18,23 @@ const sqlConfig = {
|
|
|
17
18
|
min: 0,
|
|
18
19
|
},
|
|
19
20
|
port: 1433,
|
|
20
|
-
user: '
|
|
21
|
-
server: '
|
|
21
|
+
user: 'dhensby',
|
|
22
|
+
server: '4sa.database.windows.net',
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
// Bad URI, connection timeouts, hangs process
|
|
26
|
+
mssql.connect({ ...sqlConfig, port: 2345 }).catch(err => {
|
|
27
|
+
console.error(err.message);
|
|
28
|
+
console.log('reconnecting...');
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.timeEnd('query')
|
|
38
|
-
} finally {
|
|
39
|
-
await client.close()
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
run()
|
|
30
|
+
// Try to connect using the right URI
|
|
31
|
+
return mssql
|
|
32
|
+
.connect(sqlConfig)
|
|
33
|
+
.then(() => console.log('connected'))
|
|
34
|
+
.then(() => mssql.close())
|
|
35
|
+
.then(() => console.log('closed'))
|
|
36
|
+
.catch(err => {
|
|
37
|
+
console.error(err.message)
|
|
38
|
+
wtf.dump()
|
|
39
|
+
}); // <-- Fails here
|
|
40
|
+
});
|