@pi-r/mysql 0.11.3 → 0.12.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 +39 -36
- package/client/pool.js +11 -9
- package/package.json +4 -7
- package/types/index.d.ts +2 -2
package/client/index.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const mysql = require("mysql2/promise");
|
|
10
|
-
const Db = require("@e-mc/db");
|
|
11
|
-
const types_1 = require("@e-mc/types");
|
|
12
|
-
const util_1 = require("@e-mc/db/util");
|
|
13
|
-
const DbPool = require("@pi-r/mysql/client/pool");
|
|
2
|
+
|
|
3
|
+
const main = require('mysql2');
|
|
4
|
+
const mysql = require('mysql2/promise');
|
|
5
|
+
const Db = require('@e-mc/db');
|
|
6
|
+
const { DB_TYPE, asFunction, errorMessage, isArray, isError, isErrorCode, isPlainObject, isString } = require('@e-mc/types');
|
|
7
|
+
const { parseConnectionString, parseServerAuth } = require('@e-mc/db/util');
|
|
8
|
+
const DbPool = require('@pi-r/mysql/client/pool');
|
|
14
9
|
const POOL_STATE = {};
|
|
15
10
|
function isResultSetHeader(value) {
|
|
16
11
|
const result = Array.isArray(value) ? value[0] : value;
|
|
@@ -24,11 +19,11 @@ function isResultSetHeader(value) {
|
|
|
24
19
|
return false;
|
|
25
20
|
}
|
|
26
21
|
function setAuthentication(credential) {
|
|
27
|
-
const auth =
|
|
22
|
+
const auth = parseServerAuth(credential);
|
|
28
23
|
credential.host ||= auth.hostname;
|
|
29
24
|
credential.user ||= auth.username;
|
|
30
25
|
credential.port ||= 3306;
|
|
31
|
-
if (
|
|
26
|
+
if (isPlainObject(credential.ssl)) {
|
|
32
27
|
this.readTLSConfig(credential.ssl);
|
|
33
28
|
}
|
|
34
29
|
}
|
|
@@ -43,15 +38,16 @@ function setCredential(item) {
|
|
|
43
38
|
}
|
|
44
39
|
let host;
|
|
45
40
|
if (!credential.uri) {
|
|
41
|
+
host = credential.host;
|
|
46
42
|
const errors = [];
|
|
47
|
-
if (!
|
|
43
|
+
if (!host && !credential.socketPath) {
|
|
48
44
|
errors.push('host');
|
|
49
45
|
}
|
|
50
46
|
if (!credential.user) {
|
|
51
47
|
errors.push('user');
|
|
52
48
|
}
|
|
53
49
|
if (errors.length > 0) {
|
|
54
|
-
throw
|
|
50
|
+
throw errorMessage("mysql", "Invalid credentials", errors.join(', '));
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
53
|
else {
|
|
@@ -64,7 +60,7 @@ function setCredential(item) {
|
|
|
64
60
|
if (host?.endsWith('.rds.amazonaws.com')) {
|
|
65
61
|
try {
|
|
66
62
|
const ssl = credential.ssl ||= {};
|
|
67
|
-
if (
|
|
63
|
+
if (isPlainObject(ssl) && !ssl.ca) {
|
|
68
64
|
const bundle = require('aws-ssl-profiles');
|
|
69
65
|
ssl.ca = bundle.ca;
|
|
70
66
|
}
|
|
@@ -81,8 +77,8 @@ function setCredential(item) {
|
|
|
81
77
|
return;
|
|
82
78
|
}
|
|
83
79
|
let username, password, pool;
|
|
84
|
-
if (
|
|
85
|
-
username = credential.user || credential.uri &&
|
|
80
|
+
if (isString(usePool)) {
|
|
81
|
+
username = credential.user || credential.uri && parseConnectionString(credential.uri)?.username;
|
|
86
82
|
if (username) {
|
|
87
83
|
[password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
|
|
88
84
|
if (pool) {
|
|
@@ -133,7 +129,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
133
129
|
return [];
|
|
134
130
|
}
|
|
135
131
|
let parallel, connectOnce, errorQuery, sessionKey, outCacheMiss;
|
|
136
|
-
if (
|
|
132
|
+
if (isPlainObject(options)) {
|
|
137
133
|
({ parallel, connectOnce, errorQuery, sessionKey, outCacheMiss } = options);
|
|
138
134
|
}
|
|
139
135
|
else {
|
|
@@ -153,6 +149,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
153
149
|
outResult ||= new Array(length);
|
|
154
150
|
}
|
|
155
151
|
const caching = this.hasCache("mysql", sessionKey);
|
|
152
|
+
const sortKeys = this.settingsOf("mysql", 'cache', 'sort_keys') === true;
|
|
156
153
|
const tasks = new Array(length);
|
|
157
154
|
const clients = [];
|
|
158
155
|
const pools = [];
|
|
@@ -176,15 +173,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
176
173
|
}
|
|
177
174
|
catch (err) {
|
|
178
175
|
let close;
|
|
179
|
-
if (
|
|
180
|
-
close = 1;
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
176
|
+
if (!isErrorCode(err, 'ER_ACCESS_DENIED_ERROR', 'ER_DBACCESS_DENIED_ERROR', 'ER_SPECIFIC_ACCESS_DENIED_ERROR', 'ER_ACCESS_DENIED_NO_PASSWORD_ERROR')) {
|
|
183
177
|
close = pool.closeable;
|
|
184
178
|
}
|
|
185
|
-
if (close) {
|
|
179
|
+
if (close !== false) {
|
|
186
180
|
await pool.detach(true);
|
|
187
|
-
if (close
|
|
181
|
+
if (!close) {
|
|
188
182
|
throw err;
|
|
189
183
|
}
|
|
190
184
|
}
|
|
@@ -209,7 +203,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
209
203
|
for (let i = 0, mysql2Client, mysql2Credential, statement; i < length; ++i) {
|
|
210
204
|
const item = batch[i];
|
|
211
205
|
const { source, params, ignoreCache } = item;
|
|
212
|
-
const streamRow = typeof item.streamRow === 'string' ? this.hasCoerce("mysql", 'options', mysql2Credential || item.credential) &&
|
|
206
|
+
const streamRow = typeof item.streamRow === 'string' ? this.hasCoerce("mysql", 'options', mysql2Credential || item.credential) && asFunction(item.streamRow) : item.streamRow;
|
|
213
207
|
let query = item.query, prepared = false;
|
|
214
208
|
if (typeof item.preparedStatement === 'boolean') {
|
|
215
209
|
if (item.preparedStatement) {
|
|
@@ -240,7 +234,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
240
234
|
else if (credential = mysqlCredential || onceCredential) {
|
|
241
235
|
error = null;
|
|
242
236
|
}
|
|
243
|
-
if (error !== null && !
|
|
237
|
+
if (error !== null && !isPlainObject(credential = item.credential) && (error = errorMessage(source, "Invalid credentials")) || !query && (error = errorMessage(source, "Missing database query"))) {
|
|
244
238
|
if (this.handleFail(error, item, { errorQuery })) {
|
|
245
239
|
if (!parallel) {
|
|
246
240
|
tasks.length = 0;
|
|
@@ -258,11 +252,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
258
252
|
}
|
|
259
253
|
item.transactionState = 1;
|
|
260
254
|
const cacheValue = ignoreCache === undefined ? sessionKey : Array.isArray(ignoreCache) ? { sessionKey, exclusiveOf: ignoreCache } : { sessionKey, renewCache: ignoreCache === 0 };
|
|
261
|
-
let queryString = '';
|
|
255
|
+
let queryString = '', cacheCredential;
|
|
262
256
|
if (caching && ignoreCache !== true && !prepared && !streamRow) {
|
|
263
257
|
queryString = Db.asString(query, true) + '_' + Db.asString(params, true);
|
|
258
|
+
cacheCredential = DbPool.sanitize(credential, sortKeys);
|
|
264
259
|
if (ignoreCache !== 1) {
|
|
265
|
-
const result = this.getQueryResult(source,
|
|
260
|
+
const result = this.getQueryResult(source, cacheCredential, queryString, cacheValue);
|
|
266
261
|
if (result) {
|
|
267
262
|
if (parallel) {
|
|
268
263
|
tasks[i] = Promise.resolve(result);
|
|
@@ -310,7 +305,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
310
305
|
if (err === false) {
|
|
311
306
|
return;
|
|
312
307
|
}
|
|
313
|
-
if (err
|
|
308
|
+
if (isError(err)) {
|
|
314
309
|
error = err;
|
|
315
310
|
return;
|
|
316
311
|
}
|
|
@@ -324,7 +319,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
324
319
|
}
|
|
325
320
|
else {
|
|
326
321
|
this.add(item, 4);
|
|
327
|
-
resolve(!error ? this.setQueryResult(source,
|
|
322
|
+
resolve(!error ? this.setQueryResult(source, cacheCredential, queryString, rows, cacheValue) : rows.length > 0 ? rows : null);
|
|
328
323
|
}
|
|
329
324
|
});
|
|
330
325
|
}
|
|
@@ -336,13 +331,13 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
336
331
|
commandType = this.commandType.SELECT;
|
|
337
332
|
const [rows] = await (prepared && connectOnce && !parallel ? client.execute(query, params) : client.query(query, params));
|
|
338
333
|
this.add(item, 4);
|
|
339
|
-
if (
|
|
334
|
+
if (isArray(rows)) {
|
|
340
335
|
const [row1, row2] = rows;
|
|
341
336
|
if (rows.length === 2 && Array.isArray(row1) && !Array.isArray(row2) && isResultSetHeader(row2)) {
|
|
342
337
|
resolve(row1);
|
|
343
338
|
}
|
|
344
339
|
else {
|
|
345
|
-
resolve(!isResultSetHeader(row1) ? this.setQueryResult(source,
|
|
340
|
+
resolve(!isResultSetHeader(row1) ? this.setQueryResult(source, cacheCredential, queryString, rows, cacheValue) : null);
|
|
346
341
|
}
|
|
347
342
|
}
|
|
348
343
|
else {
|
|
@@ -388,5 +383,13 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
388
383
|
async function checkTimeout(value, limit = 0) {
|
|
389
384
|
return DbPool.checkTimeout(POOL_STATE, value, limit);
|
|
390
385
|
}
|
|
391
|
-
|
|
392
|
-
|
|
386
|
+
const DB_SOURCE_CLIENT = true;
|
|
387
|
+
const DB_SOURCE_TYPE = DB_TYPE.SQL;
|
|
388
|
+
|
|
389
|
+
exports.DB_SOURCE_CLIENT = DB_SOURCE_CLIENT;
|
|
390
|
+
exports.DB_SOURCE_TYPE = DB_SOURCE_TYPE;
|
|
391
|
+
exports.checkTimeout = checkTimeout;
|
|
392
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
393
|
+
exports.executeQuery = executeQuery;
|
|
394
|
+
exports.setAuthentication = setAuthentication;
|
|
395
|
+
exports.setCredential = setCredential;
|
package/client/pool.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
const
|
|
2
|
+
|
|
3
|
+
const { isArray, isObject, isString } = require('@e-mc/types');
|
|
4
|
+
const { checkEmpty } = require('@e-mc/db/util');
|
|
4
5
|
const DbPool = require('@e-mc/db/pool');
|
|
5
6
|
const POOL_ACTIVE = new WeakSet();
|
|
6
7
|
class MySQLPool extends DbPool {
|
|
7
|
-
static CACHE_UNUSED = ['connectTimeout', 'queueLimit', 'waitForConnections', 'connectionLimit', 'maxIdle', 'idleTimeout', 'enableKeepAlive', 'keepAliveInitialDelay', 'Promise', 'gracefulEnd'];
|
|
8
|
+
static CACHE_UNUSED = ['connectTimeout', 'queueLimit', 'resetOnRelease', 'waitForConnections', 'connectionLimit', 'maxIdle', 'idleTimeout', 'enableKeepAlive', 'keepAliveInitialDelay', 'Promise', 'gracefulEnd'];
|
|
8
9
|
static CACHE_IGNORE = ['authPlugins', 'authSwitchHandler', 'stream', 'infileStreamFactory'];
|
|
9
10
|
static asString(credential) {
|
|
10
11
|
if ((credential.host || credential.socketPath) && credential.user) {
|
|
@@ -12,7 +13,7 @@ class MySQLPool extends DbPool {
|
|
|
12
13
|
}
|
|
13
14
|
return super.asString(credential);
|
|
14
15
|
}
|
|
15
|
-
static sanitize(credential) {
|
|
16
|
+
static sanitize(credential, sort) {
|
|
16
17
|
if (!this.canCache(credential)) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
@@ -20,19 +21,19 @@ class MySQLPool extends DbPool {
|
|
|
20
21
|
return credential;
|
|
21
22
|
}
|
|
22
23
|
const ssl = credential.ssl;
|
|
23
|
-
let result = super.sanitize(credential);
|
|
24
|
-
if (
|
|
24
|
+
let result = super.sanitize(credential, sort);
|
|
25
|
+
if (isObject(ssl)) {
|
|
25
26
|
if (result === credential) {
|
|
26
27
|
result = { ...credential };
|
|
27
28
|
}
|
|
28
29
|
const cert = ssl.cert;
|
|
29
|
-
if (
|
|
30
|
+
if (isString(cert)) {
|
|
30
31
|
result.ssl = cert;
|
|
31
32
|
}
|
|
32
33
|
else if (Buffer.isBuffer(cert)) {
|
|
33
34
|
result.ssl = cert.toString('utf8');
|
|
34
35
|
}
|
|
35
|
-
else if (
|
|
36
|
+
else if (isArray(cert)) {
|
|
36
37
|
result.ssl = cert.reduce((a, b) => a + (Buffer.isBuffer(b) ? b.toString('utf8') : b), '');
|
|
37
38
|
}
|
|
38
39
|
else {
|
|
@@ -52,10 +53,11 @@ class MySQLPool extends DbPool {
|
|
|
52
53
|
}
|
|
53
54
|
isEmpty() {
|
|
54
55
|
const pool = this.client.pool;
|
|
55
|
-
return this.closed ||
|
|
56
|
+
return this.closed || checkEmpty(pool._allConnections) && checkEmpty(pool._connectionQueue);
|
|
56
57
|
}
|
|
57
58
|
get closed() {
|
|
58
59
|
return !!this.client.pool._closed;
|
|
59
60
|
}
|
|
60
61
|
}
|
|
62
|
+
|
|
61
63
|
module.exports = MySQLPool;
|
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/mysql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "MySQL client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
7
|
-
"publishConfig": {
|
|
8
|
-
"access": "public"
|
|
9
|
-
},
|
|
10
7
|
"repository": {
|
|
11
8
|
"type": "git",
|
|
12
9
|
"url": "git+https://github.com/anpham6/pi-r.git",
|
|
@@ -20,8 +17,8 @@
|
|
|
20
17
|
"license": "MIT",
|
|
21
18
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
19
|
"dependencies": {
|
|
23
|
-
"@e-mc/db": "^0.
|
|
24
|
-
"@e-mc/types": "^0.
|
|
25
|
-
"mysql2": "^3.22.
|
|
20
|
+
"@e-mc/db": "^0.14.1",
|
|
21
|
+
"@e-mc/types": "^0.14.1",
|
|
22
|
+
"mysql2": "^3.22.3"
|
|
26
23
|
}
|
|
27
24
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import type { DbDataSource } from '@e-mc/types/lib/squared';
|
|
|
3
3
|
import type { IdentifierAction } from '@e-mc/types/lib/core';
|
|
4
4
|
import type { ExecuteAction, ServerAuth } from '@e-mc/types/lib/db';
|
|
5
5
|
|
|
6
|
-
import type { PoolOptions, QueryOptions } from 'mysql2/promise';
|
|
6
|
+
import type { ExecuteValues, PoolOptions, QueryOptions, QueryValues } from 'mysql2/promise';
|
|
7
7
|
|
|
8
|
-
export interface MySQLDataSource<T =
|
|
8
|
+
export interface MySQLDataSource<T = ExecuteValues | QueryValues> extends DbDataSource<string | QueryOptions, unknown, unknown, MySQLCredential, string>, ExecuteAction<T> {
|
|
9
9
|
source: "mysql";
|
|
10
10
|
preparedStatement?: boolean;
|
|
11
11
|
}
|