mysql2 3.0.0 → 3.1.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
@@ -132,6 +132,8 @@ const pool = mysql.createPool({
132
132
  database: 'test',
133
133
  waitForConnections: true,
134
134
  connectionLimit: 10,
135
+ maxIdle: 10, // max idle connections, the default value is the same as `connectionLimit`
136
+ idleTimeout: 60000, // idle connections timeout, in milliseconds, the default value 60000
135
137
  queueLimit: 0
136
138
  });
137
139
  ```
package/index.d.ts CHANGED
@@ -180,6 +180,8 @@ export interface ConnectionOptions extends mysql.ConnectionOptions {
180
180
  stream?: any;
181
181
  uri?: string;
182
182
  connectionLimit?: number;
183
+ maxIdle?: number;
184
+ idleTimeout?: number;
183
185
  Promise?: any;
184
186
  queueLimit?: number;
185
187
  waitForConnections?: boolean;
package/lib/auth_41.js CHANGED
@@ -41,16 +41,7 @@ function sha1(msg, msg1, msg2) {
41
41
  }
42
42
 
43
43
  function xor(a, b) {
44
- if (!Buffer.isBuffer(a)) {
45
- a = Buffer.from(a, 'binary');
46
- }
47
-
48
- if (!Buffer.isBuffer(b)) {
49
- b = Buffer.from(b, 'binary');
50
- }
51
-
52
44
  const result = Buffer.allocUnsafe(a.length);
53
-
54
45
  for (let i = 0; i < a.length; i++) {
55
46
  result[i] = a[i] ^ b[i];
56
47
  }
@@ -60,7 +51,6 @@ function xor(a, b) {
60
51
  exports.xor = xor;
61
52
 
62
53
  function token(password, scramble1, scramble2) {
63
- // TODO: use buffers (not sure why strings here)
64
54
  if (!password) {
65
55
  return Buffer.alloc(0);
66
56
  }
@@ -94,14 +84,6 @@ exports.doubleSha1 = function(password) {
94
84
  };
95
85
 
96
86
  function xorRotating(a, seed) {
97
- if (!Buffer.isBuffer(a)) {
98
- a = Buffer.from(a, 'binary');
99
- }
100
-
101
- if (!Buffer.isBuffer(seed)) {
102
- seed = Buffer.from(seed, 'binary');
103
- }
104
-
105
87
  const result = Buffer.allocUnsafe(a.length);
106
88
  const seedLen = seed.length;
107
89
 
@@ -17,24 +17,24 @@ const STATE_FINAL = -1;
17
17
 
18
18
  function sha256(msg) {
19
19
  const hash = crypto.createHash('sha256');
20
- hash.update(msg, 'binary');
21
- return hash.digest('binary');
20
+ hash.update(msg);
21
+ return hash.digest();
22
22
  }
23
23
 
24
24
  function calculateToken(password, scramble) {
25
25
  if (!password) {
26
26
  return Buffer.alloc(0);
27
27
  }
28
- const stage1 = sha256(Buffer.from(password, 'utf8').toString('binary'));
28
+ const stage1 = sha256(Buffer.from(password));
29
29
  const stage2 = sha256(stage1);
30
- const stage3 = sha256(stage2 + scramble.toString('binary'));
30
+ const stage3 = sha256(Buffer.concat([stage2, scramble]));
31
31
  return xor(stage1, stage3);
32
32
  }
33
33
 
34
34
  function encrypt(password, scramble, key) {
35
35
  const stage1 = xorRotating(
36
- Buffer.from(`${password}\0`, 'utf8').toString('binary'),
37
- scramble.toString('binary')
36
+ Buffer.from(`${password}\0`, 'utf8'),
37
+ scramble
38
38
  );
39
39
  return crypto.publicEncrypt(key, stage1);
40
40
  }
@@ -86,6 +86,7 @@ module.exports = (pluginOptions = {}) => ({ connection }) => {
86
86
  `Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state.`
87
87
  );
88
88
  case STATE_WAIT_SERVER_KEY:
89
+ console.log('Server pub key:', data);
89
90
  if (pluginOptions.onServerPublicKey) {
90
91
  pluginOptions.onServerPublicKey(data);
91
92
  }
@@ -12,8 +12,8 @@ const STATE_FINAL = -1;
12
12
 
13
13
  function encrypt(password, scramble, key) {
14
14
  const stage1 = xorRotating(
15
- Buffer.from(`${password}\0`, 'utf8').toString('binary'),
16
- scramble.toString('binary')
15
+ Buffer.from(`${password}\0`, 'utf8'),
16
+ scramble
17
17
  );
18
18
  return crypto.publicEncrypt(key, stage1);
19
19
  }
@@ -59,6 +59,8 @@ const validOptions = {
59
59
  user: 1,
60
60
  // These options are used for Pool
61
61
  connectionLimit: 1,
62
+ maxIdle: 1,
63
+ idleTimeout: 1,
62
64
  Promise: 1,
63
65
  queueLimit: 1,
64
66
  waitForConnections: 1
@@ -89,7 +91,7 @@ class ConnectionConfig {
89
91
  this.isServer = options.isServer;
90
92
  this.stream = options.stream;
91
93
  this.host = options.host || 'localhost';
92
- this.port = options.port || 3306;
94
+ this.port = (typeof options.port === 'string' ? parseInt(options.port, 10) : options.port)|| 3306;
93
95
  this.localAddress = options.localAddress;
94
96
  this.socketPath = options.socketPath;
95
97
  this.user = options.user || undefined;
@@ -252,7 +254,7 @@ class ConnectionConfig {
252
254
  const parsedUrl = new URL(url);
253
255
  const options = {
254
256
  host: parsedUrl.hostname,
255
- port: parsedUrl.port,
257
+ port: parseInt(parsedUrl.port, 10),
256
258
  database: parsedUrl.pathname.slice(1),
257
259
  user: parsedUrl.username,
258
260
  password: parsedUrl.password
package/lib/pool.js CHANGED
@@ -27,6 +27,10 @@ class Pool extends EventEmitter {
27
27
  this._freeConnections = new Queue();
28
28
  this._connectionQueue = new Queue();
29
29
  this._closed = false;
30
+ if (this.config.maxIdle < this.config.connectionLimit) {
31
+ // create idle connection timeout automatically release job
32
+ this._removeIdleTimeoutConnections();
33
+ }
30
34
  }
31
35
 
32
36
  promise(promiseImpl) {
@@ -40,7 +44,7 @@ class Pool extends EventEmitter {
40
44
  }
41
45
  let connection;
42
46
  if (this._freeConnections.length > 0) {
43
- connection = this._freeConnections.shift();
47
+ connection = this._freeConnections.pop();
44
48
  this.emit('acquire', connection);
45
49
  return process.nextTick(() => cb(null, connection));
46
50
  }
@@ -187,6 +191,26 @@ class Pool extends EventEmitter {
187
191
  this.releaseConnection(connection);
188
192
  }
189
193
 
194
+ _removeIdleTimeoutConnections() {
195
+ if (this._removeIdleTimeoutConnectionsTimer) {
196
+ clearTimeout(this._removeIdleTimeoutConnectionsTimer);
197
+ }
198
+
199
+ this._removeIdleTimeoutConnectionsTimer = setTimeout(() => {
200
+ try {
201
+ while (
202
+ this._freeConnections.length > this.config.maxIdle &&
203
+ Date.now() - this._freeConnections.get(0).lastActiveTime >
204
+ this.config.idleTimeout
205
+ ) {
206
+ this._freeConnections.get(0).destroy();
207
+ }
208
+ } finally {
209
+ this._removeIdleTimeoutConnections();
210
+ }
211
+ }, 1000);
212
+ }
213
+
190
214
  format(sql, values) {
191
215
  return mysql.format(
192
216
  sql,
@@ -15,6 +15,12 @@ class PoolConfig {
15
15
  this.connectionLimit = isNaN(options.connectionLimit)
16
16
  ? 10
17
17
  : Number(options.connectionLimit);
18
+ this.maxIdle = isNaN(options.maxIdle)
19
+ ? this.connectionLimit
20
+ : Number(options.maxIdle);
21
+ this.idleTimeout = isNaN(options.idleTimeout)
22
+ ? 60000
23
+ : Number(options.idleTimeout);
18
24
  this.queueLimit = isNaN(options.queueLimit)
19
25
  ? 0
20
26
  : Number(options.queueLimit);
@@ -6,6 +6,8 @@ class PoolConnection extends Connection {
6
6
  constructor(pool, options) {
7
7
  super(options);
8
8
  this._pool = pool;
9
+ // The last active time of this connection
10
+ this.lastActiveTime = Date.now();
9
11
  // When a fatal error occurs the connection's protocol ends, which will cause
10
12
  // the connection to end as well, thus we only need to watch for the end event
11
13
  // and we will be notified of disconnects.
@@ -22,6 +24,8 @@ class PoolConnection extends Connection {
22
24
  if (!this._pool || this._pool._closed) {
23
25
  return;
24
26
  }
27
+ // update last active time
28
+ this.lastActiveTime = Date.now();
25
29
  this._pool.releaseConnection(this);
26
30
  }
27
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql2",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -56,7 +56,6 @@
56
56
  "license": "MIT",
57
57
  "dependencies": {
58
58
  "denque": "^2.1.0",
59
- "eslint-config-prettier": "^8.5.0",
60
59
  "generate-function": "^2.3.1",
61
60
  "iconv-lite": "^0.6.3",
62
61
  "long": "^5.2.1",
@@ -77,6 +76,7 @@
77
76
  "chai": "^4.3.7",
78
77
  "error-stack-parser": "^2.0.3",
79
78
  "eslint": "^8.27.0",
79
+ "eslint-config-prettier": "^8.5.0",
80
80
  "eslint-plugin-async-await": "0.0.0",
81
81
  "eslint-plugin-markdown": "^3.0.0",
82
82
  "husky": "^8.0.2",
@@ -26,6 +26,16 @@ declare namespace Pool {
26
26
  */
27
27
  connectionLimit?: number;
28
28
 
29
+ /**
30
+ * The minimum number of idle connections. (Default: 10)
31
+ */
32
+ maxIdle?: number;
33
+
34
+ /**
35
+ * The idle connections timeout, in milliseconds. (Default: 60000)
36
+ */
37
+ idleTimeout?: number;
38
+
29
39
  /**
30
40
  * The maximum number of connection requests the pool will queue before returning an error from getConnection. If set to 0, there
31
41
  * is no limit to the number of queued connection requests. (Default: 0)