mssql 6.1.0 → 6.2.3

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,3 +1,32 @@
1
+ v6.2.3 (2020-09-25)
2
+ -------------------
3
+ [fix] Remove reference to global pool on connection error ([#1107](https://github.com/tediousjs/node-mssql/pull/1107))
4
+ [fix] Trailing rows from request streams using msnodesqlv8 driver fail to be emitted ([#1109](https://github.com/tediousjs/node-mssql/pull/1109))
5
+
6
+ v6.2.2 (2020-09-18)
7
+ -------------------
8
+ [fix] Avoid using deprecated `.inspect` on Objects ([#1071](https://github.com/tediousjs/node-mssql/pull/1071))
9
+ [fix] Bump various dependencies for security fixes ([#1102](https://github.com/tediousjs/node-mssql/pull/1102))
10
+
11
+ v6.2.1 (2020-07-22)
12
+ -------------------
13
+ [fix] Bump various dependencies for security fixes
14
+
15
+ v6.2.0 (2020-03-13)
16
+ -------------------
17
+ [new] Set default isolationLevel for all transactions ([#1005](https://github.com/tediousjs/node-mssql/pull/1005))
18
+ [new] sql.Date now is coerced into a date object ([#1007](https://github.com/tediousjs/node-mssql/pull/1007))
19
+ [fix] Bump acorn dependency for security fix
20
+
21
+ v6.1.0 (2020-02-17)
22
+ -------------------
23
+ [new] Add `Request.template` helper for providing templated strings to queries ([#960](https://github.com/tediousjs/node-mssql/pull/960))
24
+ [new] Repeat calls to `ConnectionPool.connect()` resolve ([#941](https://github.com/tediousjs/node-mssql/pull/941))
25
+ [new] Stored procedure params are now logged to debug log ([#979](https://github.com/tediousjs/node-mssql/pull/979))
26
+ [fix] Repeat calls to `mssql.connect()` will now resolve correctly ([#986](https://github.com/tediousjs/node-mssql/pull/986))
27
+ [fix] Connections are encrypted by default as documented ([#977](https://github.com/tediousjs/node-mssql/pull/977))
28
+ [fix] Tagged template literal queries with empty array values now work ([#990](https://github.com/tediousjs/node-mssql/pull/990))
29
+
1
30
  v6.0.1 (2019-11-15)
2
31
  -------------------
3
32
  [fix] Fix an issue with connection strings where usernames have url encoded values ([#945](https://github.com/tediousjs/node-mssql/pull/945)
@@ -24,6 +53,19 @@ v6.0.0 (2019-11-05)
24
53
  [change] Replaced pool library (`generic-pool`) with `tarn.js` ([#808](https://github.com/tediousjs/node-mssql/pull/808))
25
54
  [removed] Backoff try strategy for creating connections removed, `tarn.js` built-in retry strategy used instead
26
55
 
56
+ v5.1.3 (2020-09-18)
57
+ -------------------
58
+ [fix] Avoid using deprecated `.inspect` on Objects ([#1071](https://github.com/tediousjs/node-mssql/pull/1071))
59
+ [fix] Bump various dependencies for security fixes ([#1102](https://github.com/tediousjs/node-mssql/pull/1102))
60
+
61
+ v5.1.2 (2020-07-22)
62
+ -------------------
63
+ [fix] Bump various dependencies for security fixes
64
+
65
+ v5.1.1 (2020-03-13)
66
+ -------------------
67
+ [fix] Bump acorn dependency for security fix
68
+
27
69
  v5.1.0 (2019-04-17)
28
70
  -------------------
29
71
  [new] Add readOnlyIntent to connection string parser ([#853](https://github.com/tediousjs/node-mssql/pull/853))
@@ -62,6 +104,14 @@ v5.0.0 (2019-03-07)
62
104
  [removed] Node.js < 6 is no longer supported
63
105
  [removed] Support dropped for deprecated tedious configuration values and types
64
106
 
107
+ v4.3.9 (2020-07-22)
108
+ -------------------
109
+ [fix] Bump various dependencies for security fixes
110
+
111
+ v4.3.8 (2020-03-13)
112
+ -------------------
113
+ [fix] Bump acorn dependency for security fix
114
+
65
115
  v4.3.7 (2019-03-29)
66
116
  -------------------
67
117
  [fix] Fix an issue where connections that error can deplete the pool ([#842](https://github.com/tediousjs/node-mssql/pull/842))
@@ -69,6 +119,7 @@ v4.3.7 (2019-03-29)
69
119
  v4.3.6 (2019-03-27)
70
120
  -------------------
71
121
  [fix] Fix a bug where msnodesqlv8 driver could execute callbacks twice ([#834](https://github.com/tediousjs/node-mssql/pull/834))
122
+ [fix] Bump js-yaml dependency for security fix
72
123
 
73
124
  v4.3.5 (2019-03-09)
74
125
  -------------------
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] (native - Windows/Linux only)
10
10
 
11
11
  ## Installation
12
12
 
@@ -103,6 +103,7 @@ Parts of the connection URI should be correctly URL encoded so that the URI can
103
103
  * [SQL injection](#sql-injection)
104
104
  * [Known Issues](#known-issues)
105
105
  * [Contributing](https://github.com/tediousjs/node-mssql/wiki/Contributing)
106
+ * [5.x to 6.x changes](#5x-to-6x-changes)
106
107
  * [4.x to 5.x changes](#4x-to-5x-changes)
107
108
  * [3.x to 4.x changes](#3x-to-4x-changes)
108
109
  * [3.x Documentation](https://github.com/tediousjs/node-mssql/blob/1893969195045a250f0fdeeb2de7f30dcf6689ad/README.md)
@@ -657,7 +658,7 @@ More information about Tedious specific options: http://tediousjs.github.io/tedi
657
658
 
658
659
  ### Microsoft / Contributors Node V8 Driver for Node.js for SQL Server
659
660
 
660
- **Requires Node.js 0.12.x or newer. Windows only.** This driver is not part of the default package and must be installed separately by `npm install msnodesqlv8`. To use this driver, use this require syntax: `const sql = require('mssql/msnodesqlv8')`.
661
+ **Requires Node.js v10+ or newer. Windows/Linux only.** This driver is not part of the default package and must be installed separately by `npm install msnodesqlv8`. To use this driver, use this require syntax: `const sql = require('mssql/msnodesqlv8')`.
661
662
 
662
663
  **Extra options:**
663
664
 
@@ -33,7 +33,7 @@ class Transaction extends EventEmitter {
33
33
  debug('transaction(%d): created', IDS.get(this))
34
34
 
35
35
  this.parent = parent || globalConnection.pool
36
- this.isolationLevel = ISOLATION_LEVEL.READ_COMMITTED
36
+ this.isolationLevel = Transaction.defaultIsolationLevel
37
37
  this.name = ''
38
38
  }
39
39
 
@@ -251,4 +251,11 @@ class Transaction extends EventEmitter {
251
251
  }
252
252
  }
253
253
 
254
+ /**
255
+ * Default isolation level used for any transactions that don't explicitly specify an isolation level.
256
+ *
257
+ * @type {number}
258
+ */
259
+ Transaction.defaultIsolationLevel = ISOLATION_LEVEL.READ_COMMITTED
260
+
254
261
  module.exports = Transaction
package/lib/datatypes.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
  const objectHasProperty = require('./utils').objectHasProperty
3
+ const inspect = Symbol.for('nodejs.util.inspect.custom')
3
4
 
4
5
  const TYPES = {
5
6
  VarChar (length) {
@@ -125,7 +126,7 @@ for (const key in TYPES) {
125
126
  module.exports.DECLARATIONS[value.declaration] = value;
126
127
 
127
128
  ((key, value) => {
128
- value.inspect = () => `[sql.${key}]`
129
+ value[inspect] = () => `[sql.${key}]`
129
130
  })(key, value)
130
131
  }
131
132
  }
@@ -48,7 +48,18 @@ function connect (config, callback) {
48
48
 
49
49
  globalConnection.close = globalClose.bind(globalConnection)
50
50
  }
51
- return globalConnection.connect(callback)
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
  /**
@@ -96,7 +96,8 @@ const createColumns = function (metadata) {
96
96
  index,
97
97
  name: column.name,
98
98
  length: column.size,
99
- type: DECLARATIONS[column.sqlType]
99
+ type: DECLARATIONS[column.sqlType],
100
+ nullable: column.nullable
100
101
  }
101
102
 
102
103
  if (column.udtType != null) {
@@ -234,16 +235,55 @@ class Request extends BaseRequest {
234
235
  return callback(null, [])
235
236
  }
236
237
 
237
- let row = null
238
- let columns = null
239
- let recordset = null
240
238
  const recordsets = []
239
+ const errors = []
240
+ const errorHandlers = {}
241
241
  const output = {}
242
242
  const rowsAffected = []
243
+
244
+ let hasReturned = false
245
+ let row = null
246
+ let columns = null
247
+ let recordset = null
243
248
  let handleOutput = false
244
249
  let isChunkedRecordset = false
245
250
  let chunksBuffer = null
246
251
 
252
+ const handleError = (req, connection, info, moreErrors) => {
253
+ const doReturn = !moreErrors
254
+ if ((typeof info.sqlstate === 'string') && (info.sqlstate.toLowerCase() === '08s01')) {
255
+ connection.hasError = true
256
+ }
257
+
258
+ const err = new RequestError(info, 'EREQUEST')
259
+ err.code = 'EREQUEST'
260
+ err.state = info.sqlstate
261
+
262
+ if (this.stream) {
263
+ this.emit('error', err)
264
+ } else {
265
+ if (doReturn && !hasReturned) {
266
+ if (req) {
267
+ for (const event in errorHandlers) {
268
+ req.removeListener(event, errorHandlers[event])
269
+ }
270
+ }
271
+ if (connection) {
272
+ this.parent.release(connection)
273
+ delete this._cancel
274
+
275
+ debug('request(%d): failed', IDS.get(this), err)
276
+ }
277
+
278
+ hasReturned = true
279
+ callback(err)
280
+ }
281
+ }
282
+
283
+ // we must collect errors even in stream mode
284
+ errors.push(err)
285
+ }
286
+
247
287
  // nested = function is called by this.execute
248
288
 
249
289
  if (!this._nested) {
@@ -287,7 +327,6 @@ class Request extends BaseRequest {
287
327
 
288
328
  this.parent.acquire(this, (err, connection, config) => {
289
329
  if (err) return callback(err)
290
- let hasReturned = false
291
330
 
292
331
  debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this))
293
332
 
@@ -357,11 +396,10 @@ class Request extends BaseRequest {
357
396
  }
358
397
 
359
398
  chunksBuffer = null
360
- }
361
-
362
- if (row && row.___return___ == null) {
363
- // row with ___return___ col is the last row
364
- if (this.stream && !this.paused) this.emit('row', row)
399
+ if (row && row.___return___ == null) {
400
+ // row with ___return___ col is the last row
401
+ if (this.stream && !this.paused) this.emit('row', row)
402
+ }
365
403
  }
366
404
  }
367
405
 
@@ -397,14 +435,7 @@ class Request extends BaseRequest {
397
435
  })
398
436
 
399
437
  req.on('row', rownumber => {
400
- if (row) {
401
- if (isChunkedRecordset) return
402
-
403
- if (row.___return___ == null) {
404
- // row with ___return___ col is the last row
405
- if (this.stream && !this.paused) this.emit('row', row)
406
- }
407
- }
438
+ if (row && isChunkedRecordset) return
408
439
 
409
440
  row = {}
410
441
 
@@ -427,6 +458,11 @@ class Request extends BaseRequest {
427
458
  } else {
428
459
  row[columns[idx].name] = data
429
460
  }
461
+ if (row.___return___ == null) {
462
+ if (this.stream && !this.paused && idx === columns.length - 1) {
463
+ this.emit('row', row)
464
+ }
465
+ }
430
466
  }
431
467
  })
432
468
 
@@ -450,26 +486,7 @@ class Request extends BaseRequest {
450
486
  })
451
487
  })
452
488
 
453
- req.once('error', err => {
454
- if (hasReturned) {
455
- return
456
- }
457
- hasReturned = true
458
-
459
- if ((typeof err.sqlstate === 'string') && (err.sqlstate.toLowerCase() === '08s01')) {
460
- connection.hasError = true
461
- }
462
-
463
- err = new RequestError(err)
464
- err.code = 'EREQUEST'
465
- err.state = err.sqlstate
466
-
467
- delete this._cancel
468
- this.parent.release(connection)
469
-
470
- debug('request(%d): failed', IDS.get(this), err)
471
- callback(err)
472
- })
489
+ req.on('error', errorHandlers.error = handleError.bind(null, req, connection))
473
490
 
474
491
  req.once('done', () => {
475
492
  if (hasReturned) {
@@ -505,11 +522,10 @@ class Request extends BaseRequest {
505
522
  }
506
523
 
507
524
  chunksBuffer = null
508
- }
509
-
510
- if (row && row.___return___ == null) {
511
- // row with ___return___ col is the last row
512
- if (this.stream && !this.paused) { this.emit('row', row) }
525
+ if (row && row.___return___ == null) {
526
+ // row with ___return___ col is the last row
527
+ if (this.stream && !this.paused) { this.emit('row', row) }
528
+ }
513
529
  }
514
530
  }
515
531
 
package/lib/table.js CHANGED
@@ -30,17 +30,17 @@ function Table (name) {
30
30
  }
31
31
 
32
32
  options = options || {}
33
- column.name = name
34
- column.nullable = options.nullable
35
- column.primary = options.primary
36
- if (objectHasProperty(options, 'length')) {
37
- column.length = options.length
38
- }
33
+ column.name = name;
34
+
35
+ ['nullable', 'primary', 'identity', 'readOnly', 'length'].forEach(prop => {
36
+ if (objectHasProperty(options, prop)) {
37
+ column[prop] = options[prop]
38
+ }
39
+ })
39
40
 
40
41
  return this.push(column)
41
42
  }
42
- }
43
- )
43
+ })
44
44
 
45
45
  Object.defineProperty(this.rows, 'add', {
46
46
  value () {
@@ -58,6 +58,7 @@ Table.prototype._makeBulk = function _makeBulk () {
58
58
  for (let i = 0; i < this.columns.length; i++) {
59
59
  const col = this.columns[i]
60
60
  switch (col.type) {
61
+ case TYPES.Date:
61
62
  case TYPES.DateTime:
62
63
  case TYPES.DateTime2:
63
64
  for (let j = 0; j < this.rows.length; j++) {
@@ -125,7 +126,9 @@ Table.fromRecordset = function fromRecordset (recordset, name) {
125
126
  scale: col.scale,
126
127
  precision: col.precision
127
128
  }, {
128
- nullable: col.nullable
129
+ nullable: col.nullable,
130
+ identity: col.identity,
131
+ readOnly: col.readOnly
129
132
  })
130
133
  }
131
134
  }
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "azure",
22
22
  "node-mssql"
23
23
  ],
24
- "version": "6.1.0",
24
+ "version": "6.2.3",
25
25
  "main": "index.js",
26
26
  "repository": "github:tediousjs/node-mssql",
27
27
  "license": "MIT",
package/test.js CHANGED
@@ -1,114 +1,40 @@
1
1
  'use strict'
2
2
 
3
3
  const mssql = require('./')
4
+ const wtf = require('wtfnode');
4
5
 
5
6
  const sqlConfig = {
6
- password: 'Upper_l0wercase',
7
- database: 'di_production',
8
- // connectionTimeout: undefined,
9
- // requestTimeout: 30000,
7
+ password: '&r8wrucH',
8
+ database: 'StockDB',
10
9
  stream: false,
11
10
  options: {
11
+ // trustServerCertificate: true,
12
+ enableArithAbort: true,
12
13
  encrypt: true,
13
- readOnlyIntent: true
14
+ abortTransactionOnError: false,
14
15
  },
15
- port: 1433,
16
- user: 'sa',
17
- server: 'localhost',
18
16
  pool: {
19
- // acquireTimeoutMillis: 1000,
20
- // propagateCreateError: true,
17
+ max: 1,
18
+ min: 0,
21
19
  },
20
+ port: 1433,
21
+ user: 'dhensby',
22
+ server: '4sa.database.windows.net',
22
23
  }
23
24
 
24
- // let pool
25
- //
26
- // function createPool() {
27
- // return new mssql.ConnectionPool(sqlConfig)
28
- // }
29
- //
30
- // const poolRequest = createPool()
31
- //
32
- // function connect () {
33
- // console.log('trying to connect to server')
34
- // // const poolRequest = createPool()
35
- // mssql.on('error', (e) => {
36
- // console.log('error event fired')
37
- // console.error(e)
38
- // })
39
- // return poolRequest.connect(sqlConfig).then((connection) => {
40
- // // setTimeout(connection.close.bind(connection), 2000)
41
- // console.log('connection established')
42
- // console.log(connection)
43
- // connection.on('error', (e) => {
44
- // console.log('on error')
45
- // console.error(e)
46
- // })
47
- // pool = connection
48
- // })
49
- // }
50
- //
51
- // function runQuery (result) {
52
- // if (result) {
53
- // console.log('*** RESULT ***')
54
- // console.log(result.recordset)
55
- // console.log('*** RESULT ***')
56
- // }
57
- // const request = pool.request();
58
- // return new Promise((resolve) => {
59
- // setTimeout(resolve, 10000)
60
- // }).then(() => request.query('SELECT 1').catch(e => {
61
- // console.log('query error')
62
- // throw e
63
- // })).then(runQuery)
64
- // }
65
- //
66
- // connect()
67
- // .then(() => {
68
- // return runQuery()
69
- // })
70
- // .catch((e) => {
71
- // console.log('connection error')
72
- // console.error(e)
73
- // console.log(pool)
74
- // return runQuery()
75
- // })
76
- // .then(() => {
77
- // return pool && pool.close()
78
- // }).catch(() => {
79
- // console.log(pool)
80
- // })
81
-
82
- // const query = 'select 1';
83
- //
84
- // const quickExample = async () => {
85
- // try {
86
- // // make sure that any items are correctly URL encoded in the connection string
87
- // await mssql.connect(sqlConfig)
88
- // const result = await mssql.query(query);
89
- // console.log('quickExample', result);
90
- // } catch (err) {
91
- // console.error('quickExample error:', err);
92
- // }
93
- // }
94
- //
95
- // const func = quickExample
96
- //
97
- // const promises = [1, 2, 3, 4, 5, 6].map(index => func(index).catch(err => console.log(`err with index ${index}!`, err)));
25
+ // Bad URI, connection timeouts, hangs process
26
+ mssql.connect({ ...sqlConfig, port: 2345 }).catch(err => {
27
+ console.error(err.message);
28
+ console.log('reconnecting...');
98
29
 
99
- mssql.connect(sqlConfig)
100
- .then(async (pool) => {
101
- const query = 'SELECT [name] FROM [role] WHERE [idRole] = @id'
102
- return pool.request().input('id', mssql.Int, 1).query(query)
103
- })
104
- .then((result) => {
105
- console.log(result)
106
- })
107
- .then(() => {
108
- return mssql.close()
109
- })
110
- .catch((err) => {
111
- console.log('error handler')
112
- console.error(err)
113
- return mssql.close()
114
- })
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
+ });