mssql 7.1.2 → 7.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/CHANGELOG.txt CHANGED
@@ -1,10 +1,26 @@
1
+ v7.3.0 (2021-11-18)
2
+ -------------------
3
+ [new] Transaction/PreparedStatements expose the config from their parent connection
4
+ [fix] Fix inherited request configs from the pool. Specifically stream and arrayRowMode now inherit accurately from the connection config ([#1338](https://github.com/tediousjs/node-mssql/pull/1338))
5
+
6
+ v7.2.1 (2021-08-19)
7
+ -------------------
8
+ [fix] Fix issue with bulk insert of dates ((#1298)[https://github.com/tediousjs/node-mssql/pull/1298])
9
+
10
+ v7.2.0 (2021-07-29)
11
+ -------------------
12
+ [new] Update Geography field parsing to provide lat/lng props from Geography Point ((#1282)[https://github.com/tediousjs/node-mssql/pull/1282])
13
+ [fix] Handle errors when adding rows to bulk operations ((#1264)[https://github.com/tediousjs/node-mssql/pull/1264])
14
+ [fix] Input/Output parameter passing fix for msnodesqlv8 driver ((#1275)[https://github.com/tediousjs/node-mssql/pull/1275])
15
+
16
+ v7.1.3 (2021-06-11)
17
+ -------------------
18
+ [fix] Request timeout settings now respect value parsed from connection strings ((#1257)[https://github.com/tediousjs/node-mssql/pull/1257)
19
+
1
20
  v7.1.1 (2021-06-09)
2
21
  -------------------
3
- [fix] Errors from tedious connection creation now cause connection promise to
4
- reject ((#1254)[https://github.com/tediousjs/node-mssql/pull/1254])
5
- [fix] Encrypt and transaction binding settings now respect value parsed from
6
- connection strings
7
- ((#1252)[https://github.com/tediousjs/node-mssql/pull/1252)
22
+ [fix] Errors from tedious connection creation now cause connection promise to reject ((#1254)[https://github.com/tediousjs/node-mssql/pull/1254])
23
+ [fix] Encrypt and transaction binding settings now respect value parsed from connection strings ((#1252)[https://github.com/tediousjs/node-mssql/pull/1252)
8
24
 
9
25
  v7.1.0 (2021-05-13)
10
26
  -------------------
@@ -31,7 +47,12 @@ v7.0.0 (2021-05-06)
31
47
  [fix] Trailing rows from request streams using msnodesqlv8 driver fail to be emitted ([#1109](https://github.com/tediousjs/node-mssql/pull/1109))
32
48
  [fix] Issue with geography v2 parsing resolve ([#1138](https://github.com/tediousjs/node-mssql/pull/1138))
33
49
  [fix] Connection config objects are now deep cloned when stored against a connection pool ([#1217](https://github.com/tediousjs/node-mssql/pull/1217))
34
- [removed] Support for connection uri format has been removed (eg: `mssql://user:password@host/?params=values`
50
+ [removed] Support for connection uri format has been removed (eg: `mssql://user:password@host/?params=values`)
51
+
52
+ v6.4.0 (2021-11-18)
53
+ -------------------
54
+ [new] Transaction/PreparedStatements expose the config from their parent connection
55
+ [fix] Fix inherited request configs from the pool. Specifically stream and arrayRowMode now inherit accurately from the connection config ([#1338](https://github.com/tediousjs/node-mssql/pull/1338))
35
56
 
36
57
  v6.3.2 (2021-05-13)
37
58
  -------------------
package/README.md CHANGED
@@ -140,7 +140,7 @@ async () => {
140
140
  * [SQL injection](#sql-injection)
141
141
  * [Known Issues](#known-issues)
142
142
  * [Contributing](https://github.com/tediousjs/node-mssql/wiki/Contributing)
143
- * [6.x to 7.x changes (pre-release)](#6x-to-7x-changes-pre-release)
143
+ * [6.x to 7.x changes](#6x-to-7x-changes)
144
144
  * [5.x to 6.x changes](#5x-to-6x-changes)
145
145
  * [4.x to 5.x changes](#4x-to-5x-changes)
146
146
  * [3.x to 4.x changes](#3x-to-4x-changes)
@@ -693,11 +693,14 @@ require('mssql').connect({...config, beforeConnect: conn => {
693
693
  - **options.tdsVersion** - The version of TDS to use (default: `7_4`, available: `7_1`, `7_2`, `7_3_A`, `7_3_B`, `7_4`).
694
694
  - **options.appName** - Application name used for SQL server logging.
695
695
  - **options.abortTransactionOnError** - A boolean determining whether to rollback a transaction automatically if any error is encountered during the given transaction's execution. This sets the value for `XACT_ABORT` during the initial SQL phase of a connection.
696
- - **options.authentication** - An object with authentication settings, according to the [Tedious Documentation](https://tediousjs.github.io/tedious/api-connection.html). Passing this object will override `options.user`, `options.password`, `options.domain` settings.
697
- - **options.authentication.type** - Type of the authentication method, valid types are `default`, `ntlm`, `azure-active-directory-password`, `azure-active-directory-access-token`, `azure-active-directory-msi-vm`, or `azure-active-directory-msi-app-service`
698
- - **options.authentication.options** - Options of the authentication required by the `tedious` driver, depends on `options.authentication.type`. For more details, check [Tedious Authentication Interfaces](https://github.com/tediousjs/tedious/blob/master/src/connection.ts#L237)
699
696
 
697
+ **Authentication:**
700
698
 
699
+ On top of the extra options, an `authentication` property can be added to the pool config option
700
+
701
+ - **authentication** - An object with authentication settings, according to the [Tedious Documentation](https://tediousjs.github.io/tedious/api-connection.html). Passing this object will override `user`, `password`, `domain` settings.
702
+ - **authentication.type** - Type of the authentication method, valid types are `default`, `ntlm`, `azure-active-directory-password`, `azure-active-directory-access-token`, `azure-active-directory-msi-vm`, or `azure-active-directory-msi-app-service`
703
+ - **authentication.options** - Options of the authentication required by the `tedious` driver, depends on `authentication.type`. For more details, check [Tedious Authentication Interfaces](https://github.com/tediousjs/tedious/blob/v11.1.1/src/connection.ts#L200-L318)
701
704
 
702
705
  More information about Tedious specific options: http://tediousjs.github.io/tedious/api-connection.html
703
706
 
@@ -1511,32 +1514,65 @@ If you omit config path argument, mssql will try to load it from current working
1511
1514
 
1512
1515
  ## Geography and Geometry
1513
1516
 
1514
- node-mssql has built-in serializer for Geography and Geometry CLR data types.
1517
+ node-mssql has built-in deserializer for Geography and Geometry CLR data types.
1518
+
1519
+ ### Geography
1520
+
1521
+ Geography types can be constructed several different ways. Refer carefully to documentation to verify the coordinate ordering; the ST methods tend to order parameters as longitude (x) then latitude (y), while custom CLR methods tend to prefer to order them as latitude (y) then longitude (x).
1522
+
1523
+ The query:
1515
1524
 
1516
1525
  ```sql
1517
- select geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326)
1518
- select geometry::STGeomFromText('LINESTRING (100 100 10.3 12, 20 180, 180 180)', 0)
1526
+ select geography::STGeomFromText(N'POLYGON((1 1, 3 1, 3 1, 1 1))',4326)
1519
1527
  ```
1520
1528
 
1521
- Results in:
1529
+ results in:
1522
1530
 
1523
1531
  ```javascript
1524
- { srid: 4326,
1525
- version: 1,
1526
- points: [ { x: 47.656, y: -122.36 }, { x: 47.656, y: -122.343 } ],
1532
+ {
1533
+ srid: 4326,
1534
+ version: 2,
1535
+ points: [
1536
+ Point { lat: 1, lng: 1, z: null, m: null },
1537
+ Point { lat: 1, lng: 3, z: null, m: null },
1538
+ Point { lat: 1, lng: 3, z: null, m: null },
1539
+ Point { lat: 1, lng: 1, z: null, m: null }
1540
+ ],
1527
1541
  figures: [ { attribute: 1, pointOffset: 0 } ],
1528
- shapes: [ { parentOffset: -1, figureOffset: 0, type: 2 } ],
1529
- segments: [] }
1542
+ shapes: [ { parentOffset: -1, figureOffset: 0, type: 3 } ],
1543
+ segments: []
1544
+ }
1545
+ ```
1546
+
1547
+ **NOTE:** You will also see `x` and `y` coordinates in parsed Geography points,
1548
+ they are not recommended for use. They have thus been omitted from this example.
1549
+ For compatibility, they remain flipped (x, the horizontal offset, is instead used for latitude, the vertical), and thus risk misleading you.
1550
+ Prefer instead to use the `lat` and `lng` properties.
1530
1551
 
1531
- { srid: 0,
1552
+ ### Geometry
1553
+
1554
+ Geometry types can also be constructed in several ways. Unlike Geographies, they are consistent in always placing x before y. node-mssql decodes the result of this query:
1555
+
1556
+ ```sql
1557
+ select geometry::STGeomFromText(N'POLYGON((1 1, 3 1, 3 7, 1 1))',4326)
1558
+ ```
1559
+
1560
+ into the JavaScript object:
1561
+
1562
+ ```javascript
1563
+ {
1564
+ srid: 4326,
1532
1565
  version: 1,
1533
- points:
1534
- [ { x: 100, y: 100, z: 10.3, m: 12 },
1535
- { x: 20, y: 180, z: NaN, m: NaN },
1536
- { x: 180, y: 180, z: NaN, m: NaN } ],
1537
- figures: [ { attribute: 1, pointOffset: 0 } ],
1538
- shapes: [ { parentOffset: -1, figureOffset: 0, type: 2 } ],
1539
- segments: [] }
1566
+ points: [
1567
+ Point { x: 1, y: 1, z: null, m: null },
1568
+ Point { x: 1, y: 3, z: null, m: null },
1569
+ Point { x: 7, y: 3, z: null, m: null },
1570
+ Point { x: 1, y: 1, z: null, m: null }
1571
+ ],
1572
+ figures: [ { attribute: 2, pointOffset: 0 } ],
1573
+ shapes: [ { parentOffset: -1, figureOffset: 0, type: 3 } ],
1574
+ segments: []
1575
+ }
1540
1576
  ```
1541
1577
 
1542
1578
  ## Table-Valued Parameter (TVP)
@@ -2058,11 +2094,15 @@ request.query('select @myval as myval', (err, result) => {
2058
2094
  - If you're facing problems with connecting SQL Server 2000, try setting the default TDS version to 7.1 with `config.options.tdsVersion = '7_1'` ([issue](https://github.com/tediousjs/node-mssql/issues/36))
2059
2095
  - If you're executing a statement longer than 4000 chars on SQL Server 2000, always use [batch](#batch-batch-callback) instead of [query](#query-command-callback) ([issue](https://github.com/tediousjs/node-mssql/issues/68))
2060
2096
 
2061
- ## 6.x to 7.x changes (pre-release)
2097
+ ## 6.x to 7.x changes
2062
2098
 
2063
- - Upgraded tedious version to v8
2099
+ - Upgraded tedious version to v11
2100
+ - Upgraded msnodesqlv8 version support to v2
2101
+ - Upgraded tarn.js version to v3
2064
2102
  - Requests in stream mode that pipe into other streams no longer pass errors up the stream chain
2103
+ - Request.pipe now pipes a true node stream for better support of backpressure
2065
2104
  - tedious config option `trustServerCertificate` defaults to `false` if not supplied
2105
+ - Dropped support for Node < 10
2066
2106
 
2067
2107
  ## 5.x to 6.x changes
2068
2108
 
@@ -247,7 +247,7 @@ class ConnectionPool extends EventEmitter {
247
247
  workstationId: value
248
248
  })
249
249
  break
250
- case 'requesttimeout':
250
+ case 'request timeout':
251
251
  Object.assign(config, {
252
252
  requestTimeout: parseInt(value, 10)
253
253
  })
@@ -35,6 +35,10 @@ class PreparedStatement extends EventEmitter {
35
35
  this.parameters = {}
36
36
  }
37
37
 
38
+ get config () {
39
+ return this.parent.config
40
+ }
41
+
38
42
  get connected () {
39
43
  return this.parent.connected
40
44
  }
@@ -26,7 +26,7 @@ class Request extends EventEmitter {
26
26
  /**
27
27
  * Create new Request.
28
28
  *
29
- * @param {Connection|ConnectionPool|Transaction|PreparedStatement} parent If ommited, global connection is used instead.
29
+ * @param {Connection|ConnectionPool|Transaction|PreparedStatement} parent If omitted, global connection is used instead.
30
30
  */
31
31
 
32
32
  constructor (parent) {
@@ -39,6 +39,8 @@ class Request extends EventEmitter {
39
39
  this._paused = false
40
40
  this.parent = parent || globalConnection.pool
41
41
  this.parameters = {}
42
+ this.stream = null
43
+ this.arrayRowMode = null
42
44
  }
43
45
 
44
46
  get paused () {
@@ -224,8 +226,8 @@ class Request extends EventEmitter {
224
226
  */
225
227
 
226
228
  batch (batch, callback) {
227
- if (this.stream == null && this.connection) this.stream = this.connection.config.stream
228
- if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
229
+ if (this.stream === null && this.parent) this.stream = this.parent.config.stream
230
+ if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
229
231
  this.rowsAffected = 0
230
232
 
231
233
  if (typeof callback === 'function') {
@@ -288,11 +290,11 @@ class Request extends EventEmitter {
288
290
  */
289
291
 
290
292
  _batch (batch, callback) {
291
- if (!this.connection) {
293
+ if (!this.parent) {
292
294
  return setImmediate(callback, new RequestError('No connection is specified for that request.', 'ENOCONN'))
293
295
  }
294
296
 
295
- if (!this.connection.connected) {
297
+ if (!this.parent.connected) {
296
298
  return setImmediate(callback, new ConnectionError('Connection is closed.', 'ECONNCLOSED'))
297
299
  }
298
300
 
@@ -317,8 +319,8 @@ class Request extends EventEmitter {
317
319
  options = {}
318
320
  }
319
321
 
320
- if (this.stream == null && this.connection) this.stream = this.connection.config.stream
321
- if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
322
+ if (this.stream === null && this.parent) this.stream = this.parent.config.stream
323
+ if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
322
324
 
323
325
  if (this.stream || typeof callback === 'function') {
324
326
  this._bulk(table, options, (err, rowsAffected) => {
@@ -419,8 +421,8 @@ class Request extends EventEmitter {
419
421
  */
420
422
 
421
423
  query (command, callback) {
422
- if (this.stream == null && this.connection) this.stream = this.connection.config.stream
423
- if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
424
+ if (this.stream === null && this.parent) this.stream = this.parent.config.stream
425
+ if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
424
426
  this.rowsAffected = 0
425
427
 
426
428
  if (typeof callback === 'function') {
@@ -508,8 +510,8 @@ class Request extends EventEmitter {
508
510
  */
509
511
 
510
512
  execute (command, callback) {
511
- if (this.stream == null && this.connection) this.stream = this.connection.config.stream
512
- if (this.arrayRowMode == null && this.connection) this.arrayRowMode = this.connection.config.arrayRowMode
513
+ if (this.stream === null && this.parent) this.stream = this.parent.config.stream
514
+ if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
513
515
  this.rowsAffected = 0
514
516
 
515
517
  if (typeof callback === 'function') {
@@ -37,6 +37,10 @@ class Transaction extends EventEmitter {
37
37
  this.name = ''
38
38
  }
39
39
 
40
+ get config () {
41
+ return this.parent.config
42
+ }
43
+
40
44
  get connected () {
41
45
  return this.parent.connected
42
46
  }
@@ -146,7 +146,11 @@ class Request extends BaseRequest {
146
146
  super._bulk(table, options, err => {
147
147
  if (err) return callback(err)
148
148
 
149
- table._makeBulk()
149
+ try {
150
+ table._makeBulk()
151
+ } catch (e) {
152
+ return callback(new RequestError(e, 'EREQUEST'))
153
+ }
150
154
 
151
155
  if (!table.name) {
152
156
  setImmediate(callback, new RequestError('Table name must be specified for bulk insert.', 'ENAME'))
@@ -358,7 +362,7 @@ class Request extends BaseRequest {
358
362
  continue
359
363
  }
360
364
  const param = this.parameters[name]
361
- if (param.io === 1) {
365
+ if (param.io === 1 || (param.io === 2 && param.value)) {
362
366
  params.push(castParameter(param.value, param.type, param))
363
367
  }
364
368
  }
@@ -633,7 +637,19 @@ class Request extends BaseRequest {
633
637
  }
634
638
  }
635
639
 
636
- let cmd = `declare ${['@___return___ int'].concat(params).join(', ')};`
640
+ // set output params w/ values
641
+ const sets = []
642
+ for (const name in this.parameters) {
643
+ if (!objectHasProperty(this.parameters, name)) {
644
+ continue
645
+ }
646
+ const param = this.parameters[name]
647
+ if (param.io === 2 && param.value) {
648
+ sets.push(`set @${param.name}=?`)
649
+ }
650
+ }
651
+
652
+ let cmd = `declare ${['@___return___ int'].concat(params).join(', ')};${sets.join(';')};`
637
653
  cmd += `exec @___return___ = ${procedure} `
638
654
 
639
655
  const spp = []
@@ -213,7 +213,11 @@ class Request extends BaseRequest {
213
213
  super._bulk(table, options, err => {
214
214
  if (err) return callback(err)
215
215
 
216
- table._makeBulk()
216
+ try {
217
+ table._makeBulk()
218
+ } catch (e) {
219
+ return callback(new RequestError(e, 'EREQUEST'))
220
+ }
217
221
 
218
222
  if (!table.name) {
219
223
  return callback(new RequestError('Table name must be specified for bulk insert.', 'ENAME'))
@@ -266,14 +270,21 @@ class Request extends BaseRequest {
266
270
  }
267
271
 
268
272
  this.parent.acquire(this, (err, connection) => {
269
- if (err) return callback(err)
273
+ const callbackWithRelease = (err, ...args) => {
274
+ try {
275
+ this.parent.release(connection)
276
+ } catch (e) {
277
+ // noop
278
+ }
279
+ callback(err, ...args)
280
+ }
281
+ if (err) return callbackWithRelease(err)
270
282
 
271
283
  debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this))
272
284
 
273
285
  if (this.canceled) {
274
286
  debug('request(%d): canceled', IDS.get(this))
275
- this.parent.release(connection)
276
- return callback(new RequestError('Canceled.', 'ECANCEL'))
287
+ return callbackWithRelease(new RequestError('Canceled.', 'ECANCEL'))
277
288
  }
278
289
 
279
290
  this._cancel = () => {
@@ -307,13 +318,12 @@ class Request extends BaseRequest {
307
318
  connection.removeListener(event, errorHandlers[event])
308
319
  }
309
320
 
310
- this.parent.release(connection)
311
321
  hasReturned = true
312
322
 
313
323
  if (this.stream) {
314
- callback(null, rowCount)
324
+ callbackWithRelease(null, rowCount)
315
325
  } else {
316
- callback(error, rowCount)
326
+ callbackWithRelease(error, rowCount)
317
327
  }
318
328
  }
319
329
  }
@@ -325,7 +335,11 @@ class Request extends BaseRequest {
325
335
  }
326
336
 
327
337
  for (const row of table.rows) {
328
- bulk.addRow(row)
338
+ try {
339
+ bulk.addRow(row)
340
+ } catch (e) {
341
+ return handleError(true, connection, e)
342
+ }
329
343
  }
330
344
 
331
345
  if (table.create) {
package/lib/udt.js CHANGED
@@ -53,20 +53,42 @@ class Point {
53
53
  }
54
54
  }
55
55
 
56
- const parsePoints = (buffer, count) => {
56
+ const parsePoints = (buffer, count, isGeometryPoint) => {
57
57
  // s2.1.5 + s2.1.6
58
+ // The key distinction for parsing is that a GEOGRAPHY POINT is ordered Lat (y) then Long (x),
59
+ // while a GEOMETRY POINT is ordered x then y.
60
+ // Further, there are additional range constraints on GEOGRAPHY POINT that are useful for testing that the coordinate order has not been flipped, such as that Lat must be in the range [-90, +90].
58
61
 
59
62
  const points = []
60
63
  if (count < 1) {
61
64
  return points
62
65
  }
63
66
 
64
- for (let i = 1; i <= count; i++) {
65
- const point = new Point()
66
- points.push(point)
67
- point.x = buffer.readDoubleLE(buffer.position)
68
- point.y = buffer.readDoubleLE(buffer.position + 8)
69
- buffer.position += 16
67
+ if (isGeometryPoint) {
68
+ // GEOMETRY POINT (s2.1.6): x then y.
69
+ for (let i = 1; i <= count; i++) {
70
+ const point = new Point()
71
+ points.push(point)
72
+ point.x = buffer.readDoubleLE(buffer.position)
73
+ point.y = buffer.readDoubleLE(buffer.position + 8)
74
+ buffer.position += 16
75
+ }
76
+ } else {
77
+ // GEOGRAPHY POINT (s2.1.5): Lat (y) then Long (x).
78
+ for (let i = 1; i <= count; i++) {
79
+ const point = new Point()
80
+ points.push(point)
81
+ point.lat = buffer.readDoubleLE(buffer.position)
82
+ point.lng = buffer.readDoubleLE(buffer.position + 8)
83
+
84
+ // For backwards compatibility, preserve the coordinate inversion in x and y.
85
+ // A future breaking change likely eliminate x and y for geography points in favor of just the lat and lng fields, as they've proven marvelously confusing.
86
+ // See discussion at: https://github.com/tediousjs/node-mssql/pull/1282#discussion_r677769531
87
+ point.x = point.lat
88
+ point.y = point.lng
89
+
90
+ buffer.position += 16
91
+ }
70
92
  }
71
93
 
72
94
  return points
@@ -182,7 +204,7 @@ const parseSegments = (buffer, count) => {
182
204
  return segments
183
205
  }
184
206
 
185
- const parseGeography = buffer => {
207
+ const parseGeography = (buffer, isUsingGeometryPoints) => {
186
208
  // s2.1.1 + s.2.1.2
187
209
 
188
210
  const srid = buffer.readInt32LE(0)
@@ -227,7 +249,7 @@ const parseGeography = buffer => {
227
249
 
228
250
  // console.log("numberOfPoints", numberOfPoints)
229
251
 
230
- value.points = parsePoints(buffer, numberOfPoints)
252
+ value.points = parsePoints(buffer, numberOfPoints, isUsingGeometryPoints)
231
253
 
232
254
  if (properties.Z) {
233
255
  parseZ(buffer, value.points)
@@ -289,10 +311,10 @@ const parseGeography = buffer => {
289
311
 
290
312
  module.exports.PARSERS = {
291
313
  geography (buffer) {
292
- return parseGeography(buffer)
314
+ return parseGeography(buffer, /* isUsingGeometryPoints: */false)
293
315
  },
294
316
 
295
317
  geometry (buffer) {
296
- return parseGeography(buffer)
318
+ return parseGeography(buffer, /* isUsingGeometryPoints: */true)
297
319
  }
298
320
  }
package/package.json CHANGED
@@ -21,20 +21,20 @@
21
21
  "azure",
22
22
  "node-mssql"
23
23
  ],
24
- "version": "7.1.2",
24
+ "version": "7.3.0",
25
25
  "main": "index.js",
26
26
  "repository": "github:tediousjs/node-mssql",
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@tediousjs/connection-string": "^0.3.0",
30
- "debug": "^4",
30
+ "debug": "^4.3.2",
31
31
  "rfdc": "^1.3.0",
32
32
  "tarn": "^3.0.1",
33
- "tedious": "^11.0.7"
33
+ "tedious": "^11.4.0"
34
34
  },
35
35
  "devDependencies": {
36
- "mocha": "^8.3.2",
37
- "standard": "^16.0.3"
36
+ "mocha": "^8.4.0",
37
+ "standard": "^16.0.4"
38
38
  },
39
39
  "engines": {
40
40
  "node": ">=10"
package/test.js CHANGED
@@ -20,28 +20,21 @@ const sqlConfig = {
20
20
  },
21
21
  port: 1433,
22
22
  user: 'sa',
23
- server: 'localhost'
24
- };
23
+ server: 'localhost',
24
+ arrayRowMode: true
25
+ }
25
26
 
26
- (async () => {
27
- const pool = new mssql.ConnectionPool(sqlConfig)
28
- try {
29
- await pool.connect();
30
-
31
- const request = pool.request();
32
- request.arrayRowMode = true;
33
- request.multiple = true;
34
-
35
- const result = await request.batch('SELECT 1;');
36
-
37
- Object.entries(result.recordset.columns).forEach(([key, value]) => {
38
- console.log(`Column: ${key}, ${JSON.stringify(value)}`);
39
- });
40
- } catch (err) {
41
- console.error(err)
42
- } finally {
43
- console.log('closing pool')
44
- await pool.close()
45
- console.log('closed')
46
- }
47
- })()
27
+ mssql.connect(sqlConfig).then((pool) => {
28
+ console.log('Connected to SQL server')
29
+ const request = pool.request()
30
+ request.stream = true
31
+ request.on('error', (err) => {
32
+ console.error('good', err)
33
+ })
34
+ return request.query('SELECT * FROM nontable')
35
+ }).catch((err) => {
36
+ console.error('bad', err)
37
+ }).then(() => {
38
+ console.log('Disconnecting from SQL server')
39
+ return mssql.close()
40
+ }).then(() => console.log('Disconnected'))
package/test2.js DELETED
@@ -1,211 +0,0 @@
1
- const values = [
2
- 1810,
3
- 1729,
4
- 1857,
5
- 1777,
6
- 1927,
7
- 1936,
8
- 1797,
9
- 1719,
10
- 1703,
11
- 1758,
12
- 1768,
13
- 2008,
14
- 1963,
15
- 1925,
16
- 1919,
17
- 1911,
18
- 1782,
19
- 2001,
20
- 1744,
21
- 1738,
22
- 1742,
23
- 1799,
24
- 1765,
25
- 1819,
26
- 1888,
27
- 127,
28
- 1880,
29
- 1984,
30
- 1697,
31
- 1760,
32
- 1680,
33
- 1951,
34
- 1745,
35
- 1817,
36
- 1704,
37
- 1736,
38
- 1969,
39
- 1705,
40
- 1690,
41
- 1848,
42
- 1885,
43
- 1912,
44
- 1982,
45
- 1895,
46
- 1959,
47
- 1769,
48
- 1722,
49
- 1807,
50
- 1901,
51
- 1983,
52
- 1993,
53
- 1871,
54
- 1795,
55
- 1955,
56
- 1921,
57
- 1934,
58
- 1743,
59
- 1899,
60
- 1942,
61
- 1964,
62
- 1034,
63
- 1952,
64
- 1851,
65
- 1716,
66
- 1800,
67
- 1771,
68
- 1945,
69
- 1877,
70
- 1917,
71
- 1930,
72
- 1970,
73
- 1948,
74
- 1914,
75
- 1767,
76
- 1910,
77
- 563,
78
- 1121,
79
- 1897,
80
- 1946,
81
- 1882,
82
- 1739,
83
- 1900,
84
- 1714,
85
- 1931,
86
- 2000,
87
- 311,
88
- 1881,
89
- 1876,
90
- 354,
91
- 1965,
92
- 1842,
93
- 1979,
94
- 1998,
95
- 1960,
96
- 1852,
97
- 1847,
98
- 1938,
99
- 1369,
100
- 1780,
101
- 1698,
102
- 1753,
103
- 1746,
104
- 1868,
105
- 1752,
106
- 1802,
107
- 1892,
108
- 1755,
109
- 1818,
110
- 1913,
111
- 1706,
112
- 1862,
113
- 326,
114
- 1941,
115
- 1926,
116
- 1809,
117
- 1879,
118
- 1815,
119
- 1939,
120
- 1859,
121
- 1999,
122
- 1947,
123
- 1898,
124
- 1794,
125
- 1737,
126
- 1971,
127
- 1977,
128
- 1944,
129
- 1812,
130
- 1905,
131
- 1359,
132
- 1788,
133
- 1754,
134
- 1774,
135
- 1825,
136
- 1748,
137
- 1701,
138
- 1791,
139
- 1786,
140
- 1692,
141
- 1894,
142
- 1961,
143
- 1902,
144
- 1849,
145
- 1967,
146
- 1770,
147
- 1987,
148
- 1831,
149
- 1728,
150
- 1896,
151
- 1805,
152
- 1733,
153
- 1918,
154
- 1731,
155
- 661,
156
- 1776,
157
- 1494,
158
- 2005,
159
- 2009,
160
- 2004,
161
- 1915,
162
- 1695,
163
- 1710,
164
- 1804,
165
- 1929,
166
- 1725,
167
- 1772,
168
- 1933,
169
- 609,
170
- 1708,
171
- 1822,
172
- 1978,
173
- 1811,
174
- 1816,
175
- 1073,
176
- 1874,
177
- 1845,
178
- 1989,
179
- 1696,
180
- 1953,
181
- 1823,
182
- 1923,
183
- 1907,
184
- 1834,
185
- 1806,
186
- 1861,
187
- 1785,
188
- 297,
189
- 1968,
190
- 1764,
191
- 1932,
192
- 1937,
193
- 1826,
194
- 1732,
195
- 1962,
196
- 1916,
197
- 1756,
198
- 1975,
199
- 1775,
200
- 1922,
201
- 1773
202
- ]
203
-
204
- values.forEach((first) => {
205
- values.forEach((second) => {
206
- const third = 2020 - first - second
207
- if (values.includes(third)) {
208
- console.log(first * second * third)
209
- }
210
- })
211
- })