@pi-r/mysql 0.7.3 → 0.8.1
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/client/index.js +50 -80
- package/client/pool.d.ts +9 -0
- package/client/pool.js +57 -0
- package/package.json +4 -4
- package/types/index.d.ts +3 -5
package/client/index.js
CHANGED
|
@@ -1,57 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT =
|
|
2
|
+
exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT = void 0;
|
|
3
|
+
exports.setAuthentication = setAuthentication;
|
|
4
|
+
exports.setCredential = setCredential;
|
|
5
|
+
exports.executeQuery = executeQuery;
|
|
6
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
7
|
+
exports.checkTimeout = checkTimeout;
|
|
3
8
|
const main = require("mysql2");
|
|
4
9
|
const mysql = require("mysql2/promise");
|
|
10
|
+
const Db = require("@e-mc/db");
|
|
5
11
|
const util_1 = require("@e-mc/db/util");
|
|
6
12
|
const types_1 = require("@e-mc/types");
|
|
7
|
-
const
|
|
8
|
-
const DbPool = require('@e-mc/db/pool');
|
|
9
|
-
class MySQLPool extends DbPool {
|
|
10
|
-
async getConnection() {
|
|
11
|
-
return this.client.getConnection();
|
|
12
|
-
}
|
|
13
|
-
async close() {
|
|
14
|
-
return this.client.end();
|
|
15
|
-
}
|
|
16
|
-
isEmpty() {
|
|
17
|
-
const pool = this.client.pool;
|
|
18
|
-
return this.closed || (0, util_1.checkEmpty)(pool._allConnections) && (0, util_1.checkEmpty)(pool._connectionQueue);
|
|
19
|
-
}
|
|
20
|
-
get closed() {
|
|
21
|
-
return !!this.client.pool._closed;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
13
|
+
const DbPool = require("@pi-r/mysql/client/pool");
|
|
24
14
|
const POOL_STATE = {};
|
|
25
|
-
const POOL_UNUSED = ['ssl', 'connectTimeout', 'queueLimit', 'waitForConnections', 'connectionLimit', 'maxIdle', 'idleTimeout', 'enableKeepAlive', 'keepAliveInitialDelay', 'Promise'];
|
|
26
|
-
const POOL_ACTIVE = new WeakSet();
|
|
27
|
-
function removePoolProperties(credential) {
|
|
28
|
-
if (!credential.uuidKey && POOL_ACTIVE.has(credential)) {
|
|
29
|
-
let result;
|
|
30
|
-
for (let i = 0, length = POOL_UNUSED.length; i < length; ++i) {
|
|
31
|
-
const attr = POOL_UNUSED[i];
|
|
32
|
-
if (attr in credential) {
|
|
33
|
-
result ||= { ...credential };
|
|
34
|
-
if (attr !== 'ssl') {
|
|
35
|
-
delete result[attr];
|
|
36
|
-
}
|
|
37
|
-
else if ((0, types_1.isObject)(result.ssl)) {
|
|
38
|
-
result[attr] = true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (result) {
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return credential;
|
|
47
|
-
}
|
|
48
|
-
function removeUUIDKey(credential) {
|
|
49
|
-
if ('uuidKey' in credential) {
|
|
50
|
-
credential = { ...credential };
|
|
51
|
-
delete credential.uuidKey;
|
|
52
|
-
}
|
|
53
|
-
return credential;
|
|
54
|
-
}
|
|
55
15
|
function isResultSetHeader(value) {
|
|
56
16
|
const result = Array.isArray(value) ? value[0] : value;
|
|
57
17
|
if (result && !Array.isArray(result)) {
|
|
@@ -63,11 +23,6 @@ function isResultSetHeader(value) {
|
|
|
63
23
|
}
|
|
64
24
|
return false;
|
|
65
25
|
}
|
|
66
|
-
function getPoolKey(credential) {
|
|
67
|
-
if ((credential.host || credential.socketPath) && credential.user) {
|
|
68
|
-
return JSON.stringify(removeUUIDKey(credential));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
26
|
function setAuthentication(credential) {
|
|
72
27
|
const auth = (0, util_1.parseServerAuth)(credential);
|
|
73
28
|
credential.host ||= auth.hostname;
|
|
@@ -76,7 +31,6 @@ function setAuthentication(credential) {
|
|
|
76
31
|
this.readTLSConfig(credential.ssl);
|
|
77
32
|
}
|
|
78
33
|
}
|
|
79
|
-
exports.setAuthentication = setAuthentication;
|
|
80
34
|
function setCredential(item) {
|
|
81
35
|
let credential = this.getCredential(item);
|
|
82
36
|
if (credential) {
|
|
@@ -86,18 +40,37 @@ function setCredential(item) {
|
|
|
86
40
|
credential = { uri: item.uri };
|
|
87
41
|
item.credential = credential;
|
|
88
42
|
}
|
|
43
|
+
let host;
|
|
89
44
|
if (!credential.uri) {
|
|
90
45
|
const errors = [];
|
|
91
|
-
if (!credential.host && !credential.socketPath) {
|
|
46
|
+
if (!(host = credential.host) && !credential.socketPath) {
|
|
92
47
|
errors.push('host');
|
|
93
48
|
}
|
|
94
49
|
if (!credential.user) {
|
|
95
50
|
errors.push('user');
|
|
96
51
|
}
|
|
97
|
-
if (errors.length) {
|
|
52
|
+
if (errors.length > 0) {
|
|
98
53
|
throw (0, types_1.errorMessage)("mysql", 'Not defined - ' + errors.join(' | '));
|
|
99
54
|
}
|
|
100
55
|
}
|
|
56
|
+
else {
|
|
57
|
+
try {
|
|
58
|
+
({ host } = new URL(credential.uri));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (host?.endsWith('.rds.amazonaws.com')) {
|
|
64
|
+
try {
|
|
65
|
+
const ssl = credential.ssl ||= {};
|
|
66
|
+
if ((0, types_1.isPlainObject)(ssl) && !ssl.ca) {
|
|
67
|
+
const bundle = require('aws-ssl-profiles');
|
|
68
|
+
ssl.ca = bundle.ca;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
101
74
|
const usePool = item.usePool;
|
|
102
75
|
if (!usePool) {
|
|
103
76
|
return;
|
|
@@ -132,18 +105,19 @@ function setCredential(item) {
|
|
|
132
105
|
credential.connectTimeout ??= timeout;
|
|
133
106
|
}
|
|
134
107
|
}
|
|
135
|
-
const poolKey =
|
|
108
|
+
const poolKey = DbPool.asString(credential);
|
|
136
109
|
if ((pool = POOL_STATE[poolKey]) && !pool.closed) {
|
|
137
110
|
pool.add(item);
|
|
138
111
|
return;
|
|
139
112
|
}
|
|
140
|
-
|
|
113
|
+
const client = mysql.createPool(DbPool.removeUUIDKey(credential));
|
|
114
|
+
new DbPool(client, poolKey, username && password ? { username, password } : undefined)
|
|
115
|
+
.add(item)
|
|
116
|
+
.parent = POOL_STATE;
|
|
141
117
|
}
|
|
142
|
-
exports.setCredential = setCredential;
|
|
143
118
|
async function executeQuery(item, options) {
|
|
144
119
|
return (await executeBatchQuery.call(this, [item], options))[0] || [];
|
|
145
120
|
}
|
|
146
|
-
exports.executeQuery = executeQuery;
|
|
147
121
|
async function executeBatchQuery(batch, options = '', outResult) {
|
|
148
122
|
const length = batch.length;
|
|
149
123
|
if (length === 0) {
|
|
@@ -178,20 +152,18 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
178
152
|
item.transactionState = 64;
|
|
179
153
|
let client;
|
|
180
154
|
if (mysqlPool) {
|
|
181
|
-
pools.push(client = await mysqlPool.getConnection());
|
|
155
|
+
pools.push(client = await mysqlPool.getConnection(credential));
|
|
182
156
|
item.transactionState &= ~64;
|
|
183
|
-
POOL_ACTIVE.add(credential);
|
|
184
157
|
return client;
|
|
185
158
|
}
|
|
186
|
-
const pool = item.usePool && DbPool.findKey(POOL_STATE, item.usePool,
|
|
159
|
+
const pool = item.usePool && DbPool.findKey(POOL_STATE, item.usePool, DbPool.asString(credential), ...connectOnce ? [item, batch[0]] : [item]);
|
|
187
160
|
if (pool) {
|
|
188
161
|
try {
|
|
189
|
-
pools.push(client = await pool.getConnection());
|
|
162
|
+
pools.push(client = await pool.getConnection(credential));
|
|
190
163
|
if (connectOnce) {
|
|
191
164
|
mysqlPool = pool;
|
|
192
165
|
}
|
|
193
166
|
pool.connected = true;
|
|
194
|
-
POOL_ACTIVE.add(credential);
|
|
195
167
|
}
|
|
196
168
|
catch (err) {
|
|
197
169
|
let close;
|
|
@@ -216,7 +188,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
216
188
|
}
|
|
217
189
|
}
|
|
218
190
|
if (!client) {
|
|
219
|
-
clients.push(client = await mysql.createConnection(removeUUIDKey(mysqlCredential || credential)));
|
|
191
|
+
clients.push(client = await mysql.createConnection(DbPool.removeUUIDKey(mysqlCredential || credential)));
|
|
220
192
|
}
|
|
221
193
|
if (connectOnce) {
|
|
222
194
|
if (!parallel) {
|
|
@@ -266,7 +238,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
266
238
|
if (caching && ignoreCache !== true && !streamRow) {
|
|
267
239
|
queryString = Db.asString(query, true) + '_' + Db.asString(params, true);
|
|
268
240
|
if (ignoreCache !== 1) {
|
|
269
|
-
const result = this.getQueryResult(source,
|
|
241
|
+
const result = this.getQueryResult(source, DbPool.sanitize(credential), queryString, cacheValue);
|
|
270
242
|
if (result) {
|
|
271
243
|
if (parallel) {
|
|
272
244
|
tasks[i] = Promise.resolve(result);
|
|
@@ -297,8 +269,8 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
297
269
|
try {
|
|
298
270
|
if (streamRow) {
|
|
299
271
|
const rows = [];
|
|
300
|
-
const processRow = typeof streamRow === 'function'
|
|
301
|
-
const client = mysql2Client || main.createConnection(removeUUIDKey(mysql2Credential || credential));
|
|
272
|
+
const processRow = typeof streamRow === 'function' ? streamRow : null;
|
|
273
|
+
const client = mysql2Client || main.createConnection(DbPool.removeUUIDKey(mysql2Credential || credential));
|
|
302
274
|
clients.push(client);
|
|
303
275
|
if (connectOnce) {
|
|
304
276
|
if (!parallel) {
|
|
@@ -329,7 +301,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
329
301
|
}
|
|
330
302
|
else {
|
|
331
303
|
this.add(item, 4);
|
|
332
|
-
resolve(!error ? this.setQueryResult(source,
|
|
304
|
+
resolve(!error ? this.setQueryResult(source, DbPool.sanitize(credential), queryString, rows, cacheValue) : rows.length > 0 ? rows : null);
|
|
333
305
|
}
|
|
334
306
|
});
|
|
335
307
|
}
|
|
@@ -347,7 +319,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
347
319
|
resolve(row1);
|
|
348
320
|
}
|
|
349
321
|
else {
|
|
350
|
-
resolve(!isResultSetHeader(row1) ? this.setQueryResult(source,
|
|
322
|
+
resolve(!isResultSetHeader(row1) ? this.setQueryResult(source, DbPool.sanitize(credential), queryString, rows, cacheValue) : null);
|
|
351
323
|
}
|
|
352
324
|
}
|
|
353
325
|
else {
|
|
@@ -375,25 +347,23 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
375
347
|
}
|
|
376
348
|
}
|
|
377
349
|
return this.processRows(batch, tasks, {
|
|
350
|
+
parallel,
|
|
378
351
|
disconnect: () => {
|
|
379
|
-
|
|
380
|
-
item.end(err => {
|
|
352
|
+
for (const item of clients) {
|
|
353
|
+
void item.end(err => {
|
|
381
354
|
if (err) {
|
|
382
355
|
this.writeFail(["Unable to close connnection", "mysql"], err, { type: 65536, fatal: false });
|
|
383
356
|
}
|
|
384
357
|
});
|
|
385
|
-
}
|
|
386
|
-
|
|
358
|
+
}
|
|
359
|
+
for (const item of pools) {
|
|
387
360
|
item.release();
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
parallel
|
|
361
|
+
}
|
|
362
|
+
}
|
|
391
363
|
}, outResult);
|
|
392
364
|
}
|
|
393
|
-
exports.executeBatchQuery = executeBatchQuery;
|
|
394
365
|
async function checkTimeout(value, limit = 0) {
|
|
395
366
|
return DbPool.checkTimeout(POOL_STATE, value, limit);
|
|
396
367
|
}
|
|
397
|
-
exports.checkTimeout = checkTimeout;
|
|
398
368
|
exports.DB_SOURCE_CLIENT = true;
|
|
399
369
|
exports.DB_SOURCE_TYPE = types_1.DB_TYPE.SQL;
|
package/client/pool.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DbPoolConstructor } from '@e-mc/types/lib/db';
|
|
2
|
+
|
|
3
|
+
import type { DbPoolCredential, MySQLDataSource } from '../types';
|
|
4
|
+
|
|
5
|
+
import type { Pool, PoolConnection } from 'mysql2/promise';
|
|
6
|
+
|
|
7
|
+
declare const MySQLPool: DbPoolConstructor<MySQLDataSource, Pool, PoolConnection, DbPoolCredential>;
|
|
8
|
+
|
|
9
|
+
export = MySQLPool;
|
package/client/pool.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const util_1 = require("@e-mc/db/util");
|
|
3
|
+
const types_1 = require("@e-mc/types");
|
|
4
|
+
const DbPool = require('@e-mc/db/pool');
|
|
5
|
+
const POOL_ACTIVE = new WeakSet();
|
|
6
|
+
class MySQLPool extends DbPool {
|
|
7
|
+
static CACHE_UNUSED = ['connectTimeout', 'queueLimit', 'waitForConnections', 'connectionLimit', 'maxIdle', 'idleTimeout', 'enableKeepAlive', 'keepAliveInitialDelay', 'Promise'];
|
|
8
|
+
static asString(credential) {
|
|
9
|
+
if ((credential.host || credential.socketPath) && credential.user) {
|
|
10
|
+
return JSON.stringify(this.removeUUIDKey(credential));
|
|
11
|
+
}
|
|
12
|
+
return super.asString(credential);
|
|
13
|
+
}
|
|
14
|
+
static sanitize(credential) {
|
|
15
|
+
if (!POOL_ACTIVE.has(credential) || credential.uuidKey) {
|
|
16
|
+
return credential;
|
|
17
|
+
}
|
|
18
|
+
const ssl = credential.ssl;
|
|
19
|
+
let result = super.sanitize(credential);
|
|
20
|
+
if ((0, types_1.isObject)(ssl)) {
|
|
21
|
+
if (result === credential) {
|
|
22
|
+
result = { ...credential };
|
|
23
|
+
}
|
|
24
|
+
const cert = ssl.cert;
|
|
25
|
+
if ((0, types_1.isString)(cert)) {
|
|
26
|
+
result.ssl = cert;
|
|
27
|
+
}
|
|
28
|
+
else if (Buffer.isBuffer(cert)) {
|
|
29
|
+
result.ssl = cert.toString('utf-8');
|
|
30
|
+
}
|
|
31
|
+
else if ((0, types_1.isArray)(cert)) {
|
|
32
|
+
result.ssl = cert.reduce((a, b) => a + (Buffer.isBuffer(b) ? b.toString('utf-8') : b), '');
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
result.ssl = "Unknown";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
async getConnection(credential) {
|
|
41
|
+
if (credential) {
|
|
42
|
+
POOL_ACTIVE.add(credential);
|
|
43
|
+
}
|
|
44
|
+
return this.client.getConnection();
|
|
45
|
+
}
|
|
46
|
+
async close() {
|
|
47
|
+
return this.client.end();
|
|
48
|
+
}
|
|
49
|
+
isEmpty() {
|
|
50
|
+
const pool = this.client.pool;
|
|
51
|
+
return this.closed || (0, util_1.checkEmpty)(pool._allConnections) && (0, util_1.checkEmpty)(pool._connectionQueue);
|
|
52
|
+
}
|
|
53
|
+
get closed() {
|
|
54
|
+
return !!this.client.pool._closed;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
module.exports = MySQLPool;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/mysql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "MySQL client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@e-mc/db": "^0.
|
|
25
|
-
"@e-mc/types": "^0.
|
|
26
|
-
"mysql2": "^3.
|
|
24
|
+
"@e-mc/db": "^0.10.0",
|
|
25
|
+
"@e-mc/types": "^0.10.0",
|
|
26
|
+
"mysql2": "^3.11.0"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import type { DbDataSource } from '@e-mc/types/lib/squared';
|
|
2
2
|
|
|
3
|
+
import type { IdentifierAction } from '@e-mc/types/lib/core';
|
|
3
4
|
import type { ExecuteAction, ServerAuth } from '@e-mc/types/lib/db';
|
|
4
5
|
|
|
5
|
-
import type { SecureContextOptions } from 'tls';
|
|
6
|
-
|
|
7
6
|
import type { PoolOptions, QueryOptions } from 'mysql2/promise';
|
|
8
7
|
|
|
9
8
|
export interface MySQLDataSource<T = unknown> extends DbDataSource<string | QueryOptions, unknown, unknown, MySQLCredential, string>, ExecuteAction<T> {
|
|
10
9
|
source: "mysql";
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
}
|
|
12
|
+
export type MySQLCredential = PoolOptions & ServerAuth;
|
|
13
|
+
export type DbPoolCredential = PoolOptions & IdentifierAction;
|