diff --git a/lib/base/connection-pool.js b/lib/base/connection-pool.js index 6dcc6fa9..62f675f6 100644 --- a/lib/base/connection-pool.js +++ b/lib/base/connection-pool.js @@ -508,8 +508,8 @@ class ConnectionPool extends EventEmitter { * @return {Request} */ - request () { - return new shared.driver.Request(this) + request (conf) { + return new shared.driver.Request(this, conf) } /** @@ -518,8 +518,8 @@ class ConnectionPool extends EventEmitter { * @return {Transaction} */ - transaction () { - return new shared.driver.Transaction(this) + transaction (conf) { + return new shared.driver.Transaction(this, conf) } /** diff --git a/lib/base/prepared-statement.js b/lib/base/prepared-statement.js index cda1797b..516e7ed9 100644 --- a/lib/base/prepared-statement.js +++ b/lib/base/prepared-statement.js @@ -20,10 +20,11 @@ class PreparedStatement extends EventEmitter { /** * Creates a new Prepared Statement. * - * @param {ConnectionPool|Transaction} [holder] + * @param {ConnectionPool|Transaction} [parent] + * @param {{[requestTimeout]: number}} [overrides] */ - constructor (parent) { + constructor (parent, overrides = {}) { super() IDS.add(this, 'PreparedStatement') @@ -33,6 +34,10 @@ class PreparedStatement extends EventEmitter { this._handle = 0 this.prepared = false this.parameters = {} + this.overrides = {} + if (typeof overrides?.requestTimeout === 'number') { + this.overrides.requestTimeout = overrides.requestTimeout + } } get config () { diff --git a/lib/base/request.js b/lib/base/request.js index cb7e4ee1..717a29c4 100644 --- a/lib/base/request.js +++ b/lib/base/request.js @@ -26,10 +26,11 @@ class Request extends EventEmitter { /** * Create new Request. * - * @param {Connection|ConnectionPool|Transaction|PreparedStatement} parent If omitted, global connection is used instead. + * @param {Connection|ConnectionPool|Transaction|PreparedStatement} [parent] If omitted, global connection is used instead. + * @param {{[requestTimeout]: number}} [overrides] */ - constructor (parent) { + constructor (parent, overrides) { super() IDS.add(this, 'Request') @@ -41,6 +42,10 @@ class Request extends EventEmitter { this.parameters = {} this.stream = null this.arrayRowMode = null + this.overrides = {} + if (typeof overrides?.requestTimeout === 'number') { + this.overrides.requestTimeout = overrides.requestTimeout + } } get paused () { diff --git a/lib/base/transaction.js b/lib/base/transaction.js index 42fbf45a..912e85bb 100644 --- a/lib/base/transaction.js +++ b/lib/base/transaction.js @@ -24,9 +24,10 @@ class Transaction extends EventEmitter { * Create new Transaction. * * @param {Connection} [parent] If ommited, global connection is used instead. + * @param {{[requestTimeout]: number}} [overrides] */ - constructor (parent) { + constructor (parent, overrides = {}) { super() IDS.add(this, 'Transaction') @@ -35,6 +36,10 @@ class Transaction extends EventEmitter { this.parent = parent || globalConnection.pool this.isolationLevel = Transaction.defaultIsolationLevel this.name = '' + this.overrides = {} + if (typeof overrides?.requestTimeout === 'number') { + this.overrides.requestTimeout = overrides.requestTimeout + } } get config () { @@ -196,11 +201,12 @@ class Transaction extends EventEmitter { /** * Returns new request using this transaction. * + * @param {{[requestTimout]: number}} [config] * @return {Request} */ - request () { - return new shared.driver.Request(this) + request (config) { + return new shared.driver.Request(this, config ?? this.overrides) } /** diff --git a/lib/msnodesqlv8/request.js b/lib/msnodesqlv8/request.js index c43502ef..8d088bd6 100644 --- a/lib/msnodesqlv8/request.js +++ b/lib/msnodesqlv8/request.js @@ -166,7 +166,7 @@ class Request extends BaseRequest { setImmediate(callback, new RequestError("You can't use table variables for bulk insert.", 'ENAME')) } - this.parent.acquire(this, (err, connection) => { + this.parent.acquire(this, (err, connection, config) => { let hasReturned = false if (!err) { debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this)) @@ -232,7 +232,10 @@ class Request extends BaseRequest { objectid = table.path } - return connection.queryRaw(`if object_id('${objectid.replace(/'/g, '\'\'')}') is null ${table.declare()}`, function (err) { + return connection.queryRaw({ + query_str: `if object_id('${objectid.replace(/'/g, '\'\'')}') is null ${table.declare()}`, + query_timeout: (this.overrides.requestTimeout ?? config.requestTimeout) / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported), + }, function (err) { if (err) { return done(err) } go() }) @@ -377,7 +380,7 @@ class Request extends BaseRequest { const req = connection.queryRaw({ query_str: command, - query_timeout: config.requestTimeout / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported) + query_timeout: (this.overrides.requestTimeout ?? config.requestTimeout) / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported) }, params) this._setCurrentRequest(req) diff --git a/lib/tedious/request.js b/lib/tedious/request.js index 63af04c7..82149389 100644 --- a/lib/tedious/request.js +++ b/lib/tedious/request.js @@ -345,6 +345,9 @@ class Request extends BaseRequest { connection.execBulkLoad(bulk, table.rows) }) + if (typeof this.overrides.requestTimeout === 'number') { + req.setTimeout(this.overrides.requestTimeout) + } this._setCurrentRequest(req) connection.execSqlBatch(req) @@ -494,6 +497,10 @@ class Request extends BaseRequest { } }) + if (typeof this.overrides.requestTimeout === 'number') { + req.setTimeout(this.overrides.requestTimeout) + } + this._setCurrentRequest(req) req.on('columnMetadata', metadata => {