connection-pool.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. 'use strict'
  2. const tds = require('tedious')
  3. const debug = require('debug')('mssql:tedi')
  4. const BaseConnectionPool = require('../base/connection-pool')
  5. const { IDS } = require('../utils')
  6. const shared = require('../shared')
  7. const ConnectionError = require('../error/connection-error')
  8. class ConnectionPool extends BaseConnectionPool {
  9. _poolCreate () {
  10. return new shared.Promise((resolve, reject) => {
  11. const resolveOnce = (v) => {
  12. resolve(v)
  13. resolve = reject = () => {}
  14. }
  15. const rejectOnce = (e) => {
  16. reject(e)
  17. resolve = reject = () => {}
  18. }
  19. const cfg = {
  20. server: this.config.server,
  21. options: Object.assign({
  22. encrypt: typeof this.config.encrypt === 'boolean' ? this.config.encrypt : false
  23. }, this.config.options),
  24. authentication: Object.assign({
  25. type: this.config.domain !== undefined ? 'ntlm' : 'default',
  26. options: {
  27. userName: this.config.user,
  28. password: this.config.password,
  29. domain: this.config.domain
  30. }
  31. }, this.config.authentication)
  32. }
  33. cfg.options.database = this.config.database
  34. cfg.options.port = this.config.port
  35. cfg.options.connectTimeout = this.config.connectionTimeout || this.config.timeout || 15000
  36. cfg.options.requestTimeout = this.config.requestTimeout != null ? this.config.requestTimeout : 15000
  37. cfg.options.tdsVersion = cfg.options.tdsVersion || '7_4'
  38. cfg.options.rowCollectionOnDone = false
  39. cfg.options.rowCollectionOnRequestCompletion = false
  40. cfg.options.useColumnNames = false
  41. cfg.options.appName = cfg.options.appName || 'node-mssql'
  42. // tedious always connect via tcp when port is specified
  43. if (cfg.options.instanceName) delete cfg.options.port
  44. if (isNaN(cfg.options.requestTimeout)) cfg.options.requestTimeout = 15000
  45. if (cfg.options.requestTimeout === Infinity) cfg.options.requestTimeout = 0
  46. if (cfg.options.requestTimeout < 0) cfg.options.requestTimeout = 0
  47. if (this.config.debug) {
  48. cfg.options.debug = {
  49. packet: true,
  50. token: true,
  51. data: true,
  52. payload: true
  53. }
  54. }
  55. const tedious = new tds.Connection(cfg)
  56. IDS.add(tedious, 'Connection')
  57. debug('pool(%d): connection #%d created', IDS.get(this), IDS.get(tedious))
  58. debug('connection(%d): establishing', IDS.get(tedious))
  59. tedious.once('connect', err => {
  60. if (err) {
  61. err = new ConnectionError(err)
  62. return rejectOnce(err)
  63. }
  64. debug('connection(%d): established', IDS.get(tedious))
  65. resolveOnce(tedious)
  66. })
  67. tedious.on('end', () => {
  68. const err = new ConnectionError('The connection ended without ever completing the connection')
  69. rejectOnce(err)
  70. })
  71. tedious.on('error', err => {
  72. if (err.code === 'ESOCKET') {
  73. tedious.hasError = true
  74. } else {
  75. this.emit('error', err)
  76. }
  77. rejectOnce(err)
  78. })
  79. if (this.config.debug) {
  80. tedious.on('debug', this.emit.bind(this, 'debug', tedious))
  81. }
  82. if (typeof this.config.beforeConnect === 'function') {
  83. this.config.beforeConnect(tedious)
  84. }
  85. })
  86. }
  87. _poolValidate (tedious) {
  88. return tedious && !tedious.closed && !tedious.hasError
  89. }
  90. _poolDestroy (tedious) {
  91. return new shared.Promise((resolve, reject) => {
  92. if (!tedious) {
  93. resolve()
  94. return
  95. }
  96. debug('connection(%d): destroying', IDS.get(tedious))
  97. if (tedious.closed) {
  98. debug('connection(%d): already closed', IDS.get(tedious))
  99. resolve()
  100. } else {
  101. tedious.once('end', () => {
  102. debug('connection(%d): destroyed', IDS.get(tedious))
  103. resolve()
  104. })
  105. tedious.close()
  106. }
  107. })
  108. }
  109. }
  110. module.exports = ConnectionPool