@zz1996/dbhub-dameng 0.1.7 → 1.2.5-dameng.621
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 +126 -137
- package/dbhub.dameng.toml.example +4 -11
- package/dist/{chunk-SQA2ISDE.js → chunk-2JL4KCP5.js} +21 -119
- package/dist/chunk-3RJRH3CN.js +121 -0
- package/dist/chunk-4276LPPU.js +179 -0
- package/dist/chunk-FU2ZJE4E.js +16 -0
- package/dist/chunk-HDPZAIDL.js +155 -0
- package/dist/{chunk-2A2QF3CS.js → chunk-HGU7ILEZ.js} +215 -68
- package/dist/{chunk-IPK7BYBL.js → chunk-JFWX35TB.js} +0 -1
- package/dist/chunk-O3PEWKBB.js +302 -0
- package/dist/dameng-NKF7NZKE.js +250 -0
- package/dist/index.js +461 -251
- package/dist/{mariadb-7F72IRB4.js → mariadb-MMC6WMEG.js} +86 -53
- package/dist/{mysql-A43SL7UM.js → mysql-TESH7KKV.js} +126 -50
- package/dist/{postgres-VFNLBWMF.js → postgres-C24SBQ4I.js} +154 -36
- package/dist/public/assets/index-BJ-1UrcV.css +1 -0
- package/dist/public/assets/index-BdBaFSHd.js +148 -0
- package/dist/public/assets/postgres-BpcazhJg.svg +22 -0
- package/dist/public/assets/sqlserver-ByfFYYpV.svg +11 -0
- package/dist/public/favicon.svg +57 -0
- package/dist/public/index.html +14 -0
- package/dist/public/logo-full-light.svg +58 -0
- package/dist/{registry-XSX2VZTD.js → registry-WVSFVS35.js} +3 -2
- package/dist/{sqlite-IOUAYHGE.js → sqlite-7BNGDMBZ.js} +57 -42
- package/dist/sqlserver-KZPPK67Q.js +1042 -0
- package/package.json +22 -65
- package/dist/chunk-RTB262PR.js +0 -60
- package/dist/chunk-ZNQTMARG.js +0 -127
- package/dist/dameng-5KYI5JBK.js +0 -898
- package/dist/sqlserver-OE4SFH4B.js +0 -587
- package/docs/README.md +0 -14
- package/docs/dameng-connector-plan.md +0 -143
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
MissingDatabaseError,
|
|
3
|
+
getMySQLFamilyHealthCheck,
|
|
4
|
+
isTiDBVersion,
|
|
5
|
+
parseQueryResultSets,
|
|
6
|
+
requireDatabaseInDSN,
|
|
7
|
+
withReadOnlyTransaction
|
|
8
|
+
} from "./chunk-4276LPPU.js";
|
|
9
|
+
import "./chunk-FU2ZJE4E.js";
|
|
5
10
|
import {
|
|
6
11
|
quoteIdentifier
|
|
7
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JFWX35TB.js";
|
|
8
13
|
import {
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
14
|
+
obfuscateDSNPassword
|
|
15
|
+
} from "./chunk-3RJRH3CN.js";
|
|
16
|
+
import {
|
|
17
|
+
SQLRowLimiter,
|
|
18
|
+
closeQuietly
|
|
19
|
+
} from "./chunk-O3PEWKBB.js";
|
|
20
|
+
import "./chunk-HDPZAIDL.js";
|
|
11
21
|
import {
|
|
12
22
|
ConnectorRegistry,
|
|
13
23
|
SafeURL,
|
|
14
|
-
obfuscateDSNPassword,
|
|
15
24
|
splitSQLStatements
|
|
16
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2JL4KCP5.js";
|
|
17
26
|
|
|
18
27
|
// src/connectors/mariadb/index.ts
|
|
19
28
|
import * as mariadb from "mariadb";
|
|
@@ -32,11 +41,12 @@ Expected: ${expectedFormat}`
|
|
|
32
41
|
}
|
|
33
42
|
try {
|
|
34
43
|
const url = new SafeURL(dsn);
|
|
44
|
+
const database = url.pathname ? url.pathname.substring(1) : "";
|
|
45
|
+
requireDatabaseInDSN(database, dsn, "MariaDB");
|
|
35
46
|
const connectionConfig = {
|
|
36
47
|
host: url.hostname,
|
|
37
48
|
port: url.port ? parseInt(url.port) : 3306,
|
|
38
|
-
database
|
|
39
|
-
// Remove leading '/' if exists
|
|
49
|
+
database,
|
|
40
50
|
user: url.username,
|
|
41
51
|
password: url.password,
|
|
42
52
|
multipleStatements: true,
|
|
@@ -50,7 +60,14 @@ Expected: ${expectedFormat}`
|
|
|
50
60
|
// Controls how the driver interprets DATETIME values ("Z", "local", or "±HH:MM").
|
|
51
61
|
...config?.timezone !== void 0 && {
|
|
52
62
|
timezone: config.timezone
|
|
53
|
-
}
|
|
63
|
+
},
|
|
64
|
+
// Connection character set (e.g. "utf8mb4") / collation (e.g.
|
|
65
|
+
// "utf8mb4_general_ci"). The mariadb driver exposes both as distinct
|
|
66
|
+
// options, but a configured collation is authoritative (it implies its
|
|
67
|
+
// character set) and the driver ignores `collation` when `charset` is also
|
|
68
|
+
// passed. So forward the collation when present, otherwise the charset
|
|
69
|
+
// (which uses that character set's default collation).
|
|
70
|
+
...config?.collation !== void 0 ? { collation: config.collation } : config?.charset !== void 0 ? { charset: config.charset } : {}
|
|
54
71
|
};
|
|
55
72
|
url.forEachSearchParam((value, key) => {
|
|
56
73
|
if (key === "sslmode") {
|
|
@@ -70,6 +87,9 @@ Expected: ${expectedFormat}`
|
|
|
70
87
|
}
|
|
71
88
|
return connectionConfig;
|
|
72
89
|
} catch (error) {
|
|
90
|
+
if (error instanceof MissingDatabaseError) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
73
93
|
throw new Error(
|
|
74
94
|
`Failed to parse MariaDB DSN: ${error instanceof Error ? error.message : String(error)}`
|
|
75
95
|
);
|
|
@@ -94,6 +114,9 @@ var MariaDBConnector = class _MariaDBConnector {
|
|
|
94
114
|
this.pool = null;
|
|
95
115
|
// Source ID is set by ConnectorManager after cloning
|
|
96
116
|
this.sourceId = "default";
|
|
117
|
+
// TiDB speaks the MySQL protocol but rejects `START TRANSACTION READ ONLY`
|
|
118
|
+
// unless tidb_enable_noop_functions is on. Detected once at connect time.
|
|
119
|
+
this.supportsReadOnlyTransaction = true;
|
|
97
120
|
}
|
|
98
121
|
getId() {
|
|
99
122
|
return this.sourceId;
|
|
@@ -105,8 +128,20 @@ var MariaDBConnector = class _MariaDBConnector {
|
|
|
105
128
|
try {
|
|
106
129
|
const connectionConfig = await this.dsnParser.parse(dsn, config);
|
|
107
130
|
this.pool = mariadb.createPool(connectionConfig);
|
|
108
|
-
|
|
131
|
+
this.pool.on("error", (err) => {
|
|
132
|
+
console.error(
|
|
133
|
+
`MariaDB pool (source "${this.sourceId}"): background connection error, pool will retry:`,
|
|
134
|
+
err.message
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
const rows = await this.pool.query("SELECT VERSION() AS version");
|
|
138
|
+
this.supportsReadOnlyTransaction = !isTiDBVersion(rows?.[0]?.version);
|
|
109
139
|
} catch (err) {
|
|
140
|
+
if (this.pool) {
|
|
141
|
+
const pool = this.pool;
|
|
142
|
+
this.pool = null;
|
|
143
|
+
await closeQuietly(() => pool.end());
|
|
144
|
+
}
|
|
110
145
|
console.error("Failed to connect to MariaDB database:", err);
|
|
111
146
|
throw err;
|
|
112
147
|
}
|
|
@@ -313,6 +348,13 @@ var MariaDBConnector = class _MariaDBConnector {
|
|
|
313
348
|
return null;
|
|
314
349
|
}
|
|
315
350
|
}
|
|
351
|
+
async getHealthCheck() {
|
|
352
|
+
if (!this.pool) {
|
|
353
|
+
throw new Error("Not connected to database");
|
|
354
|
+
}
|
|
355
|
+
const pool = this.pool;
|
|
356
|
+
return getMySQLFamilyHealthCheck((sql) => pool.query(sql));
|
|
357
|
+
}
|
|
316
358
|
async getStoredProcedures(schema, routineType) {
|
|
317
359
|
if (!this.pool) {
|
|
318
360
|
throw new Error("Not connected to database");
|
|
@@ -466,48 +508,39 @@ var MariaDBConnector = class _MariaDBConnector {
|
|
|
466
508
|
}
|
|
467
509
|
const conn = await this.pool.getConnection();
|
|
468
510
|
try {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
501
|
-
return { rows, rowCount };
|
|
502
|
-
} catch (error) {
|
|
503
|
-
if (options.readonly) {
|
|
504
|
-
try {
|
|
505
|
-
await conn.query("ROLLBACK");
|
|
506
|
-
} catch {
|
|
511
|
+
return await withReadOnlyTransaction(
|
|
512
|
+
conn,
|
|
513
|
+
options.readonly,
|
|
514
|
+
this.supportsReadOnlyTransaction,
|
|
515
|
+
async () => {
|
|
516
|
+
const statements = splitSQLStatements(sql, "mariadb");
|
|
517
|
+
let processedSQL = sql;
|
|
518
|
+
let probes = [];
|
|
519
|
+
if (options.maxRows) {
|
|
520
|
+
const rewrites = statements.map(
|
|
521
|
+
(statement) => SQLRowLimiter.applyMaxRowsWithTruncationProbe(statement, options.maxRows, "mariadb")
|
|
522
|
+
);
|
|
523
|
+
probes = rewrites.map((rewrite) => rewrite.probeApplied);
|
|
524
|
+
processedSQL = rewrites.map((rewrite) => rewrite.sql).join("; ");
|
|
525
|
+
if (sql.trim().endsWith(";")) {
|
|
526
|
+
processedSQL += ";";
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
let results;
|
|
530
|
+
if (parameters && parameters.length > 0) {
|
|
531
|
+
results = await conn.query(processedSQL, parameters);
|
|
532
|
+
} else {
|
|
533
|
+
results = await conn.query(processedSQL);
|
|
534
|
+
}
|
|
535
|
+
const resultSets = parseQueryResultSets(results, statements);
|
|
536
|
+
if (resultSets.length === probes.length) {
|
|
537
|
+
resultSets.forEach(
|
|
538
|
+
(set, index) => SQLRowLimiter.flagTruncation(set, options.maxRows, probes[index])
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
return { resultSets };
|
|
507
542
|
}
|
|
508
|
-
|
|
509
|
-
console.error("Error executing query:", error);
|
|
510
|
-
throw error;
|
|
543
|
+
);
|
|
511
544
|
} finally {
|
|
512
545
|
conn.release();
|
|
513
546
|
}
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
MissingDatabaseError,
|
|
3
|
+
getMySQLFamilyHealthCheck,
|
|
4
|
+
isClientSideTimeout,
|
|
5
|
+
isTiDBVersion,
|
|
6
|
+
parseQueryResultSets,
|
|
7
|
+
requireDatabaseInDSN,
|
|
8
|
+
withReadOnlyTransaction
|
|
9
|
+
} from "./chunk-4276LPPU.js";
|
|
10
|
+
import "./chunk-FU2ZJE4E.js";
|
|
5
11
|
import {
|
|
6
12
|
quoteIdentifier
|
|
7
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-JFWX35TB.js";
|
|
8
14
|
import {
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
15
|
+
obfuscateDSNPassword
|
|
16
|
+
} from "./chunk-3RJRH3CN.js";
|
|
17
|
+
import {
|
|
18
|
+
SQLRowLimiter,
|
|
19
|
+
closeQuietly
|
|
20
|
+
} from "./chunk-O3PEWKBB.js";
|
|
21
|
+
import "./chunk-HDPZAIDL.js";
|
|
11
22
|
import {
|
|
12
23
|
ConnectorRegistry,
|
|
13
24
|
SafeURL,
|
|
14
|
-
obfuscateDSNPassword,
|
|
15
25
|
splitSQLStatements
|
|
16
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-2JL4KCP5.js";
|
|
17
27
|
|
|
18
28
|
// src/connectors/mysql/index.ts
|
|
19
29
|
import mysql from "mysql2/promise";
|
|
@@ -21,6 +31,8 @@ var MySQLDSNParser = class {
|
|
|
21
31
|
async parse(dsn, config) {
|
|
22
32
|
const connectionTimeoutSeconds = config?.connectionTimeoutSeconds;
|
|
23
33
|
const timezone = config?.timezone;
|
|
34
|
+
const charset = config?.charset;
|
|
35
|
+
const collation = config?.collation;
|
|
24
36
|
if (!this.isValidDSN(dsn)) {
|
|
25
37
|
const obfuscatedDSN = obfuscateDSNPassword(dsn);
|
|
26
38
|
const expectedFormat = this.getSampleDSN();
|
|
@@ -32,11 +44,12 @@ Expected: ${expectedFormat}`
|
|
|
32
44
|
}
|
|
33
45
|
try {
|
|
34
46
|
const url = new SafeURL(dsn);
|
|
47
|
+
const database = url.pathname ? url.pathname.substring(1) : "";
|
|
48
|
+
requireDatabaseInDSN(database, dsn, "MySQL");
|
|
35
49
|
const config2 = {
|
|
36
50
|
host: url.hostname,
|
|
37
51
|
port: url.port ? parseInt(url.port) : 3306,
|
|
38
|
-
database
|
|
39
|
-
// Remove leading '/' if exists
|
|
52
|
+
database,
|
|
40
53
|
user: url.username,
|
|
41
54
|
password: url.password,
|
|
42
55
|
multipleStatements: true,
|
|
@@ -61,6 +74,10 @@ Expected: ${expectedFormat}`
|
|
|
61
74
|
if (timezone !== void 0) {
|
|
62
75
|
config2.timezone = timezone;
|
|
63
76
|
}
|
|
77
|
+
const charsetOrCollation = collation ?? charset;
|
|
78
|
+
if (charsetOrCollation !== void 0) {
|
|
79
|
+
config2.charset = charsetOrCollation;
|
|
80
|
+
}
|
|
64
81
|
if (url.password && url.password.includes("X-Amz-Credential")) {
|
|
65
82
|
config2.authPlugins = {
|
|
66
83
|
mysql_clear_password: () => () => {
|
|
@@ -73,6 +90,9 @@ Expected: ${expectedFormat}`
|
|
|
73
90
|
}
|
|
74
91
|
return config2;
|
|
75
92
|
} catch (error) {
|
|
93
|
+
if (error instanceof MissingDatabaseError) {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
76
96
|
throw new Error(
|
|
77
97
|
`Failed to parse MySQL DSN: ${error instanceof Error ? error.message : String(error)}`
|
|
78
98
|
);
|
|
@@ -89,7 +109,7 @@ Expected: ${expectedFormat}`
|
|
|
89
109
|
}
|
|
90
110
|
}
|
|
91
111
|
};
|
|
92
|
-
var
|
|
112
|
+
var _MySQLConnector = class _MySQLConnector {
|
|
93
113
|
constructor() {
|
|
94
114
|
this.id = "mysql";
|
|
95
115
|
this.name = "MySQL";
|
|
@@ -97,6 +117,9 @@ var MySQLConnector = class _MySQLConnector {
|
|
|
97
117
|
this.pool = null;
|
|
98
118
|
// Source ID is set by ConnectorManager after cloning
|
|
99
119
|
this.sourceId = "default";
|
|
120
|
+
// TiDB speaks the MySQL protocol but rejects `START TRANSACTION READ ONLY`
|
|
121
|
+
// unless tidb_enable_noop_functions is on. Detected once at connect time.
|
|
122
|
+
this.supportsReadOnlyTransaction = true;
|
|
100
123
|
}
|
|
101
124
|
getId() {
|
|
102
125
|
return this.sourceId;
|
|
@@ -111,8 +134,14 @@ var MySQLConnector = class _MySQLConnector {
|
|
|
111
134
|
if (config?.queryTimeoutSeconds !== void 0) {
|
|
112
135
|
this.queryTimeoutMs = config.queryTimeoutSeconds * 1e3;
|
|
113
136
|
}
|
|
114
|
-
const [rows] = await this.pool.query("SELECT
|
|
137
|
+
const [rows] = await this.pool.query("SELECT VERSION() AS version");
|
|
138
|
+
this.supportsReadOnlyTransaction = !isTiDBVersion(rows[0]?.version);
|
|
115
139
|
} catch (err) {
|
|
140
|
+
if (this.pool) {
|
|
141
|
+
const pool = this.pool;
|
|
142
|
+
this.pool = null;
|
|
143
|
+
await closeQuietly(() => pool.end());
|
|
144
|
+
}
|
|
116
145
|
console.error("Failed to connect to MySQL database:", err);
|
|
117
146
|
throw err;
|
|
118
147
|
}
|
|
@@ -319,6 +348,16 @@ var MySQLConnector = class _MySQLConnector {
|
|
|
319
348
|
return null;
|
|
320
349
|
}
|
|
321
350
|
}
|
|
351
|
+
async getHealthCheck() {
|
|
352
|
+
if (!this.pool) {
|
|
353
|
+
throw new Error("Not connected to database");
|
|
354
|
+
}
|
|
355
|
+
const pool = this.pool;
|
|
356
|
+
return getMySQLFamilyHealthCheck(async (sql) => {
|
|
357
|
+
const [rows] = await pool.query(sql);
|
|
358
|
+
return rows;
|
|
359
|
+
});
|
|
360
|
+
}
|
|
322
361
|
async getStoredProcedures(schema, routineType) {
|
|
323
362
|
if (!this.pool) {
|
|
324
363
|
throw new Error("Not connected to database");
|
|
@@ -471,55 +510,92 @@ var MySQLConnector = class _MySQLConnector {
|
|
|
471
510
|
throw new Error("Not connected to database");
|
|
472
511
|
}
|
|
473
512
|
const conn = await this.pool.getConnection();
|
|
513
|
+
const threadId = conn.threadId;
|
|
514
|
+
let isConnectionPoisoned = false;
|
|
474
515
|
try {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
516
|
+
return await withReadOnlyTransaction(
|
|
517
|
+
conn,
|
|
518
|
+
options.readonly,
|
|
519
|
+
this.supportsReadOnlyTransaction,
|
|
520
|
+
async () => {
|
|
521
|
+
const statements = splitSQLStatements(sql, "mysql");
|
|
522
|
+
let processedSQL = sql;
|
|
523
|
+
let probes = [];
|
|
524
|
+
if (options.maxRows) {
|
|
525
|
+
const rewrites = statements.map(
|
|
526
|
+
(statement) => SQLRowLimiter.applyMaxRowsWithTruncationProbe(statement, options.maxRows, "mysql")
|
|
527
|
+
);
|
|
528
|
+
probes = rewrites.map((rewrite) => rewrite.probeApplied);
|
|
529
|
+
processedSQL = rewrites.map((rewrite) => rewrite.sql).join("; ");
|
|
530
|
+
if (sql.trim().endsWith(";")) {
|
|
531
|
+
processedSQL += ";";
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
let results;
|
|
535
|
+
if (parameters && parameters.length > 0) {
|
|
536
|
+
results = await conn.query({ sql: processedSQL, timeout: this.queryTimeoutMs }, parameters);
|
|
537
|
+
} else {
|
|
538
|
+
results = await conn.query({ sql: processedSQL, timeout: this.queryTimeoutMs });
|
|
539
|
+
}
|
|
540
|
+
const [firstResult] = results;
|
|
541
|
+
const resultSets = parseQueryResultSets(firstResult, statements);
|
|
542
|
+
if (resultSets.length === probes.length) {
|
|
543
|
+
resultSets.forEach(
|
|
544
|
+
(set, index) => SQLRowLimiter.flagTruncation(set, options.maxRows, probes[index])
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
return { resultSets };
|
|
487
548
|
}
|
|
549
|
+
);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (isClientSideTimeout(error)) {
|
|
552
|
+
isConnectionPoisoned = true;
|
|
553
|
+
await this.killQuery(threadId);
|
|
488
554
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
} catch (error) {
|
|
494
|
-
console.error(`[MySQL executeSQL] ERROR: ${error.message}`);
|
|
495
|
-
console.error(`[MySQL executeSQL] SQL: ${processedSQL}`);
|
|
496
|
-
console.error(`[MySQL executeSQL] Parameters: ${JSON.stringify(parameters)}`);
|
|
497
|
-
throw error;
|
|
498
|
-
}
|
|
555
|
+
throw error;
|
|
556
|
+
} finally {
|
|
557
|
+
if (isConnectionPoisoned) {
|
|
558
|
+
conn.destroy();
|
|
499
559
|
} else {
|
|
500
|
-
|
|
560
|
+
conn.release();
|
|
501
561
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Best-effort server-side kill for a query abandoned by mysql2's client-side
|
|
566
|
+
* timeout. Uses a separate connection: the original connection's command
|
|
567
|
+
* queue is stuck behind the abandoned statement (see isClientSideTimeout)
|
|
568
|
+
* and cannot itself be used to send KILL QUERY.
|
|
569
|
+
*
|
|
570
|
+
* Bounded by its own short timeout, independent of the user's (possibly
|
|
571
|
+
* long or unset) query_timeout — KILL QUERY is metadata-only and should
|
|
572
|
+
* return almost immediately on a healthy server, so cleanup must not stall
|
|
573
|
+
* indefinitely if it doesn't.
|
|
574
|
+
*/
|
|
575
|
+
async killQuery(threadId) {
|
|
576
|
+
if (!this.pool) return;
|
|
577
|
+
let killer;
|
|
578
|
+
let killerPoisoned = false;
|
|
579
|
+
try {
|
|
580
|
+
killer = await this.pool.getConnection();
|
|
581
|
+
await killer.query({ sql: `KILL QUERY ${threadId}`, timeout: _MySQLConnector.KILL_QUERY_TIMEOUT_MS });
|
|
509
582
|
} catch (error) {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
583
|
+
killerPoisoned = isClientSideTimeout(error);
|
|
584
|
+
} finally {
|
|
585
|
+
if (killer) {
|
|
586
|
+
if (killerPoisoned) {
|
|
587
|
+
killer.destroy();
|
|
588
|
+
} else {
|
|
589
|
+
killer.release();
|
|
514
590
|
}
|
|
515
591
|
}
|
|
516
|
-
console.error("Error executing query:", error);
|
|
517
|
-
throw error;
|
|
518
|
-
} finally {
|
|
519
|
-
conn.release();
|
|
520
592
|
}
|
|
521
593
|
}
|
|
522
594
|
};
|
|
595
|
+
// Bounds the KILL QUERY cleanup call issued after a client-side query
|
|
596
|
+
// timeout; see killQuery.
|
|
597
|
+
_MySQLConnector.KILL_QUERY_TIMEOUT_MS = 5e3;
|
|
598
|
+
var MySQLConnector = _MySQLConnector;
|
|
523
599
|
var mysqlConnector = new MySQLConnector();
|
|
524
600
|
ConnectorRegistry.register(mysqlConnector);
|
|
525
601
|
export {
|