mssql 12.3.0 → 12.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Microsoft SQL Server client for Node.js**
4
4
 
5
- [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Appveyor CI][appveyor-image]][appveyor-url] [![Join the chat at https://gitter.im/patriksimek/node-mssql](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/patriksimek/node-mssql?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
+ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url]
6
6
 
7
7
  Supported TDS drivers:
8
8
 
@@ -137,6 +137,8 @@ const config = {
137
137
  * [ConnectionPool](#connections-1)
138
138
  * [connect](#connect-callback)
139
139
  * [close](#close)
140
+ * [Pool properties](#pool-properties)
141
+ * [parseConnectionString](#connectionpoolparseconnectionstring-connectionstring)
140
142
 
141
143
  ### Requests
142
144
 
@@ -144,6 +146,8 @@ const config = {
144
146
  * [execute](#execute-procedure-callback)
145
147
  * [input](#input-name-type-value)
146
148
  * [output](#output-name-type-value)
149
+ * [replaceInput](#replaceinput-name-type-value-1)
150
+ * [replaceOutput](#replaceoutput-name-type-value)
147
151
  * [toReadableStream](#toReadableStream)
148
152
  * [pipe](#pipe-stream)
149
153
  * [query](#query-command-callback)
@@ -181,8 +185,10 @@ const config = {
181
185
  * [Metadata](#metadata)
182
186
  * [Data Types](#data-types)
183
187
  * [SQL injection](#sql-injection)
184
- * [Known Issues](#known-issues)
185
188
  * [Contributing](https://github.com/tediousjs/node-mssql/wiki/Contributing)
189
+ * [11.x to 12.x changes](#11x-to-12x-changes)
190
+ * [10.x to 11.x changes](#10x-to-11x-changes)
191
+ * [9.x to 10.x changes](#9x-to-10x-changes)
186
192
  * [8.x to 9.x changes](#8x-to-9x-changes)
187
193
  * [7.x to 8.x changes](#7x-to-8x-changes)
188
194
  * [6.x to 7.x changes](#6x-to-7x-changes)
@@ -724,7 +730,7 @@ ___
724
730
 
725
731
  ### MSNodeSQLv8
726
732
 
727
- Alternative driver, requires Node.js v10+ or newer; Windows (32 or 64-bit) or Linux/macOS (64-bit only). It's not part of the default package so it must be [installed](#msnodesqlv8-driver) in addition. Supports [Windows/Trusted Connection authentication](#windows-authentication-example-using-msnodesqlv8).
733
+ Alternative driver for Windows (32 or 64-bit) or Linux/macOS (64-bit only). It's not part of the default package so it must be [installed](#msnodesqlv8-driver) in addition. Supports [Windows/Trusted Connection authentication](#windows-authentication-example-using-msnodesqlv8).
728
734
 
729
735
  **To use this driver you must use this `require` statement:**
730
736
 
@@ -816,6 +822,36 @@ __Example__
816
822
  pool.close()
817
823
  ```
818
824
 
825
+ ---------------------------------------
826
+
827
+ ### Pool properties
828
+
829
+ These properties are available on a connected `ConnectionPool` instance (after `connect()` has resolved):
830
+
831
+ - **pool.healthy** - `Boolean` - Whether the pool is able to create new connections.
832
+ - **pool.size** - `Number` - Total number of connections in the pool (free + used + pending creation).
833
+ - **pool.available** - `Number` - Number of free connections in the pool.
834
+ - **pool.pending** - `Number` - Number of pending connection acquisition requests.
835
+ - **pool.borrowed** - `Number` - Number of connections currently in use.
836
+ - **pool.connected** - `Boolean` - Whether the pool is connected.
837
+ - **pool.connecting** - `Boolean` - Whether the pool is currently connecting.
838
+
839
+ ---------------------------------------
840
+
841
+ ### ConnectionPool.parseConnectionString (connectionString)
842
+
843
+ Parses a connection string into a configuration object. This is a static method.
844
+
845
+ __Arguments__
846
+
847
+ - **connectionString** - Classic or Azure AD connection string.
848
+
849
+ __Example__
850
+
851
+ ```javascript
852
+ const config = sql.ConnectionPool.parseConnectionString('Server=localhost,1433;Database=mydb;User Id=sa;Password=pwd')
853
+ ```
854
+
819
855
  ## Request
820
856
 
821
857
  ```javascript
@@ -903,6 +939,13 @@ __JS Data Type To SQL Data Type Map__
903
939
 
904
940
  Default data type for unknown object is `sql.NVarChar`.
905
941
 
942
+ When a `Number` value is provided without an explicit type, the library inspects the value to choose the best SQL type:
943
+ - Integers within the 32-bit signed range → `sql.Int`
944
+ - Integers outside the 32-bit range → `sql.BigInt`
945
+ - Non-integer numbers → `sql.Float`
946
+
947
+ JavaScript `bigint` primitives follow the same range logic (`sql.Int` for values within the 32-bit signed range, `sql.BigInt` otherwise).
948
+
906
949
  You can define your own type map.
907
950
 
908
951
  ```javascript
@@ -946,6 +989,46 @@ __Errors__ (synchronous)
946
989
 
947
990
  ---------------------------------------
948
991
 
992
+ ### replaceInput (name, type, value)
993
+
994
+ Replace an existing input parameter on the request. If the parameter was previously added with `input()`, it is removed and re-added with the new type and value. Useful when building queries dynamically or re-using a `Request` object.
995
+
996
+ __Arguments__
997
+
998
+ - **name** - Name of the input parameter without @ char.
999
+ - **type** - SQL data type of input parameter.
1000
+ - **value** - Input parameter value.
1001
+
1002
+ Unlike `input()`, `replaceInput()` requires an explicit SQL type — auto type inference is not supported.
1003
+
1004
+ __Example__
1005
+
1006
+ ```javascript
1007
+ request.input('myval', sql.Int, 1)
1008
+ request.replaceInput('myval', sql.Int, 2)
1009
+ ```
1010
+
1011
+ ---------------------------------------
1012
+
1013
+ ### replaceOutput (name, type, [value])
1014
+
1015
+ Replace an existing output parameter on the request.
1016
+
1017
+ __Arguments__
1018
+
1019
+ - **name** - Name of the output parameter without @ char.
1020
+ - **type** - SQL data type of output parameter.
1021
+ - **value** - Output parameter value initial value. Optional.
1022
+
1023
+ __Example__
1024
+
1025
+ ```javascript
1026
+ request.output('myval', sql.Int)
1027
+ request.replaceOutput('myval', sql.BigInt)
1028
+ ```
1029
+
1030
+ ---------------------------------------
1031
+
949
1032
  ### toReadableStream
950
1033
 
951
1034
  Convert request to a Node.js ReadableStream
@@ -1044,7 +1127,7 @@ request.query('select 1 as number; select 2 as number', (err, result) => {
1044
1127
 
1045
1128
  ### batch (batch, [callback])
1046
1129
 
1047
- Execute the SQL command. Unlike [query](#query-command-callback), it doesn't use `sp_executesql`, so is not likely that SQL Server will reuse the execution plan it generates for the SQL. Use this only in special cases, for example when you need to execute commands like `create procedure` which can't be executed with [query](#query-command-callback) or if you're executing statements longer than 4000 chars on SQL Server 2000. Also you should use this if you're plan to work with local temporary tables ([more information here](http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx)).
1130
+ Execute the SQL command. Unlike [query](#query-command-callback), it doesn't use `sp_executesql`, so is not likely that SQL Server will reuse the execution plan it generates for the SQL. Use this only in special cases, for example when you need to execute commands like `create procedure` which can't be executed with [query](#query-command-callback). Also you should use this if you plan to work with local temporary tables ([more information here](http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx)).
1048
1131
 
1049
1132
  NOTE: Table-Valued Parameter (TVP) is not supported in batch.
1050
1133
 
@@ -1072,8 +1155,6 @@ __Errors__
1072
1155
  - ENOTBEGUN (`TransactionError`) - Transaction has not begun.
1073
1156
  - EABORT (`TransactionError`) - Transaction was aborted (by user or because of an error).
1074
1157
 
1075
- You can enable multiple recordsets in queries with the `request.multiple = true` command.
1076
-
1077
1158
  ---------------------------------------
1078
1159
 
1079
1160
  ### bulk (table, [options,] [callback])
@@ -2139,12 +2220,12 @@ request.query('select @myval as myval', (err, result) => {
2139
2220
  })
2140
2221
  ```
2141
2222
 
2142
- ## Known issues
2143
-
2144
- ### Tedious
2223
+ ## 11.x to 12.x changes
2145
2224
 
2146
- - 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))
2147
- - 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))
2225
+ - Config objects are no longer cloned by the library. Mutating a config object after passing it to a `ConnectionPool` results in undefined behaviour.
2226
+ - Removed `rfdc` dependency
2227
+ - Upgraded to tedious version 19
2228
+ - Upgraded `@tediousjs/connection-string` to 0.6.x
2148
2229
 
2149
2230
  ## 10.x to 11.x changes
2150
2231
 
@@ -2220,10 +2301,6 @@ to create new connections or not
2220
2301
  [npm-url]: https://www.npmjs.com/package/mssql
2221
2302
  [downloads-image]: https://img.shields.io/npm/dm/mssql.svg?style=flat-square
2222
2303
  [downloads-url]: https://www.npmjs.com/package/mssql
2223
- [david-image]: https://img.shields.io/david/tediousjs/node-mssql.svg?style=flat-square
2224
- [david-url]: https://david-dm.org/tediousjs/node-mssql
2225
- [appveyor-image]: https://ci.appveyor.com/api/projects/status/e5gq1a0ujwams9t7/branch/master?svg=true
2226
- [appveyor-url]: https://ci.appveyor.com/project/tediousjs/node-mssql
2227
2304
 
2228
2305
  [tedious-url]: https://www.npmjs.com/package/tedious
2229
2306
  [msnodesqlv8-url]: https://www.npmjs.com/package/msnodesqlv8
@@ -200,9 +200,13 @@ const parameterCorrection = function (value) {
200
200
  }
201
201
 
202
202
  for (const col of value.columns) {
203
+ const tediousType = getTediousType(col.type)
204
+ if (tediousType === tds.TYPES.Variant) {
205
+ throw new RequestError(`Column '${col.name}' in TVP '${value.schema ? value.schema + '.' : ''}${value.name}' uses sql_variant which is not supported by the tedious driver for TVP column types. Consider using a more specific data type.`, 'EARGS')
206
+ }
203
207
  tvp.columns.push({
204
208
  name: col.name,
205
- type: getTediousType(col.type),
209
+ type: tediousType,
206
210
  length: col.length,
207
211
  scale: col.scale,
208
212
  precision: col.precision
@@ -664,9 +668,18 @@ class Request extends BaseRequest {
664
668
  } catch (e) {
665
669
  e.message = `Validation failed for parameter '${name}'. ${e.message}`
666
670
  const err = new RequestError(e, 'EPARAM')
671
+ delete this._cancel
672
+
673
+ if (!hasReturned) {
674
+ for (const event in errorHandlers) {
675
+ connection.removeListener(event, errorHandlers[event])
676
+ }
667
677
 
668
- this.parent.release(connection)
669
- return callback(err)
678
+ this.parent.release(connection)
679
+ hasReturned = true
680
+ return callback(err)
681
+ }
682
+ return
670
683
  }
671
684
  }
672
685
 
@@ -703,21 +716,23 @@ class Request extends BaseRequest {
703
716
 
704
717
  req.sqlTextOrProcedure = `declare ${declarations.join(', ')};select ${assigns.join(', ')};${req.sqlTextOrProcedure};${batchHasOutput ? (`select 1 as [___return___], ${selects.join(', ')}`) : ''}`
705
718
  }
706
- } else {
707
- for (const name in this.parameters) {
708
- if (!objectHasProperty(this.parameters, name)) {
709
- continue
710
- }
711
- const param = this.parameters[name]
712
- if (param.io === 1) {
713
- req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
714
- } else {
715
- req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
716
- }
717
- }
718
719
  }
719
720
 
720
721
  try {
722
+ if (!this._isBatch) {
723
+ for (const name in this.parameters) {
724
+ if (!objectHasProperty(this.parameters, name)) {
725
+ continue
726
+ }
727
+ const param = this.parameters[name]
728
+ if (param.io === 1) {
729
+ req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
730
+ } else {
731
+ req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
732
+ }
733
+ }
734
+ }
735
+
721
736
  connection[this._isBatch ? 'execSqlBatch' : 'execSql'](req)
722
737
  } catch (error) {
723
738
  handleError(true, connection, error)
@@ -983,19 +998,34 @@ class Request extends BaseRequest {
983
998
  output[parameterName] = value
984
999
  })
985
1000
 
986
- for (const name in this.parameters) {
987
- if (!objectHasProperty(this.parameters, name)) {
988
- continue
1001
+ try {
1002
+ for (const name in this.parameters) {
1003
+ if (!objectHasProperty(this.parameters, name)) {
1004
+ continue
1005
+ }
1006
+ const param = this.parameters[name]
1007
+ if (param.io === 1) {
1008
+ req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
1009
+ } else {
1010
+ req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
1011
+ }
989
1012
  }
990
- const param = this.parameters[name]
991
- if (param.io === 1) {
992
- req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
993
- } else {
994
- req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
1013
+
1014
+ connection.callProcedure(req)
1015
+ } catch (error) {
1016
+ const err = error instanceof RequestError ? error : new RequestError(error, 'EREQUEST')
1017
+ delete this._cancel
1018
+
1019
+ if (!hasReturned) {
1020
+ for (const event in errorHandlers) {
1021
+ connection.removeListener(event, errorHandlers[event])
1022
+ }
1023
+
1024
+ this.parent.release(connection)
1025
+ hasReturned = true
1026
+ callback(err)
995
1027
  }
996
1028
  }
997
-
998
- connection.callProcedure(req)
999
1029
  })
1000
1030
  })
1001
1031
  }
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "azure",
22
22
  "node-mssql"
23
23
  ],
24
- "version": "12.3.0",
24
+ "version": "12.3.1",
25
25
  "main": "index.js",
26
26
  "type": "commonjs",
27
27
  "repository": {