@depup/mysql2 3.19.0-depup.0 → 3.20.0-depup.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 +14 -103
- package/lib/auth_plugins/caching_sha2_password.js +1 -0
- package/lib/auth_plugins/sha256_password.js +7 -1
- package/lib/base/connection.js +166 -19
- package/lib/base/pool.js +71 -40
- package/lib/connection_config.js +5 -2
- package/lib/packets/packet.js +40 -8
- package/lib/pool_connection.js +71 -2
- package/lib/promise/pool_connection.js +1 -5
- package/lib/tracing.js +81 -0
- package/package.json +24 -13
- package/promise.d.ts +2 -2
- package/promise.js +2 -0
- package/typings/mysql/index.d.ts +8 -3
- package/typings/mysql/lib/Tracing.d.ts +71 -0
- package/lib/base/pool_connection.js +0 -77
package/README.md
CHANGED
|
@@ -1,114 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
[npm-url]: https://npmjs.com/package/mysql2
|
|
3
|
-
[node-version-image]: https://img.shields.io/node/v/mysql2.svg
|
|
4
|
-
[node-version-url]: https://nodejs.org/en/download
|
|
5
|
-
[downloads-image]: https://img.shields.io/npm/dm/mysql2.svg
|
|
6
|
-
[downloads-url]: https://npmjs.com/package/mysql2
|
|
7
|
-
[license-url]: https://github.com/sidorares/node-mysql2/blob/master/License
|
|
8
|
-
[license-image]: https://img.shields.io/npm/l/mysql2.svg?maxAge=2592000
|
|
9
|
-
[node-mysql]: https://github.com/mysqljs/mysql
|
|
10
|
-
[mysqljs]: https://github.com/mysqljs
|
|
11
|
-
[mysql-native]: https://github.com/sidorares/nodejs-mysql-native
|
|
12
|
-
[sidorares]: https://github.com/sidorares
|
|
13
|
-
[TooTallNate]: https://gist.github.com/TooTallNate
|
|
14
|
-
[starttls.js]: https://gist.github.com/TooTallNate/848444
|
|
15
|
-
[node-mariasql]: https://github.com/mscdex/node-mariasql
|
|
16
|
-
[contributors]: https://github.com/sidorares/node-mysql2/graphs/contributors
|
|
17
|
-
[contributing]: https://github.com/sidorares/node-mysql2/blob/master/Contributing.md
|
|
18
|
-
[docs-base]: https://sidorares.github.io/node-mysql2/docs
|
|
19
|
-
[docs-base-zh-CN]: https://sidorares.github.io/node-mysql2/zh-CN/docs
|
|
20
|
-
[docs-base-pt-BR]: https://sidorares.github.io/node-mysql2/pt-BR/docs
|
|
21
|
-
[docs-prepared-statements]: https://sidorares.github.io/node-mysql2/docs/documentation/prepared-statements
|
|
22
|
-
[docs-mysql-server]: https://sidorares.github.io/node-mysql2/docs/documentation/mysql-server
|
|
23
|
-
[docs-promise-wrapper]: https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper
|
|
24
|
-
[docs-authentication-switch]: https://sidorares.github.io/node-mysql2/docs/documentation/authentication-switch
|
|
25
|
-
[docs-streams]: https://sidorares.github.io/node-mysql2/docs/documentation/extras
|
|
26
|
-
[docs-typescript-docs]: https://sidorares.github.io/node-mysql2/docs/documentation/typescript-examples
|
|
27
|
-
[docs-qs-pooling]: https://sidorares.github.io/node-mysql2/docs#using-connection-pools
|
|
28
|
-
[docs-qs-first-query]: https://sidorares.github.io/node-mysql2/docs#first-query
|
|
29
|
-
[docs-qs-using-prepared-statements]: https://sidorares.github.io/node-mysql2/docs#using-prepared-statements
|
|
30
|
-
[docs-examples]: https://sidorares.github.io/node-mysql2/docs/examples
|
|
31
|
-
[docs-faq]: https://sidorares.github.io/node-mysql2/docs/faq
|
|
32
|
-
[docs-documentation]: https://sidorares.github.io/node-mysql2/docs/documentation
|
|
33
|
-
[docs-contributing]: https://sidorares.github.io/node-mysql2/docs/contributing/website
|
|
34
|
-
[coverage]: https://img.shields.io/codecov/c/github/sidorares/node-mysql2
|
|
35
|
-
[coverage-url]: https://app.codecov.io/github/sidorares/node-mysql2
|
|
36
|
-
[ci-url]: https://github.com/sidorares/node-mysql2/actions/workflows/ci-coverage.yml?query=branch%3Amaster
|
|
37
|
-
[ci-image]: https://img.shields.io/github/actions/workflow/status/sidorares/node-mysql2/ci-coverage.yml?event=push&style=flat&label=CI&branch=master
|
|
1
|
+
# @depup/mysql2
|
|
38
2
|
|
|
39
|
-
|
|
3
|
+
> Dependency-bumped version of [mysql2](https://www.npmjs.com/package/mysql2)
|
|
40
4
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
[![Node.js Version][node-version-image]][node-version-url]
|
|
44
|
-
[![GitHub Workflow Status (with event)][ci-image]][ci-url]
|
|
45
|
-
[![Codecov][coverage]][coverage-url]
|
|
46
|
-
[![License][license-image]][license-url]
|
|
47
|
-
|
|
48
|
-
[English][docs-base] | [简体中文][docs-base-zh-CN] | [Português (BR)][docs-base-pt-BR]
|
|
49
|
-
|
|
50
|
-
> MySQL client for Node.js with focus on performance. Supports prepared statements, non-utf8 encodings, binary log protocol, compression, ssl [much more][docs-documentation].
|
|
51
|
-
|
|
52
|
-
**Table of Contents**
|
|
53
|
-
|
|
54
|
-
- [History and Why MySQL2](#history-and-why-mysql2)
|
|
55
|
-
- [Installation](#installation)
|
|
56
|
-
- [Documentation](#documentation)
|
|
57
|
-
- [Acknowledgements](#acknowledgements)
|
|
58
|
-
- [Contributing](#contributing)
|
|
59
|
-
|
|
60
|
-
## History and Why MySQL2
|
|
61
|
-
|
|
62
|
-
MySQL2 project is a continuation of [MySQL-Native][mysql-native]. Protocol parser code was rewritten from scratch and api changed to match popular [Node MySQL][node-mysql]. MySQL2 team is working together with [Node MySQL][node-mysql] team to factor out shared code and move it under [mysqljs][mysqljs] organization.
|
|
63
|
-
|
|
64
|
-
MySQL2 is mostly API compatible with [Node MySQL][node-mysql] and supports majority of features. MySQL2 also offers these additional features:
|
|
65
|
-
|
|
66
|
-
- Faster / Better Performance
|
|
67
|
-
- [Prepared Statements][docs-prepared-statements]
|
|
68
|
-
- MySQL Binary Log Protocol
|
|
69
|
-
- [MySQL Server][docs-mysql-server]
|
|
70
|
-
- Extended support for Encoding and Collation
|
|
71
|
-
- [Promise Wrapper][docs-promise-wrapper]
|
|
72
|
-
- Compression
|
|
73
|
-
- SSL and [Authentication Switch][docs-authentication-switch]
|
|
74
|
-
- [Custom Streams][docs-streams]
|
|
75
|
-
- [Pooling][docs-qs-pooling]
|
|
5
|
+
Generated by [DepUp](https://github.com/depup/npm) -- all production
|
|
6
|
+
dependencies bumped to latest versions.
|
|
76
7
|
|
|
77
8
|
## Installation
|
|
78
9
|
|
|
79
|
-
MySQL2 is free from native bindings and can be installed on Linux, Mac OS or Windows without any issues.
|
|
80
|
-
|
|
81
10
|
```bash
|
|
82
|
-
npm install
|
|
11
|
+
npm install @depup/mysql2
|
|
83
12
|
```
|
|
84
13
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
> For TypeScript documentation and examples, see [here][docs-typescript-docs].
|
|
92
|
-
|
|
93
|
-
## Documentation
|
|
94
|
-
|
|
95
|
-
- [Quickstart][docs-base]
|
|
96
|
-
- [First Query][docs-qs-first-query], [Using Prepared Statements][docs-qs-using-prepared-statements], [Using Connection Pools][docs-qs-pooling] and more.
|
|
97
|
-
- [Documentation][docs-documentation]
|
|
98
|
-
- [Examples][docs-examples]
|
|
99
|
-
- [FAQ][docs-faq]
|
|
100
|
-
|
|
101
|
-
## Acknowledgements
|
|
102
|
-
|
|
103
|
-
- Internal protocol is written by [@sidorares][sidorares] [MySQL-Native][mysql-native].
|
|
104
|
-
- Constants, SQL parameters interpolation, Pooling, `ConnectionConfig` class taken from [Node MySQL][node-mysql].
|
|
105
|
-
- SSL upgrade code based on [@TooTallNate][TooTallNate] [code][starttls.js].
|
|
106
|
-
- Secure connection / compressed connection api flags compatible to [MariaSQL][node-mariasql] client.
|
|
107
|
-
- [Contributors][contributors].
|
|
14
|
+
| Field | Value |
|
|
15
|
+
|-------|-------|
|
|
16
|
+
| Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.20.0 |
|
|
17
|
+
| Processed | 2026-03-16 |
|
|
18
|
+
| Smoke test | passed |
|
|
19
|
+
| Deps updated | 0 |
|
|
108
20
|
|
|
109
|
-
|
|
21
|
+
---
|
|
110
22
|
|
|
111
|
-
|
|
112
|
-
Please check [Contributing.md][contributing] for detailed instruction on how to get started.
|
|
23
|
+
Source: https://github.com/depup/npm | Original: https://www.npmjs.com/package/mysql2
|
|
113
24
|
|
|
114
|
-
|
|
25
|
+
License inherited from the original package.
|
|
@@ -13,7 +13,13 @@ const STATE_FINAL = -1;
|
|
|
13
13
|
|
|
14
14
|
function encrypt(password, scramble, key) {
|
|
15
15
|
const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
|
|
16
|
-
return crypto.publicEncrypt(
|
|
16
|
+
return crypto.publicEncrypt(
|
|
17
|
+
{
|
|
18
|
+
key,
|
|
19
|
+
oaepHash: 'sha1',
|
|
20
|
+
},
|
|
21
|
+
stage1
|
|
22
|
+
);
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
module.exports =
|
package/lib/base/connection.js
CHANGED
|
@@ -28,6 +28,15 @@ const Packets = require('../packets/index.js');
|
|
|
28
28
|
const Commands = require('../commands/index.js');
|
|
29
29
|
const ConnectionConfig = require('../connection_config.js');
|
|
30
30
|
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
31
|
+
const {
|
|
32
|
+
traceCallback,
|
|
33
|
+
tracePromise,
|
|
34
|
+
getServerContext,
|
|
35
|
+
shouldTrace,
|
|
36
|
+
queryChannel,
|
|
37
|
+
executeChannel,
|
|
38
|
+
connectChannel,
|
|
39
|
+
} = require('../tracing.js');
|
|
31
40
|
|
|
32
41
|
let _connectionId = 0;
|
|
33
42
|
|
|
@@ -141,6 +150,41 @@ class BaseConnection extends EventEmitter {
|
|
|
141
150
|
this._notifyError(err);
|
|
142
151
|
});
|
|
143
152
|
this.addCommand(handshakeCommand);
|
|
153
|
+
|
|
154
|
+
// Trace the connection handshake
|
|
155
|
+
if (shouldTrace(connectChannel)) {
|
|
156
|
+
const config = this.config;
|
|
157
|
+
tracePromise(
|
|
158
|
+
connectChannel,
|
|
159
|
+
() =>
|
|
160
|
+
new Promise((resolve, reject) => {
|
|
161
|
+
/* eslint-disable prefer-const */
|
|
162
|
+
let onConnect, onError;
|
|
163
|
+
onConnect = (param) => {
|
|
164
|
+
this.removeListener('error', onError);
|
|
165
|
+
resolve(param);
|
|
166
|
+
};
|
|
167
|
+
onError = (err) => {
|
|
168
|
+
this.removeListener('connect', onConnect);
|
|
169
|
+
reject(err);
|
|
170
|
+
};
|
|
171
|
+
/* eslint-enable prefer-const */
|
|
172
|
+
this.once('connect', onConnect);
|
|
173
|
+
this.once('error', onError);
|
|
174
|
+
}),
|
|
175
|
+
() => {
|
|
176
|
+
const server = getServerContext(config);
|
|
177
|
+
return {
|
|
178
|
+
database: config.database || '',
|
|
179
|
+
serverAddress: server.serverAddress,
|
|
180
|
+
serverPort: server.serverPort,
|
|
181
|
+
user: config.user || '',
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
).catch(() => {
|
|
185
|
+
// errors are already handled by the handshake error listener
|
|
186
|
+
});
|
|
187
|
+
}
|
|
144
188
|
}
|
|
145
189
|
// in case there was no initial handshake but we need to read sting, assume it utf-8
|
|
146
190
|
// most common example: "Too many connections" error ( packet is sent immediately on connection attempt, we don't know server encoding yet)
|
|
@@ -601,7 +645,57 @@ class BaseConnection extends EventEmitter {
|
|
|
601
645
|
cmdQuery.values !== undefined ? cmdQuery.values : []
|
|
602
646
|
);
|
|
603
647
|
cmdQuery.sql = rawSql;
|
|
604
|
-
|
|
648
|
+
|
|
649
|
+
if (cmdQuery.onResult) {
|
|
650
|
+
// Callback mode: traceCallback wraps the callback with tracing lifecycle, or calls through directly when no subscribers are registered
|
|
651
|
+
traceCallback(
|
|
652
|
+
queryChannel,
|
|
653
|
+
(wrappedCb) => {
|
|
654
|
+
cmdQuery.onResult = wrappedCb;
|
|
655
|
+
this.addCommand(cmdQuery);
|
|
656
|
+
},
|
|
657
|
+
0,
|
|
658
|
+
() => {
|
|
659
|
+
const server = getServerContext(this.config);
|
|
660
|
+
return {
|
|
661
|
+
query: cmdQuery.sql,
|
|
662
|
+
values: cmdQuery.values,
|
|
663
|
+
database: this.config.database || '',
|
|
664
|
+
serverAddress: server.serverAddress,
|
|
665
|
+
serverPort: server.serverPort,
|
|
666
|
+
};
|
|
667
|
+
},
|
|
668
|
+
null,
|
|
669
|
+
cmdQuery.onResult
|
|
670
|
+
);
|
|
671
|
+
} else if (shouldTrace(queryChannel)) {
|
|
672
|
+
// Event-emitter mode: tracePromise wraps the async lifecycle
|
|
673
|
+
tracePromise(
|
|
674
|
+
queryChannel,
|
|
675
|
+
() =>
|
|
676
|
+
new Promise((resolve, reject) => {
|
|
677
|
+
cmdQuery.once('error', reject);
|
|
678
|
+
cmdQuery.once('end', () => resolve());
|
|
679
|
+
this.addCommand(cmdQuery);
|
|
680
|
+
}),
|
|
681
|
+
() => {
|
|
682
|
+
const server = getServerContext(this.config);
|
|
683
|
+
return {
|
|
684
|
+
query: cmdQuery.sql,
|
|
685
|
+
values: cmdQuery.values,
|
|
686
|
+
database: this.config.database || '',
|
|
687
|
+
serverAddress: server.serverAddress,
|
|
688
|
+
serverPort: server.serverPort,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
).catch(() => {
|
|
692
|
+
// errors are already emitted on the command
|
|
693
|
+
});
|
|
694
|
+
} else {
|
|
695
|
+
this.addCommand(cmdQuery);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return cmdQuery;
|
|
605
699
|
}
|
|
606
700
|
|
|
607
701
|
pause() {
|
|
@@ -702,25 +796,78 @@ class BaseConnection extends EventEmitter {
|
|
|
702
796
|
});
|
|
703
797
|
}
|
|
704
798
|
const executeCommand = new Commands.Execute(options, cb);
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
799
|
+
|
|
800
|
+
const prepareAndExecute = (errorCb) => {
|
|
801
|
+
const prepareCommand = new Commands.Prepare(options, (err, stmt) => {
|
|
802
|
+
if (err) {
|
|
803
|
+
// skip execute command if prepare failed
|
|
804
|
+
executeCommand.start = function () {
|
|
805
|
+
return null;
|
|
806
|
+
};
|
|
807
|
+
errorCb(err);
|
|
808
|
+
executeCommand.emit('end');
|
|
809
|
+
return;
|
|
716
810
|
}
|
|
717
|
-
executeCommand.
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
executeCommand
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
|
|
811
|
+
executeCommand.statement = stmt;
|
|
812
|
+
});
|
|
813
|
+
this.addCommand(prepareCommand);
|
|
814
|
+
this.addCommand(executeCommand);
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
if (executeCommand.onResult) {
|
|
818
|
+
// Callback mode: traceCallback wraps the callback with tracing lifecycle, or calls through directly when no subscribers are registered
|
|
819
|
+
const origExecCb = executeCommand.onResult;
|
|
820
|
+
traceCallback(
|
|
821
|
+
executeChannel,
|
|
822
|
+
(wrappedCb) => {
|
|
823
|
+
executeCommand.onResult = wrappedCb;
|
|
824
|
+
prepareAndExecute(wrappedCb);
|
|
825
|
+
},
|
|
826
|
+
0,
|
|
827
|
+
() => {
|
|
828
|
+
const server = getServerContext(this.config);
|
|
829
|
+
return {
|
|
830
|
+
query: options.sql,
|
|
831
|
+
values: options.values,
|
|
832
|
+
database: this.config.database || '',
|
|
833
|
+
serverAddress: server.serverAddress,
|
|
834
|
+
serverPort: server.serverPort,
|
|
835
|
+
};
|
|
836
|
+
},
|
|
837
|
+
null,
|
|
838
|
+
origExecCb
|
|
839
|
+
);
|
|
840
|
+
} else if (shouldTrace(executeChannel)) {
|
|
841
|
+
// Event-emitter mode: tracePromise wraps the async lifecycle
|
|
842
|
+
tracePromise(
|
|
843
|
+
executeChannel,
|
|
844
|
+
() =>
|
|
845
|
+
new Promise((resolve, reject) => {
|
|
846
|
+
prepareAndExecute((err) => {
|
|
847
|
+
executeCommand.emit('error', err);
|
|
848
|
+
});
|
|
849
|
+
executeCommand.once('error', reject);
|
|
850
|
+
executeCommand.once('end', () => resolve());
|
|
851
|
+
}),
|
|
852
|
+
() => {
|
|
853
|
+
const server = getServerContext(this.config);
|
|
854
|
+
return {
|
|
855
|
+
query: options.sql,
|
|
856
|
+
values: options.values,
|
|
857
|
+
database: this.config.database || '',
|
|
858
|
+
serverAddress: server.serverAddress,
|
|
859
|
+
serverPort: server.serverPort,
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
).catch(() => {
|
|
863
|
+
// errors are already emitted on the command
|
|
864
|
+
});
|
|
865
|
+
} else {
|
|
866
|
+
prepareAndExecute((err) => {
|
|
867
|
+
executeCommand.emit('error', err);
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
|
|
724
871
|
return executeCommand;
|
|
725
872
|
}
|
|
726
873
|
|
package/lib/base/pool.js
CHANGED
|
@@ -7,6 +7,11 @@ const PoolConnection = require('../pool_connection.js');
|
|
|
7
7
|
const Queue = require('denque');
|
|
8
8
|
const BaseConnection = require('./connection.js');
|
|
9
9
|
const Errors = require('../constants/errors.js');
|
|
10
|
+
const {
|
|
11
|
+
traceCallback,
|
|
12
|
+
getServerContext,
|
|
13
|
+
poolConnectChannel,
|
|
14
|
+
} = require('../tracing.js');
|
|
10
15
|
|
|
11
16
|
// Source: https://github.com/go-sql-driver/mysql/blob/76c00e35a8d48f8f70f0e7dffe584692bd3fa612/packets.go#L598-L613
|
|
12
17
|
function isReadOnlyError(err) {
|
|
@@ -49,46 +54,69 @@ class BasePool extends EventEmitter {
|
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
getConnection(cb) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return process.nextTick(() => cb(null, connection));
|
|
60
|
-
}
|
|
61
|
-
if (
|
|
62
|
-
this.config.connectionLimit === 0 ||
|
|
63
|
-
this._allConnections.length < this.config.connectionLimit
|
|
64
|
-
) {
|
|
65
|
-
connection = new PoolConnection(this, {
|
|
66
|
-
config: this.config.connectionConfig,
|
|
67
|
-
});
|
|
68
|
-
this._allConnections.push(connection);
|
|
69
|
-
return connection.connect((err) => {
|
|
70
|
-
if (this._closed) {
|
|
71
|
-
return cb(new Error('Pool is closed.'));
|
|
72
|
-
}
|
|
73
|
-
if (err) {
|
|
74
|
-
return cb(err);
|
|
75
|
-
}
|
|
76
|
-
this.emit('connection', connection);
|
|
57
|
+
const _getConnection = (cb) => {
|
|
58
|
+
if (this._closed) {
|
|
59
|
+
return process.nextTick(() => cb(new Error('Pool is closed.')));
|
|
60
|
+
}
|
|
61
|
+
let connection;
|
|
62
|
+
if (this._freeConnections.length > 0) {
|
|
63
|
+
connection = this._freeConnections.pop();
|
|
77
64
|
this.emit('acquire', connection);
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
65
|
+
return process.nextTick(() => {
|
|
66
|
+
connection._released = false;
|
|
67
|
+
cb(null, connection);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (
|
|
71
|
+
this.config.connectionLimit === 0 ||
|
|
72
|
+
this._allConnections.length < this.config.connectionLimit
|
|
73
|
+
) {
|
|
74
|
+
connection = new PoolConnection(this, {
|
|
75
|
+
config: this.config.connectionConfig,
|
|
76
|
+
});
|
|
77
|
+
this._allConnections.push(connection);
|
|
78
|
+
return connection.connect((err) => {
|
|
79
|
+
if (this._closed) {
|
|
80
|
+
return cb(new Error('Pool is closed.'));
|
|
81
|
+
}
|
|
82
|
+
if (err) {
|
|
83
|
+
return cb(err);
|
|
84
|
+
}
|
|
85
|
+
this.emit('connection', connection);
|
|
86
|
+
this.emit('acquire', connection);
|
|
87
|
+
return cb(null, connection);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (!this.config.waitForConnections) {
|
|
91
|
+
return process.nextTick(() =>
|
|
92
|
+
cb(new Error('No connections available.'))
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (
|
|
96
|
+
this.config.queueLimit &&
|
|
97
|
+
this._connectionQueue.length >= this.config.queueLimit
|
|
98
|
+
) {
|
|
99
|
+
return cb(new Error('Queue limit reached.'));
|
|
100
|
+
}
|
|
101
|
+
this.emit('enqueue');
|
|
102
|
+
return this._connectionQueue.push(cb);
|
|
103
|
+
};
|
|
104
|
+
const config = this.config.connectionConfig;
|
|
105
|
+
traceCallback(
|
|
106
|
+
poolConnectChannel,
|
|
107
|
+
_getConnection,
|
|
108
|
+
0,
|
|
109
|
+
() => {
|
|
110
|
+
const server = getServerContext(config);
|
|
111
|
+
return {
|
|
112
|
+
database: config.database || '',
|
|
113
|
+
serverAddress: server.serverAddress,
|
|
114
|
+
serverPort: server.serverPort,
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
null,
|
|
118
|
+
cb
|
|
119
|
+
);
|
|
92
120
|
}
|
|
93
121
|
|
|
94
122
|
releaseConnection(connection) {
|
|
@@ -101,7 +129,10 @@ class BasePool extends EventEmitter {
|
|
|
101
129
|
}
|
|
102
130
|
} else if (this._connectionQueue.length) {
|
|
103
131
|
cb = this._connectionQueue.shift();
|
|
104
|
-
process.nextTick(
|
|
132
|
+
process.nextTick(() => {
|
|
133
|
+
connection._released = false;
|
|
134
|
+
cb(null, connection);
|
|
135
|
+
});
|
|
105
136
|
} else {
|
|
106
137
|
this._freeConnections.push(connection);
|
|
107
138
|
this.emit('release', connection);
|
package/lib/connection_config.js
CHANGED
|
@@ -277,7 +277,10 @@ class ConnectionConfig {
|
|
|
277
277
|
user: decodeURIComponent(parsedUrl.username),
|
|
278
278
|
password: decodeURIComponent(parsedUrl.password),
|
|
279
279
|
};
|
|
280
|
-
parsedUrl.searchParams
|
|
280
|
+
for (const [key, value] of parsedUrl.searchParams) {
|
|
281
|
+
if (key in options) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
281
284
|
try {
|
|
282
285
|
// Try to parse this as a JSON expression first
|
|
283
286
|
options[key] = JSON.parse(value);
|
|
@@ -285,7 +288,7 @@ class ConnectionConfig {
|
|
|
285
288
|
// Otherwise assume it is a plain string
|
|
286
289
|
options[key] = value;
|
|
287
290
|
}
|
|
288
|
-
}
|
|
291
|
+
}
|
|
289
292
|
return options;
|
|
290
293
|
}
|
|
291
294
|
}
|
package/lib/packets/packet.js
CHANGED
|
@@ -406,8 +406,8 @@ class Packet {
|
|
|
406
406
|
readNullTerminatedString(encoding) {
|
|
407
407
|
const start = this.offset;
|
|
408
408
|
let end = this.offset;
|
|
409
|
-
while (this.buffer[end]) {
|
|
410
|
-
end = end + 1;
|
|
409
|
+
while (end < this.end && this.buffer[end] !== 0x00) {
|
|
410
|
+
end = end + 1;
|
|
411
411
|
}
|
|
412
412
|
this.offset = end + 1;
|
|
413
413
|
return StringParser.decode(this.buffer, encoding, start, end);
|
|
@@ -516,16 +516,20 @@ class Packet {
|
|
|
516
516
|
return result * sign;
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
-
//
|
|
519
|
+
// adapted from https://github.com/mysqljs/mysql/blob/dc9c152a87ec51a1f647447268917243d2eab1fd/lib/protocol/Parser.js
|
|
520
520
|
parseGeometryValue() {
|
|
521
521
|
const buffer = this.readLengthCodedBuffer();
|
|
522
522
|
let offset = 4;
|
|
523
523
|
if (buffer === null || !buffer.length) {
|
|
524
524
|
return null;
|
|
525
525
|
}
|
|
526
|
+
const bufferLength = buffer.length;
|
|
526
527
|
function parseGeometry() {
|
|
527
|
-
let x, y, i, j, numPoints, line;
|
|
528
|
+
let x, y, i, j, numPoints, numRings, num, line;
|
|
528
529
|
let result = null;
|
|
530
|
+
if (offset + 5 > bufferLength) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
529
533
|
const byteOrder = buffer.readUInt8(offset);
|
|
530
534
|
offset += 1;
|
|
531
535
|
const wkbType = byteOrder
|
|
@@ -534,6 +538,9 @@ class Packet {
|
|
|
534
538
|
offset += 4;
|
|
535
539
|
switch (wkbType) {
|
|
536
540
|
case 1: // WKBPoint
|
|
541
|
+
if (offset + 16 > bufferLength) {
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
537
544
|
x = byteOrder
|
|
538
545
|
? buffer.readDoubleLE(offset)
|
|
539
546
|
: buffer.readDoubleBE(offset);
|
|
@@ -545,12 +552,21 @@ class Packet {
|
|
|
545
552
|
result = { x: x, y: y };
|
|
546
553
|
break;
|
|
547
554
|
case 2: // WKBLineString
|
|
555
|
+
if (offset + 4 > bufferLength) {
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
548
558
|
numPoints = byteOrder
|
|
549
559
|
? buffer.readUInt32LE(offset)
|
|
550
560
|
: buffer.readUInt32BE(offset);
|
|
551
561
|
offset += 4;
|
|
562
|
+
if (numPoints > (bufferLength - offset) / 16) {
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
552
565
|
result = [];
|
|
553
566
|
for (i = numPoints; i > 0; i--) {
|
|
567
|
+
if (offset + 16 > bufferLength) {
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
554
570
|
x = byteOrder
|
|
555
571
|
? buffer.readDoubleLE(offset)
|
|
556
572
|
: buffer.readDoubleBE(offset);
|
|
@@ -563,19 +579,30 @@ class Packet {
|
|
|
563
579
|
}
|
|
564
580
|
break;
|
|
565
581
|
case 3: // WKBPolygon
|
|
566
|
-
|
|
567
|
-
|
|
582
|
+
if (offset + 4 > bufferLength) {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
numRings = byteOrder
|
|
568
586
|
? buffer.readUInt32LE(offset)
|
|
569
587
|
: buffer.readUInt32BE(offset);
|
|
570
588
|
offset += 4;
|
|
589
|
+
if (numRings > (bufferLength - offset) / 4) {
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
571
592
|
result = [];
|
|
572
593
|
for (i = numRings; i > 0; i--) {
|
|
594
|
+
if (offset + 4 > bufferLength) {
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
573
597
|
numPoints = byteOrder
|
|
574
598
|
? buffer.readUInt32LE(offset)
|
|
575
599
|
: buffer.readUInt32BE(offset);
|
|
576
600
|
offset += 4;
|
|
577
601
|
line = [];
|
|
578
602
|
for (j = numPoints; j > 0; j--) {
|
|
603
|
+
if (offset + 16 > bufferLength) {
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
579
606
|
x = byteOrder
|
|
580
607
|
? buffer.readDoubleLE(offset)
|
|
581
608
|
: buffer.readDoubleBE(offset);
|
|
@@ -593,11 +620,16 @@ class Packet {
|
|
|
593
620
|
case 5: // WKBMultiLineString
|
|
594
621
|
case 6: // WKBMultiPolygon
|
|
595
622
|
case 7: // WKBGeometryCollection
|
|
596
|
-
|
|
597
|
-
|
|
623
|
+
if (offset + 4 > bufferLength) {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
num = byteOrder
|
|
598
627
|
? buffer.readUInt32LE(offset)
|
|
599
628
|
: buffer.readUInt32BE(offset);
|
|
600
629
|
offset += 4;
|
|
630
|
+
if (num > (bufferLength - offset) / 9) {
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
601
633
|
result = [];
|
|
602
634
|
for (i = num; i > 0; i--) {
|
|
603
635
|
result.push(parseGeometry());
|
package/lib/pool_connection.js
CHANGED
|
@@ -1,12 +1,81 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Connection = require('./connection.js');
|
|
4
|
+
|
|
5
|
+
class PoolConnection extends Connection {
|
|
6
|
+
constructor(pool, options) {
|
|
7
|
+
super(options);
|
|
8
|
+
this._pool = pool;
|
|
9
|
+
this._released = false;
|
|
10
|
+
this.lastActiveTime = Date.now();
|
|
11
|
+
this.once('end', () => {
|
|
12
|
+
this._removeFromPool();
|
|
13
|
+
});
|
|
14
|
+
this.once('error', () => {
|
|
15
|
+
this._removeFromPool();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
release() {
|
|
20
|
+
if (this._released) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!this._pool || this._pool._closed) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this._released = true;
|
|
27
|
+
this.lastActiveTime = Date.now();
|
|
28
|
+
this._pool.releaseConnection(this);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
[Symbol.dispose]() {
|
|
32
|
+
this.release();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
end(callback) {
|
|
36
|
+
if (this.config.gracefulEnd) {
|
|
37
|
+
this._removeFromPool();
|
|
38
|
+
super.end(callback);
|
|
39
|
+
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const err = new Error(
|
|
44
|
+
'Calling conn.end() to release a pooled connection is ' +
|
|
45
|
+
'deprecated. In next version calling conn.end() will be ' +
|
|
46
|
+
'restored to default conn.end() behavior. Use ' +
|
|
47
|
+
'conn.release() instead.'
|
|
48
|
+
);
|
|
49
|
+
this.emit('warn', err);
|
|
50
|
+
console.warn(err.message);
|
|
51
|
+
this.release();
|
|
52
|
+
if (typeof callback === 'function') {
|
|
53
|
+
callback();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
destroy() {
|
|
58
|
+
this._removeFromPool();
|
|
59
|
+
super.destroy();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_removeFromPool() {
|
|
63
|
+
if (!this._pool || this._pool._closed) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const pool = this._pool;
|
|
67
|
+
this._pool = null;
|
|
68
|
+
pool._removeConnection(this);
|
|
69
|
+
}
|
|
4
70
|
|
|
5
|
-
class PoolConnection extends BasePoolConnection {
|
|
6
71
|
promise(promiseImpl) {
|
|
7
72
|
const PromisePoolConnection = require('./promise/pool_connection.js');
|
|
8
73
|
return new PromisePoolConnection(this, promiseImpl);
|
|
9
74
|
}
|
|
10
75
|
}
|
|
11
76
|
|
|
77
|
+
PoolConnection.statementKey = Connection.statementKey;
|
|
12
78
|
module.exports = PoolConnection;
|
|
79
|
+
|
|
80
|
+
// TODO: Remove this when we are removing PoolConnection#end
|
|
81
|
+
PoolConnection.prototype._realEnd = Connection.prototype.end;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PromiseConnection = require('./connection.js');
|
|
4
|
-
const BasePoolConnection = require('../base/pool_connection.js');
|
|
5
4
|
|
|
6
5
|
class PromisePoolConnection extends PromiseConnection {
|
|
7
6
|
constructor(connection, promiseImpl) {
|
|
@@ -9,10 +8,7 @@ class PromisePoolConnection extends PromiseConnection {
|
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
destroy() {
|
|
12
|
-
return
|
|
13
|
-
this.connection,
|
|
14
|
-
arguments
|
|
15
|
-
);
|
|
11
|
+
return this.connection.destroy();
|
|
16
12
|
}
|
|
17
13
|
|
|
18
14
|
async [Symbol.asyncDispose]() {
|
package/lib/tracing.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const process = require('process');
|
|
4
|
+
|
|
5
|
+
// Safe load: use getBuiltinModule if available, fallback to require, catch if unavailable
|
|
6
|
+
const dc = (() => {
|
|
7
|
+
try {
|
|
8
|
+
return 'getBuiltinModule' in process
|
|
9
|
+
? process.getBuiltinModule('node:diagnostics_channel')
|
|
10
|
+
: require('node:diagnostics_channel');
|
|
11
|
+
} catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
})();
|
|
15
|
+
|
|
16
|
+
const hasTracingChannel = typeof dc?.tracingChannel === 'function';
|
|
17
|
+
|
|
18
|
+
const queryChannel = hasTracingChannel
|
|
19
|
+
? dc.tracingChannel('mysql2:query')
|
|
20
|
+
: undefined;
|
|
21
|
+
|
|
22
|
+
const executeChannel = hasTracingChannel
|
|
23
|
+
? dc.tracingChannel('mysql2:execute')
|
|
24
|
+
: undefined;
|
|
25
|
+
|
|
26
|
+
const connectChannel = hasTracingChannel
|
|
27
|
+
? dc.tracingChannel('mysql2:connect')
|
|
28
|
+
: undefined;
|
|
29
|
+
|
|
30
|
+
const poolConnectChannel = hasTracingChannel
|
|
31
|
+
? dc.tracingChannel('mysql2:pool:connect')
|
|
32
|
+
: undefined;
|
|
33
|
+
|
|
34
|
+
function getServerContext(config) {
|
|
35
|
+
if (config.socketPath) {
|
|
36
|
+
return { serverAddress: config.socketPath, serverPort: undefined };
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
serverAddress: config.host || 'localhost',
|
|
40
|
+
serverPort: config.port || 3306,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Node 20+: TracingChannel has an aggregated hasSubscribers getter.
|
|
45
|
+
// Node 18.x: that getter is missing (undefined), fall back to start sub-channel.
|
|
46
|
+
function shouldTrace(channel) {
|
|
47
|
+
if (channel === undefined || channel === null) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return channel.hasSubscribers ?? channel.start?.hasSubscribers ?? false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Generic traceCallback wrapper — calls fn synchronously, wraps the callback
|
|
54
|
+
// at args[position] to emit asyncStart/asyncEnd/error. No promises involved.
|
|
55
|
+
function traceCallback(channel, fn, position, context, thisArg, ...args) {
|
|
56
|
+
if (shouldTrace(channel)) {
|
|
57
|
+
return channel.traceCallback(fn, position, context(), thisArg, ...args);
|
|
58
|
+
}
|
|
59
|
+
return fn.apply(thisArg, args);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// tracePromise for operations that are inherently async (connection handshake)
|
|
63
|
+
function tracePromise(channel, fn, contextFactory) {
|
|
64
|
+
if (shouldTrace(channel)) {
|
|
65
|
+
return channel.tracePromise(fn, contextFactory());
|
|
66
|
+
}
|
|
67
|
+
return fn();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
dc,
|
|
72
|
+
hasTracingChannel,
|
|
73
|
+
shouldTrace,
|
|
74
|
+
queryChannel,
|
|
75
|
+
executeChannel,
|
|
76
|
+
connectChannel,
|
|
77
|
+
poolConnectChannel,
|
|
78
|
+
getServerContext,
|
|
79
|
+
traceCallback,
|
|
80
|
+
tracePromise,
|
|
81
|
+
};
|
package/package.json
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/mysql2",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS",
|
|
3
|
+
"version": "3.20.0-depup.0",
|
|
4
|
+
"description": "[DepUp] fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "typings/mysql/index",
|
|
7
7
|
"type": "commonjs",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"lint": "eslint . && prettier --check .",
|
|
10
10
|
"lint:fix": "eslint . --fix && prettier --write .",
|
|
11
|
-
"test": "
|
|
12
|
-
"test:
|
|
13
|
-
"test:
|
|
14
|
-
"test:bun": "npm run test:bun:parallel && npm run test:bun:global",
|
|
15
|
-
"test:bun:parallel": "bun poku -c=\"poku.config.mjs\" test",
|
|
16
|
-
"test:bun:global": "cross-env SUITE=global bun poku -c=\"poku.config.mjs\" test/global",
|
|
17
|
-
"test:deno": "npm run test:deno:parallel && npm run test:deno:global",
|
|
18
|
-
"test:deno:parallel": "deno run --allow-read --allow-env --allow-run npm:poku@canary -c=\"poku.config.mjs\" test",
|
|
19
|
-
"test:deno:global": "cross-env SUITE=global deno run --allow-read --allow-env --allow-run npm:poku@canary -c=\"poku.config.mjs\" test/global",
|
|
11
|
+
"test": "poku",
|
|
12
|
+
"test:bun": "bun poku",
|
|
13
|
+
"test:deno": "deno run -A npm:poku",
|
|
20
14
|
"test:docker:up": "docker compose -f test/docker-compose.yml up --abort-on-container-exit --remove-orphans",
|
|
21
15
|
"test:docker:down": "docker compose -f test/docker-compose.yml down",
|
|
22
16
|
"test:docker:node": "npm run test:docker:up -- node && npm run test:docker:down",
|
|
@@ -24,6 +18,7 @@
|
|
|
24
18
|
"test:docker:deno": "npm run test:docker:up -- deno && npm run test:docker:down",
|
|
25
19
|
"test:docker:coverage": "npm run test:docker:up -- coverage && npm run test:docker:down",
|
|
26
20
|
"test:coverage": "c8 npm test",
|
|
21
|
+
"test:build": "rollup -c",
|
|
27
22
|
"typecheck": "cd \"test/tsc-build\" && tsc -p \"tsconfig.json\" && cd .. && tsc -p \"tsconfig.json\" --noEmit",
|
|
28
23
|
"benchmark": "node ./benchmarks/benchmark.js",
|
|
29
24
|
"wait-port": "wait-on"
|
|
@@ -34,6 +29,10 @@
|
|
|
34
29
|
},
|
|
35
30
|
"homepage": "https://sidorares.github.io/node-mysql2/docs",
|
|
36
31
|
"keywords": [
|
|
32
|
+
"depup",
|
|
33
|
+
"dependency-bumped",
|
|
34
|
+
"updated-deps",
|
|
35
|
+
"mysql2",
|
|
37
36
|
"mysql",
|
|
38
37
|
"client",
|
|
39
38
|
"server"
|
|
@@ -75,22 +74,34 @@
|
|
|
75
74
|
"@eslint/js": "^9.39.2",
|
|
76
75
|
"@eslint/markdown": "^7.5.1",
|
|
77
76
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
|
77
|
+
"@pokujs/multi-suite": "^1.0.0",
|
|
78
|
+
"@rollup/plugin-commonjs": "^29.0.2",
|
|
79
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
80
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
78
81
|
"@types/node": "^25.3.0",
|
|
79
82
|
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
80
83
|
"@typescript-eslint/parser": "^8.56.0",
|
|
81
84
|
"assert-diff": "^3.0.4",
|
|
82
85
|
"benchmark": "^2.1.4",
|
|
83
86
|
"c8": "^11.0.0",
|
|
84
|
-
"cross-env": "^10.1.0",
|
|
85
87
|
"error-stack-parser": "^2.1.4",
|
|
86
88
|
"eslint-config-prettier": "^10.1.8",
|
|
87
89
|
"eslint-plugin-async-await": "^0.0.0",
|
|
88
90
|
"eslint-plugin-prettier": "^5.5.5",
|
|
89
91
|
"globals": "^17.3.0",
|
|
90
|
-
"poku": "^
|
|
92
|
+
"poku": "^4.1.0",
|
|
91
93
|
"portfinder": "^1.0.38",
|
|
92
94
|
"prettier": "^3.8.1",
|
|
95
|
+
"rollup": "^4.59.0",
|
|
93
96
|
"tsx": "^4.21.0",
|
|
94
97
|
"typescript": "^5.9.3"
|
|
98
|
+
},
|
|
99
|
+
"depup": {
|
|
100
|
+
"changes": {},
|
|
101
|
+
"depsUpdated": 0,
|
|
102
|
+
"originalPackage": "mysql2",
|
|
103
|
+
"originalVersion": "3.20.0",
|
|
104
|
+
"processedAt": "2026-03-16T00:39:43.420Z",
|
|
105
|
+
"smokeTest": "passed"
|
|
95
106
|
}
|
|
96
107
|
}
|
package/promise.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface PreparedStatementInfo {
|
|
|
40
40
|
>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export
|
|
43
|
+
export declare class Connection extends QueryableAndExecutableBase {
|
|
44
44
|
config: ConnectionOptions;
|
|
45
45
|
|
|
46
46
|
threadId: number;
|
|
@@ -81,7 +81,7 @@ export interface Connection extends QueryableAndExecutableBase {
|
|
|
81
81
|
format(sql: string, values?: any | any[] | { [param: string]: any }): string;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
export
|
|
84
|
+
export declare class PoolConnection extends Connection {
|
|
85
85
|
release(): void;
|
|
86
86
|
connection: Connection;
|
|
87
87
|
[Symbol.asyncDispose](): Promise<void>;
|
package/promise.js
CHANGED
|
@@ -185,6 +185,8 @@ exports.escape = SqlString.escape;
|
|
|
185
185
|
exports.escapeId = SqlString.escapeId;
|
|
186
186
|
exports.format = SqlString.format;
|
|
187
187
|
exports.raw = SqlString.raw;
|
|
188
|
+
exports.Connection = PromiseConnection;
|
|
189
|
+
exports.PoolConnection = PromisePoolConnection;
|
|
188
190
|
exports.PromisePool = PromisePool;
|
|
189
191
|
exports.PromiseConnection = PromiseConnection;
|
|
190
192
|
exports.PromisePoolConnection = PromisePoolConnection;
|
package/typings/mysql/index.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
PoolClusterOptions,
|
|
15
15
|
PoolNamespace,
|
|
16
16
|
} from './lib/PoolCluster.js';
|
|
17
|
-
import { PoolConnection as BasePoolConnection } from './lib/PoolConnection.js';
|
|
18
17
|
import {
|
|
19
18
|
Prepare as BasePrepare,
|
|
20
19
|
PrepareStatementInfo,
|
|
@@ -44,11 +43,10 @@ export * from './lib/Auth.js';
|
|
|
44
43
|
export * from './lib/constants/index.js';
|
|
45
44
|
export * from './lib/parsers/index.js';
|
|
46
45
|
export * from './lib/Connection.js';
|
|
46
|
+
export * from './lib/PoolConnection.js';
|
|
47
47
|
|
|
48
48
|
// Expose class interfaces
|
|
49
|
-
export interface Connection extends BaseConnection {}
|
|
50
49
|
export interface Pool extends BasePool {}
|
|
51
|
-
export interface PoolConnection extends BasePoolConnection {}
|
|
52
50
|
export interface PoolCluster extends BasePoolCluster {}
|
|
53
51
|
export interface Query extends BaseQuery {}
|
|
54
52
|
export interface Prepare extends BasePrepare {}
|
|
@@ -82,3 +80,10 @@ export interface ConnectionConfig extends ConnectionOptions {
|
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
export function createServer(handler: (conn: BaseConnection) => any): Server;
|
|
83
|
+
|
|
84
|
+
export type {
|
|
85
|
+
QueryTraceContext,
|
|
86
|
+
ExecuteTraceContext,
|
|
87
|
+
ConnectTraceContext,
|
|
88
|
+
PoolConnectTraceContext,
|
|
89
|
+
} from './lib/Tracing.js';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { TracingChannel } from 'node:diagnostics_channel';
|
|
2
|
+
|
|
3
|
+
export interface QueryTraceContext {
|
|
4
|
+
query: string;
|
|
5
|
+
values: any;
|
|
6
|
+
database: string;
|
|
7
|
+
serverAddress: string;
|
|
8
|
+
serverPort: number | undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ExecuteTraceContext {
|
|
12
|
+
query: string;
|
|
13
|
+
values: any;
|
|
14
|
+
database: string;
|
|
15
|
+
serverAddress: string;
|
|
16
|
+
serverPort: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ConnectTraceContext {
|
|
20
|
+
database: string;
|
|
21
|
+
serverAddress: string;
|
|
22
|
+
serverPort: number | undefined;
|
|
23
|
+
user: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface PoolConnectTraceContext {
|
|
27
|
+
database: string;
|
|
28
|
+
serverAddress: string;
|
|
29
|
+
serverPort: number | undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export declare const dc: typeof import('node:diagnostics_channel') | undefined;
|
|
33
|
+
export declare const hasTracingChannel: boolean;
|
|
34
|
+
|
|
35
|
+
export declare function shouldTrace(
|
|
36
|
+
channel: TracingChannel<object> | undefined | null
|
|
37
|
+
): boolean;
|
|
38
|
+
|
|
39
|
+
export declare function traceCallback<T extends object>(
|
|
40
|
+
channel: TracingChannel<T> | undefined | null,
|
|
41
|
+
fn: (...args: any[]) => any,
|
|
42
|
+
position: number,
|
|
43
|
+
contextFactory: () => T,
|
|
44
|
+
thisArg: any,
|
|
45
|
+
...args: any[]
|
|
46
|
+
): any;
|
|
47
|
+
|
|
48
|
+
export declare function tracePromise<T extends object, R>(
|
|
49
|
+
channel: TracingChannel<T> | undefined | null,
|
|
50
|
+
fn: () => Promise<R>,
|
|
51
|
+
contextFactory: () => T
|
|
52
|
+
): Promise<R>;
|
|
53
|
+
|
|
54
|
+
export declare const queryChannel:
|
|
55
|
+
| TracingChannel<QueryTraceContext>
|
|
56
|
+
| undefined;
|
|
57
|
+
export declare const executeChannel:
|
|
58
|
+
| TracingChannel<ExecuteTraceContext>
|
|
59
|
+
| undefined;
|
|
60
|
+
export declare const connectChannel:
|
|
61
|
+
| TracingChannel<ConnectTraceContext>
|
|
62
|
+
| undefined;
|
|
63
|
+
export declare const poolConnectChannel:
|
|
64
|
+
| TracingChannel<PoolConnectTraceContext>
|
|
65
|
+
| undefined;
|
|
66
|
+
|
|
67
|
+
export declare function getServerContext(config: {
|
|
68
|
+
socketPath?: string;
|
|
69
|
+
host?: string;
|
|
70
|
+
port?: number;
|
|
71
|
+
}): { serverAddress: string; serverPort: number | undefined };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const BaseConnection = require('./connection.js');
|
|
4
|
-
|
|
5
|
-
class BasePoolConnection extends BaseConnection {
|
|
6
|
-
constructor(pool, options) {
|
|
7
|
-
super(options);
|
|
8
|
-
this._pool = pool;
|
|
9
|
-
// The last active time of this connection
|
|
10
|
-
this.lastActiveTime = Date.now();
|
|
11
|
-
// When a fatal error occurs the connection's protocol ends, which will cause
|
|
12
|
-
// the connection to end as well, thus we only need to watch for the end event
|
|
13
|
-
// and we will be notified of disconnects.
|
|
14
|
-
// REVIEW: Moved to `once`
|
|
15
|
-
this.once('end', () => {
|
|
16
|
-
this._removeFromPool();
|
|
17
|
-
});
|
|
18
|
-
this.once('error', () => {
|
|
19
|
-
this._removeFromPool();
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
release() {
|
|
24
|
-
if (!this._pool || this._pool._closed) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
// update last active time
|
|
28
|
-
this.lastActiveTime = Date.now();
|
|
29
|
-
this._pool.releaseConnection(this);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[Symbol.dispose]() {
|
|
33
|
-
this.release();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
end(callback) {
|
|
37
|
-
if (this.config.gracefulEnd) {
|
|
38
|
-
this._removeFromPool();
|
|
39
|
-
super.end(callback);
|
|
40
|
-
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const err = new Error(
|
|
45
|
-
'Calling conn.end() to release a pooled connection is ' +
|
|
46
|
-
'deprecated. In next version calling conn.end() will be ' +
|
|
47
|
-
'restored to default conn.end() behavior. Use ' +
|
|
48
|
-
'conn.release() instead.'
|
|
49
|
-
);
|
|
50
|
-
this.emit('warn', err);
|
|
51
|
-
console.warn(err.message);
|
|
52
|
-
this.release();
|
|
53
|
-
if (typeof callback === 'function') {
|
|
54
|
-
callback();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
destroy() {
|
|
59
|
-
this._removeFromPool();
|
|
60
|
-
super.destroy();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_removeFromPool() {
|
|
64
|
-
if (!this._pool || this._pool._closed) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const pool = this._pool;
|
|
68
|
-
this._pool = null;
|
|
69
|
-
pool._removeConnection(this);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
BasePoolConnection.statementKey = BaseConnection.statementKey;
|
|
74
|
-
module.exports = BasePoolConnection;
|
|
75
|
-
|
|
76
|
-
// TODO: Remove this when we are removing PoolConnection#end
|
|
77
|
-
BasePoolConnection.prototype._realEnd = BaseConnection.prototype.end;
|