mssql 12.4.0 → 12.5.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/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} [holder]
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)
@@ -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 () {
@@ -28,10 +28,11 @@ class Transaction extends EventEmitter {
28
28
  /**
29
29
  * Create new Transaction.
30
30
  *
31
- * @param {Connection} [parent] If ommited, global connection is used instead.
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
- return new shared.driver.Request(this)
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(`if object_id('${objectid.replace(/'/g, '\'\'')}') is null ${table.declare()}`, function (err) {
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)
@@ -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) {
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "azure",
22
22
  "node-mssql"
23
23
  ],
24
- "version": "12.4.0",
24
+ "version": "12.5.0",
25
25
  "main": "index.js",
26
26
  "type": "commonjs",
27
27
  "repository": {