mssql 12.4.0 → 12.5.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 +18 -3
- package/lib/base/connection-pool.js +6 -4
- package/lib/base/prepared-statement.js +10 -5
- package/lib/base/request.js +7 -2
- package/lib/base/transaction.js +14 -4
- package/lib/msnodesqlv8/request.js +6 -3
- package/lib/tedious/request.js +12 -1
- package/lib/tedious/transaction.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -856,11 +856,22 @@ const config = sql.ConnectionPool.parseConnectionString('Server=localhost,1433;D
|
|
|
856
856
|
## Request
|
|
857
857
|
|
|
858
858
|
```javascript
|
|
859
|
-
const request = new sql.Request(/* [pool or transaction] */)
|
|
859
|
+
const request = new sql.Request(/* [pool or transaction], [options] */)
|
|
860
860
|
```
|
|
861
861
|
|
|
862
862
|
If you omit pool/transaction argument, global pool is used instead.
|
|
863
863
|
|
|
864
|
+
The optional `options` argument allows per-request configuration overrides:
|
|
865
|
+
|
|
866
|
+
- **requestTimeout** - Override the pool's default request timeout (in ms) for this request only. This applies to queries and stored procedure executions; it does not apply to bulk data transfers (`request.bulk()`), which stream to completion as long as the connection is healthy. If you need to bound a bulk transfer, wrap the call with your own timer and call `request.cancel()`.
|
|
867
|
+
|
|
868
|
+
```javascript
|
|
869
|
+
// Request with a 60-second timeout instead of the pool default
|
|
870
|
+
const request = new sql.Request(pool, { requestTimeout: 60000 })
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
**Note:** When using the global pool, you must still pass `undefined` as the first argument to use options: `new sql.Request(undefined, { requestTimeout: 60000 })`.
|
|
874
|
+
|
|
864
875
|
### Events
|
|
865
876
|
|
|
866
877
|
- **recordset(columns)** - Dispatched when metadata for new recordset are parsed.
|
|
@@ -1226,11 +1237,13 @@ request.cancel()
|
|
|
1226
1237
|
**IMPORTANT:** always use `Transaction` class to create transactions - it ensures that all your requests are executed on one connection. Once you call `begin`, a single connection is acquired from the connection pool and all subsequent requests (initialized with the `Transaction` object) are executed exclusively on this connection. After you call `commit` or `rollback`, connection is then released back to the connection pool.
|
|
1227
1238
|
|
|
1228
1239
|
```javascript
|
|
1229
|
-
const transaction = new sql.Transaction(/* [pool] */)
|
|
1240
|
+
const transaction = new sql.Transaction(/* [pool], [options] */)
|
|
1230
1241
|
```
|
|
1231
1242
|
|
|
1232
1243
|
If you omit connection argument, global connection is used instead.
|
|
1233
1244
|
|
|
1245
|
+
The optional `options` argument allows per-transaction configuration overrides (e.g. `{ requestTimeout: 60000 }`). These are inherited by any requests created from this transaction unless overridden at the request level. Note that the timeout applies to data requests only, not to the `begin`/`commit`/`rollback` operations themselves.
|
|
1246
|
+
|
|
1234
1247
|
__Example__
|
|
1235
1248
|
|
|
1236
1249
|
```javascript
|
|
@@ -1378,11 +1391,13 @@ __Errors__
|
|
|
1378
1391
|
**IMPORTANT:** always use `PreparedStatement` class to create prepared statements - it ensures that all your executions of prepared statement are executed on one connection. Once you call `prepare`, a single connection is acquired from the connection pool and all subsequent executions are executed exclusively on this connection. After you call `unprepare`, the connection is then released back to the connection pool.
|
|
1379
1392
|
|
|
1380
1393
|
```javascript
|
|
1381
|
-
const ps = new sql.PreparedStatement(/* [pool] */)
|
|
1394
|
+
const ps = new sql.PreparedStatement(/* [pool], [options] */)
|
|
1382
1395
|
```
|
|
1383
1396
|
|
|
1384
1397
|
If you omit the connection argument, the global connection is used instead.
|
|
1385
1398
|
|
|
1399
|
+
The optional `options` argument allows per-statement configuration overrides (e.g. `{ requestTimeout: 60000 }`). The timeout is applied to the `prepare`, `execute`, and `unprepare` operations.
|
|
1400
|
+
|
|
1386
1401
|
__Example__
|
|
1387
1402
|
|
|
1388
1403
|
```javascript
|
|
@@ -627,21 +627,23 @@ class ConnectionPool extends EventEmitter {
|
|
|
627
627
|
/**
|
|
628
628
|
* Returns new request using this connection.
|
|
629
629
|
*
|
|
630
|
+
* @param {{ requestTimeout?: number }} [conf] Per-request overrides.
|
|
630
631
|
* @return {Request}
|
|
631
632
|
*/
|
|
632
633
|
|
|
633
|
-
request () {
|
|
634
|
-
return new shared.driver.Request(this)
|
|
634
|
+
request (conf) {
|
|
635
|
+
return new shared.driver.Request(this, conf)
|
|
635
636
|
}
|
|
636
637
|
|
|
637
638
|
/**
|
|
638
639
|
* Returns new transaction using this connection.
|
|
639
640
|
*
|
|
641
|
+
* @param {{ requestTimeout?: number }} [conf] Per-transaction overrides, cascaded to child requests.
|
|
640
642
|
* @return {Transaction}
|
|
641
643
|
*/
|
|
642
644
|
|
|
643
|
-
transaction () {
|
|
644
|
-
return new shared.driver.Transaction(this)
|
|
645
|
+
transaction (conf) {
|
|
646
|
+
return new shared.driver.Transaction(this, conf)
|
|
645
647
|
}
|
|
646
648
|
|
|
647
649
|
/**
|
|
@@ -21,10 +21,11 @@ class PreparedStatement extends EventEmitter {
|
|
|
21
21
|
/**
|
|
22
22
|
* Creates a new Prepared Statement.
|
|
23
23
|
*
|
|
24
|
-
* @param {ConnectionPool|Transaction} [
|
|
24
|
+
* @param {ConnectionPool|Transaction} [parent]
|
|
25
|
+
* @param {{ requestTimeout?: number }} [overrides]
|
|
25
26
|
*/
|
|
26
27
|
|
|
27
|
-
constructor (parent) {
|
|
28
|
+
constructor (parent, overrides = {}) {
|
|
28
29
|
super()
|
|
29
30
|
|
|
30
31
|
IDS.add(this, 'PreparedStatement')
|
|
@@ -34,6 +35,10 @@ class PreparedStatement extends EventEmitter {
|
|
|
34
35
|
this._handle = 0
|
|
35
36
|
this.prepared = false
|
|
36
37
|
this.parameters = {}
|
|
38
|
+
this.overrides = {}
|
|
39
|
+
if (Number.isFinite(overrides?.requestTimeout) && overrides.requestTimeout >= 0) {
|
|
40
|
+
this.overrides.requestTimeout = overrides.requestTimeout
|
|
41
|
+
}
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
get config () {
|
|
@@ -245,7 +250,7 @@ class PreparedStatement extends EventEmitter {
|
|
|
245
250
|
this._acquiredConnection = connection
|
|
246
251
|
this._acquiredConfig = config
|
|
247
252
|
|
|
248
|
-
const req = new shared.driver.Request(this)
|
|
253
|
+
const req = new shared.driver.Request(this, this.overrides)
|
|
249
254
|
req._internal = true
|
|
250
255
|
req.stream = false
|
|
251
256
|
req.output('handle', TYPES.Int)
|
|
@@ -328,7 +333,7 @@ class PreparedStatement extends EventEmitter {
|
|
|
328
333
|
*/
|
|
329
334
|
|
|
330
335
|
_execute (values, callback) {
|
|
331
|
-
const req = new shared.driver.Request(this)
|
|
336
|
+
const req = new shared.driver.Request(this, this.overrides)
|
|
332
337
|
req._internal = true
|
|
333
338
|
req.stream = this.stream
|
|
334
339
|
req.arrayRowMode = this.arrayRowMode
|
|
@@ -409,7 +414,7 @@ class PreparedStatement extends EventEmitter {
|
|
|
409
414
|
return setImmediate(callback, new TransactionError("Can't unprepare the statement. There is a request in progress.", 'EREQINPROG'))
|
|
410
415
|
}
|
|
411
416
|
|
|
412
|
-
const req = new shared.driver.Request(this)
|
|
417
|
+
const req = new shared.driver.Request(this, this.overrides)
|
|
413
418
|
req._internal = true
|
|
414
419
|
req.stream = false
|
|
415
420
|
req.input('handle', TYPES.Int, this._handle)
|
package/lib/base/request.js
CHANGED
|
@@ -27,10 +27,11 @@ class Request extends EventEmitter {
|
|
|
27
27
|
/**
|
|
28
28
|
* Create new Request.
|
|
29
29
|
*
|
|
30
|
-
* @param {Connection|ConnectionPool|Transaction|PreparedStatement} parent If omitted, global connection is used instead.
|
|
30
|
+
* @param {Connection|ConnectionPool|Transaction|PreparedStatement} [parent] If omitted, global connection is used instead.
|
|
31
|
+
* @param {{ requestTimeout?: number }} [overrides]
|
|
31
32
|
*/
|
|
32
33
|
|
|
33
|
-
constructor (parent) {
|
|
34
|
+
constructor (parent, overrides = {}) {
|
|
34
35
|
super()
|
|
35
36
|
|
|
36
37
|
IDS.add(this, 'Request')
|
|
@@ -43,6 +44,10 @@ class Request extends EventEmitter {
|
|
|
43
44
|
this.parameters = {}
|
|
44
45
|
this.stream = null
|
|
45
46
|
this.arrayRowMode = null
|
|
47
|
+
this.overrides = {}
|
|
48
|
+
if (Number.isFinite(overrides?.requestTimeout) && overrides.requestTimeout >= 0) {
|
|
49
|
+
this.overrides.requestTimeout = overrides.requestTimeout
|
|
50
|
+
}
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
get paused () {
|
package/lib/base/transaction.js
CHANGED
|
@@ -28,10 +28,11 @@ class Transaction extends EventEmitter {
|
|
|
28
28
|
/**
|
|
29
29
|
* Create new Transaction.
|
|
30
30
|
*
|
|
31
|
-
* @param {Connection} [parent] If
|
|
31
|
+
* @param {Connection} [parent] If omitted, global connection is used instead.
|
|
32
|
+
* @param {{ requestTimeout?: number }} [overrides]
|
|
32
33
|
*/
|
|
33
34
|
|
|
34
|
-
constructor (parent) {
|
|
35
|
+
constructor (parent, overrides = {}) {
|
|
35
36
|
super()
|
|
36
37
|
|
|
37
38
|
IDS.add(this, 'Transaction')
|
|
@@ -40,6 +41,10 @@ class Transaction extends EventEmitter {
|
|
|
40
41
|
this.parent = parent || globalConnection.pool
|
|
41
42
|
this.isolationLevel = Transaction.defaultIsolationLevel
|
|
42
43
|
this.name = ''
|
|
44
|
+
this.overrides = {}
|
|
45
|
+
if (Number.isFinite(overrides?.requestTimeout) && overrides.requestTimeout >= 0) {
|
|
46
|
+
this.overrides.requestTimeout = overrides.requestTimeout
|
|
47
|
+
}
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
get config () {
|
|
@@ -219,11 +224,16 @@ class Transaction extends EventEmitter {
|
|
|
219
224
|
/**
|
|
220
225
|
* Returns new request using this transaction.
|
|
221
226
|
*
|
|
227
|
+
* @param {{ requestTimeout?: number }} [config]
|
|
222
228
|
* @return {Request}
|
|
223
229
|
*/
|
|
224
230
|
|
|
225
|
-
request () {
|
|
226
|
-
|
|
231
|
+
request (config) {
|
|
232
|
+
const overrides = { ...this.overrides }
|
|
233
|
+
if (Number.isFinite(config?.requestTimeout) && config.requestTimeout >= 0) {
|
|
234
|
+
overrides.requestTimeout = config.requestTimeout
|
|
235
|
+
}
|
|
236
|
+
return new shared.driver.Request(this, overrides)
|
|
227
237
|
}
|
|
228
238
|
|
|
229
239
|
/**
|
|
@@ -172,7 +172,7 @@ class Request extends BaseRequest {
|
|
|
172
172
|
setImmediate(callback, new RequestError("You can't use table variables for bulk insert.", 'ENAME'))
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
this.parent.acquire(this, (err, connection) => {
|
|
175
|
+
this.parent.acquire(this, (err, connection, config) => {
|
|
176
176
|
let hasReturned = false
|
|
177
177
|
if (!err) {
|
|
178
178
|
debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this))
|
|
@@ -244,7 +244,10 @@ class Request extends BaseRequest {
|
|
|
244
244
|
objectid = table.path
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
return connection.queryRaw(
|
|
247
|
+
return connection.queryRaw({
|
|
248
|
+
query_str: `if object_id('${objectid.replace(/'/g, '\'\'')}') is null ${table.declare()}`,
|
|
249
|
+
query_timeout: (this.overrides.requestTimeout ?? config.requestTimeout) / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported)
|
|
250
|
+
}, function (err) {
|
|
248
251
|
if (err) { return done(err) }
|
|
249
252
|
go()
|
|
250
253
|
})
|
|
@@ -389,7 +392,7 @@ class Request extends BaseRequest {
|
|
|
389
392
|
|
|
390
393
|
const req = connection.queryRaw({
|
|
391
394
|
query_str: command,
|
|
392
|
-
query_timeout: config.requestTimeout / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported)
|
|
395
|
+
query_timeout: (this.overrides.requestTimeout ?? config.requestTimeout) / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported)
|
|
393
396
|
}, params)
|
|
394
397
|
|
|
395
398
|
this._setCurrentRequest(req)
|
package/lib/tedious/request.js
CHANGED
|
@@ -176,7 +176,7 @@ const createColumns = function (metadata, arrayRowMode) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
const valueCorrection = function (value, metadata) {
|
|
179
|
-
const type = getMssqlType(metadata.type)
|
|
179
|
+
const type = getMssqlType(metadata.type, metadata.dataLength)
|
|
180
180
|
if (valueHandler.has(type)) {
|
|
181
181
|
return valueHandler.get(type)(value)
|
|
182
182
|
} else if ((metadata.type === tds.TYPES.UDT) && (value != null)) {
|
|
@@ -365,6 +365,9 @@ class Request extends BaseRequest {
|
|
|
365
365
|
|
|
366
366
|
connection.execBulkLoad(bulk, table.rows)
|
|
367
367
|
})
|
|
368
|
+
if (typeof this.overrides.requestTimeout === 'number') {
|
|
369
|
+
req.setTimeout(this.overrides.requestTimeout)
|
|
370
|
+
}
|
|
368
371
|
this._setCurrentRequest(req)
|
|
369
372
|
|
|
370
373
|
connection.execSqlBatch(req)
|
|
@@ -514,6 +517,10 @@ class Request extends BaseRequest {
|
|
|
514
517
|
}
|
|
515
518
|
})
|
|
516
519
|
|
|
520
|
+
if (typeof this.overrides.requestTimeout === 'number') {
|
|
521
|
+
req.setTimeout(this.overrides.requestTimeout)
|
|
522
|
+
}
|
|
523
|
+
|
|
517
524
|
this._setCurrentRequest(req)
|
|
518
525
|
|
|
519
526
|
req.on('columnMetadata', metadata => {
|
|
@@ -874,6 +881,10 @@ class Request extends BaseRequest {
|
|
|
874
881
|
}
|
|
875
882
|
})
|
|
876
883
|
|
|
884
|
+
if (typeof this.overrides.requestTimeout === 'number') {
|
|
885
|
+
req.setTimeout(this.overrides.requestTimeout)
|
|
886
|
+
}
|
|
887
|
+
|
|
877
888
|
this._setCurrentRequest(req)
|
|
878
889
|
|
|
879
890
|
req.on('columnMetadata', metadata => {
|
|
@@ -7,8 +7,8 @@ const TransactionError = require('../error/transaction-error')
|
|
|
7
7
|
const { CHANNELS, publish } = require('../diagnostics')
|
|
8
8
|
|
|
9
9
|
class Transaction extends BaseTransaction {
|
|
10
|
-
constructor (parent) {
|
|
11
|
-
super(parent)
|
|
10
|
+
constructor (parent, overrides) {
|
|
11
|
+
super(parent, overrides)
|
|
12
12
|
|
|
13
13
|
this._abort = () => {
|
|
14
14
|
if (!this._rollbackRequested) {
|