wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'use strict'
 
const msnodesql = require('msnodesqlv8')
const debug = require('debug')('mssql:msv8')
const BaseConnectionPool = require('../base/connection-pool')
const { IDS, INCREMENT } = require('../utils')
const shared = require('../shared')
const ConnectionError = require('../error/connection-error')
const { platform } = require('node:os')
const { build } = require('@tediousjs/connection-string')
 
const DEFAULT_CONNECTION_DRIVER = ['darwin', 'linux'].includes(platform()) ? 'ODBC Driver 17 for SQL Server' : 'SQL Server Native Client 11.0'
 
class ConnectionPool extends BaseConnectionPool {
  _poolCreate () {
    return new shared.Promise((resolve, reject) => {
      this.config.requestTimeout = this.config.requestTimeout ?? this.config.timeout ?? 15000
 
      const cfg = {
        conn_str: this.config.connectionString,
        conn_timeout: (this.config.connectionTimeout ?? this.config.timeout ?? 15000) / 1000
      }
 
      if (!this.config.connectionString) {
        cfg.conn_str = build({
          Driver: this.config.driver && this.config.driver !== 'msnodesqlv8' ? this.config.driver : DEFAULT_CONNECTION_DRIVER,
          Server: this.config.options.instanceName ? `${this.config.server}\\${this.config.options.instanceName}` : `${this.config.server},${this.config.port}`,
          Database: this.config.database,
          Uid: this.config.user,
          Pwd: this.config.password,
          Trusted_Connection: !!this.config.options.trustedConnection,
          Encrypt: !!this.config.options.encrypt
        })
      }
 
      const connedtionId = INCREMENT.Connection++
      debug('pool(%d): connection #%d created', IDS.get(this), connedtionId)
      debug('connection(%d): establishing', connedtionId)
 
      if (typeof this.config.beforeConnect === 'function') {
        this.config.beforeConnect(cfg)
      }
 
      msnodesql.open(cfg, (err, tds) => {
        if (err) {
          let customErr = err?.details
          if (customErr instanceof Array && (customErr = customErr.at(-1))) {
            err.message = customErr.message
            err.code = customErr.code
          }
 
          err = new ConnectionError(err.message, err.code)
          return reject(err)
        }
 
        tds.setUseNumericString(true)
 
        IDS.add(tds, 'Connection', connedtionId)
        tds.setUseUTC(this.config.options.useUTC)
        debug('connection(%d): established', IDS.get(tds))
        resolve(tds)
      })
    })
  }
 
  _poolValidate (tds) {
    if (tds && !tds.hasError) {
      return !this.config.validateConnection || new shared.Promise((resolve) => {
        tds.query('SELECT 1;', (err) => {
          resolve(!err)
        })
      })
    }
    return false
  }
 
  _poolDestroy (tds) {
    return new shared.Promise((resolve, reject) => {
      if (!tds) {
        resolve()
        return
      }
      debug('connection(%d): destroying', IDS.get(tds))
      tds.close(() => {
        debug('connection(%d): destroyed', IDS.get(tds))
        resolve()
      })
    })
  }
}
 
module.exports = ConnectionPool