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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
'use strict'
 
const shared = require('./shared')
 
let globalConnection = null
const globalConnectionHandlers = {}
 
/**
 * Open global connection pool.
 *
 * @param {Object|String} config Connection configuration object or connection string.
 * @param {basicCallback} [callback] A callback which is called after connection has established, or an error has occurred. If omited, method returns Promise.
 * @return {Promise.<ConnectionPool>}
 */
 
function connect (config, callback) {
  if (!globalConnection) {
    globalConnection = new shared.driver.ConnectionPool(config)
 
    for (const event in globalConnectionHandlers) {
      for (let i = 0, l = globalConnectionHandlers[event].length; i < l; i++) {
        globalConnection.on(event, globalConnectionHandlers[event][i])
      }
    }
 
    const ogClose = globalConnection.close
 
    const globalClose = function (callback) {
      // remove event handlers from the global connection
      for (const event in globalConnectionHandlers) {
        for (let i = 0, l = globalConnectionHandlers[event].length; i < l; i++) {
          this.removeListener(event, globalConnectionHandlers[event][i])
        }
      }
 
      // attach error handler to prevent process crash in case of error
      this.on('error', err => {
        if (globalConnectionHandlers.error) {
          for (let i = 0, l = globalConnectionHandlers.error.length; i < l; i++) {
            globalConnectionHandlers.error[i].call(this, err)
          }
        }
      })
 
      globalConnection = null
      return ogClose.call(this, callback)
    }
 
    globalConnection.close = globalClose.bind(globalConnection)
  }
  if (typeof callback === 'function') {
    return globalConnection.connect((err, connection) => {
      if (err) {
        globalConnection = null
      }
      callback(err, connection)
    })
  }
  return globalConnection.connect().catch((err) => {
    globalConnection = null
    return shared.Promise.reject(err)
  })
}
 
/**
 * Close all active connections in the global pool.
 *
 * @param {basicCallback} [callback] A callback which is called after connection has closed, or an error has occurred. If omited, method returns Promise.
 * @return {ConnectionPool|Promise}
 */
 
function close (callback) {
  if (globalConnection) {
    const gc = globalConnection
    globalConnection = null
    return gc.close(callback)
  }
 
  if (typeof callback === 'function') {
    setImmediate(callback)
    return null
  }
 
  return new shared.Promise((resolve) => {
    resolve(globalConnection)
  })
}
 
/**
 * Attach event handler to global connection pool.
 *
 * @param {String} event Event name.
 * @param {Function} handler Event handler.
 * @return {ConnectionPool}
 */
 
function on (event, handler) {
  if (!globalConnectionHandlers[event]) globalConnectionHandlers[event] = []
  globalConnectionHandlers[event].push(handler)
 
  if (globalConnection) globalConnection.on(event, handler)
  return globalConnection
}
 
/**
 * Detach event handler from global connection.
 *
 * @param {String} event Event name.
 * @param {Function} handler Event handler.
 * @return {ConnectionPool}
 */
 
function removeListener (event, handler) {
  if (!globalConnectionHandlers[event]) return globalConnection
  const index = globalConnectionHandlers[event].indexOf(handler)
  if (index === -1) return globalConnection
  globalConnectionHandlers[event].splice(index, 1)
  if (globalConnectionHandlers[event].length === 0) globalConnectionHandlers[event] = undefined
 
  if (globalConnection) globalConnection.removeListener(event, handler)
  return globalConnection
}
 
/**
 * Creates a new query using global connection from a tagged template string.
 *
 * @variation 1
 * @param {Array|String} strings Array of string literals or sql command.
 * @param {...*} keys Values.
 * @return {Request}
 */
 
/**
 * Execute the SQL command.
 *
 * @variation 2
 * @param {String} command T-SQL command to be executed.
 * @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
 * @return {Request|Promise}
 */
 
function query () {
  if (typeof arguments[0] === 'string') { return new shared.driver.Request().query(arguments[0], arguments[1]) }
 
  const values = Array.prototype.slice.call(arguments)
  const strings = values.shift()
 
  return new shared.driver.Request()._template(strings, values, 'query')
}
 
/**
 * Creates a new batch using global connection from a tagged template string.
 *
 * @variation 1
 * @param {Array} strings Array of string literals.
 * @param {...*} keys Values.
 * @return {Request}
 */
 
/**
 * Execute the SQL command.
 *
 * @variation 2
 * @param {String} command T-SQL command to be executed.
 * @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
 * @return {Request|Promise}
 */
 
function batch () {
  if (typeof arguments[0] === 'string') { return new shared.driver.Request().batch(arguments[0], arguments[1]) }
 
  const values = Array.prototype.slice.call(arguments)
  const strings = values.shift()
 
  return new shared.driver.Request()._template(strings, values, 'batch')
}
 
module.exports = {
  batch,
  close,
  connect,
  off: removeListener,
  on,
  query,
  removeListener
}
 
Object.defineProperty(module.exports, 'pool', {
  get: () => {
    return globalConnection
  },
  set: () => {}
})