@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,21 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
toNullableNumber
|
|
3
|
+
} from "./chunk-FU2ZJE4E.js";
|
|
1
4
|
import {
|
|
2
5
|
quoteIdentifier
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JFWX35TB.js";
|
|
7
|
+
import {
|
|
8
|
+
obfuscateDSNPassword
|
|
9
|
+
} from "./chunk-3RJRH3CN.js";
|
|
4
10
|
import {
|
|
5
|
-
SQLRowLimiter
|
|
6
|
-
|
|
11
|
+
SQLRowLimiter,
|
|
12
|
+
closeQuietly
|
|
13
|
+
} from "./chunk-O3PEWKBB.js";
|
|
14
|
+
import "./chunk-HDPZAIDL.js";
|
|
7
15
|
import {
|
|
8
16
|
ConnectorRegistry,
|
|
9
17
|
SafeURL,
|
|
10
|
-
obfuscateDSNPassword,
|
|
11
18
|
splitSQLStatements
|
|
12
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-2JL4KCP5.js";
|
|
13
20
|
|
|
14
21
|
// src/connectors/postgres/index.ts
|
|
15
22
|
import fs from "fs";
|
|
16
23
|
import os from "os";
|
|
17
24
|
import path from "path";
|
|
18
|
-
import
|
|
25
|
+
import pg2 from "pg";
|
|
19
26
|
|
|
20
27
|
// src/connectors/postgres/failed-to-read-certificate.ts
|
|
21
28
|
var FailedToReadCertificate = class extends Error {
|
|
@@ -25,12 +32,40 @@ var FailedToReadCertificate = class extends Error {
|
|
|
25
32
|
}
|
|
26
33
|
};
|
|
27
34
|
|
|
35
|
+
// src/connectors/postgres/type-parsers.ts
|
|
36
|
+
import pg from "pg";
|
|
37
|
+
var VERBATIM_DATE_TIME_OIDS = /* @__PURE__ */ new Set([
|
|
38
|
+
1082,
|
|
39
|
+
// date
|
|
40
|
+
1114,
|
|
41
|
+
// timestamp without time zone
|
|
42
|
+
1184,
|
|
43
|
+
// timestamp with time zone
|
|
44
|
+
1182,
|
|
45
|
+
// date[]
|
|
46
|
+
1115,
|
|
47
|
+
// timestamp[]
|
|
48
|
+
1185
|
|
49
|
+
// timestamptz[]
|
|
50
|
+
]);
|
|
51
|
+
var passthrough = (value) => value;
|
|
52
|
+
var postgresTypeParsers = {
|
|
53
|
+
getTypeParser(oid, format) {
|
|
54
|
+
if (VERBATIM_DATE_TIME_OIDS.has(oid) && (format === void 0 || format === "text")) {
|
|
55
|
+
return passthrough;
|
|
56
|
+
}
|
|
57
|
+
return pg.types.getTypeParser(oid, format);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
28
61
|
// src/connectors/postgres/index.ts
|
|
29
|
-
var { Pool } =
|
|
62
|
+
var { Pool } = pg2;
|
|
63
|
+
var POSTGRES_CLIENT_QUERY_TIMEOUT_GRACE_MS = 5e3;
|
|
30
64
|
var PostgresDSNParser = class {
|
|
31
65
|
async parse(dsn, config) {
|
|
32
66
|
const connectionTimeoutSeconds = config?.connectionTimeoutSeconds;
|
|
33
67
|
const queryTimeoutSeconds = config?.queryTimeoutSeconds;
|
|
68
|
+
const poolMaxConnections = config?.poolMaxConnections;
|
|
34
69
|
if (!this.isValidDSN(dsn)) {
|
|
35
70
|
const obfuscatedDSN = obfuscateDSNPassword(dsn);
|
|
36
71
|
const expectedFormat = this.getSampleDSN();
|
|
@@ -86,7 +121,12 @@ Expected: ${expectedFormat}`
|
|
|
86
121
|
poolConfig.connectionTimeoutMillis = connectionTimeoutSeconds * 1e3;
|
|
87
122
|
}
|
|
88
123
|
if (queryTimeoutSeconds !== void 0) {
|
|
89
|
-
|
|
124
|
+
const queryTimeoutMs = queryTimeoutSeconds * 1e3;
|
|
125
|
+
poolConfig.statement_timeout = queryTimeoutMs;
|
|
126
|
+
poolConfig.query_timeout = queryTimeoutMs + POSTGRES_CLIENT_QUERY_TIMEOUT_GRACE_MS;
|
|
127
|
+
}
|
|
128
|
+
if (poolMaxConnections !== void 0) {
|
|
129
|
+
poolConfig.max = poolMaxConnections;
|
|
90
130
|
}
|
|
91
131
|
return poolConfig;
|
|
92
132
|
} catch (error) {
|
|
@@ -132,6 +172,7 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
132
172
|
this.defaultSchema = "public";
|
|
133
173
|
try {
|
|
134
174
|
const poolConfig = await this.dsnParser.parse(dsn, config);
|
|
175
|
+
poolConfig.types = postgresTypeParsers;
|
|
135
176
|
if (config?.readonly) {
|
|
136
177
|
poolConfig.options = (poolConfig.options || "") + " -c default_transaction_read_only=on";
|
|
137
178
|
}
|
|
@@ -145,9 +186,20 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
145
186
|
}
|
|
146
187
|
}
|
|
147
188
|
this.pool = new Pool(poolConfig);
|
|
189
|
+
this.pool.on("error", (err) => {
|
|
190
|
+
console.error(
|
|
191
|
+
`PostgreSQL pool (source "${this.sourceId}"): idle connection dropped, will reconnect on next query:`,
|
|
192
|
+
err.message
|
|
193
|
+
);
|
|
194
|
+
});
|
|
148
195
|
const client = await this.pool.connect();
|
|
149
196
|
client.release();
|
|
150
197
|
} catch (err) {
|
|
198
|
+
if (this.pool) {
|
|
199
|
+
const pool = this.pool;
|
|
200
|
+
this.pool = null;
|
|
201
|
+
await closeQuietly(() => pool.end());
|
|
202
|
+
}
|
|
151
203
|
console.error("Failed to connect to PostgreSQL database:", err);
|
|
152
204
|
throw err;
|
|
153
205
|
}
|
|
@@ -187,7 +239,7 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
187
239
|
SELECT table_name
|
|
188
240
|
FROM information_schema.tables
|
|
189
241
|
WHERE table_schema = $1
|
|
190
|
-
AND table_type
|
|
242
|
+
AND table_type IN ('BASE TABLE', 'FOREIGN')
|
|
191
243
|
ORDER BY table_name
|
|
192
244
|
`,
|
|
193
245
|
[schemaToUse]
|
|
@@ -266,7 +318,7 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
266
318
|
AND i.oid = ix.indexrelid
|
|
267
319
|
AND a.attrelid = t.oid
|
|
268
320
|
AND a.attnum = ANY(ix.indkey)
|
|
269
|
-
AND t.relkind
|
|
321
|
+
AND t.relkind IN ('r','p')
|
|
270
322
|
AND t.relname = $1
|
|
271
323
|
AND ns.oid = t.relnamespace
|
|
272
324
|
AND ns.nspname = $2
|
|
@@ -377,6 +429,64 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
377
429
|
client.release();
|
|
378
430
|
}
|
|
379
431
|
}
|
|
432
|
+
async getHealthCheck() {
|
|
433
|
+
if (!this.pool) {
|
|
434
|
+
throw new Error("Not connected to database");
|
|
435
|
+
}
|
|
436
|
+
const client = await this.pool.connect();
|
|
437
|
+
try {
|
|
438
|
+
const [connectionsResult, maxConnectionsResult, bufferCacheResult] = await Promise.all([
|
|
439
|
+
client.query(`
|
|
440
|
+
SELECT
|
|
441
|
+
count(*) AS total,
|
|
442
|
+
count(*) FILTER (WHERE state = 'active') AS active,
|
|
443
|
+
count(*) FILTER (WHERE state = 'idle') AS idle,
|
|
444
|
+
count(*) FILTER (WHERE state = 'idle in transaction') AS idle_in_transaction,
|
|
445
|
+
count(*) FILTER (WHERE state = 'idle in transaction (aborted)') AS idle_in_transaction_aborted,
|
|
446
|
+
max(EXTRACT(EPOCH FROM (now() - state_change)))
|
|
447
|
+
FILTER (WHERE state = 'idle in transaction') AS longest_idle_in_transaction_seconds,
|
|
448
|
+
max(EXTRACT(EPOCH FROM (now() - query_start)))
|
|
449
|
+
FILTER (WHERE state = 'active') AS longest_active_query_seconds
|
|
450
|
+
FROM pg_stat_activity
|
|
451
|
+
WHERE pid <> pg_backend_pid()
|
|
452
|
+
`),
|
|
453
|
+
client.query(`SHOW max_connections`),
|
|
454
|
+
client.query(
|
|
455
|
+
`
|
|
456
|
+
SELECT
|
|
457
|
+
blks_hit,
|
|
458
|
+
blks_read,
|
|
459
|
+
CASE WHEN (blks_hit + blks_read) = 0 THEN NULL
|
|
460
|
+
ELSE round(100.0 * blks_hit / (blks_hit + blks_read), 2)
|
|
461
|
+
END AS hit_ratio_pct
|
|
462
|
+
FROM pg_stat_database
|
|
463
|
+
WHERE datname = current_database()
|
|
464
|
+
`
|
|
465
|
+
)
|
|
466
|
+
]);
|
|
467
|
+
const conn = connectionsResult.rows[0];
|
|
468
|
+
const cache = bufferCacheResult.rows[0];
|
|
469
|
+
return {
|
|
470
|
+
connections: {
|
|
471
|
+
total: Number(conn.total),
|
|
472
|
+
active: Number(conn.active),
|
|
473
|
+
idle: Number(conn.idle),
|
|
474
|
+
idleInTransaction: Number(conn.idle_in_transaction),
|
|
475
|
+
idleInTransactionAborted: Number(conn.idle_in_transaction_aborted),
|
|
476
|
+
maxConnections: Number(maxConnectionsResult.rows[0].max_connections),
|
|
477
|
+
longestIdleInTransactionSeconds: toNullableNumber(conn.longest_idle_in_transaction_seconds),
|
|
478
|
+
longestActiveQuerySeconds: toNullableNumber(conn.longest_active_query_seconds)
|
|
479
|
+
},
|
|
480
|
+
bufferCache: {
|
|
481
|
+
hitRatioPct: toNullableNumber(cache.hit_ratio_pct),
|
|
482
|
+
blocksHit: Number(cache.blks_hit),
|
|
483
|
+
blocksRead: Number(cache.blks_read)
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
} finally {
|
|
487
|
+
client.release();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
380
490
|
async getStoredProcedures(schema, routineType) {
|
|
381
491
|
if (!this.pool) {
|
|
382
492
|
throw new Error("Not connected to database");
|
|
@@ -490,57 +600,65 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
490
600
|
try {
|
|
491
601
|
const statements = splitSQLStatements(sql, "postgres");
|
|
492
602
|
if (statements.length === 1) {
|
|
493
|
-
const processedStatement = SQLRowLimiter.
|
|
603
|
+
const { sql: processedStatement, probeApplied } = SQLRowLimiter.applyMaxRowsWithTruncationProbe(
|
|
604
|
+
statements[0],
|
|
605
|
+
options.maxRows,
|
|
606
|
+
"postgres"
|
|
607
|
+
);
|
|
494
608
|
if (options.readonly) {
|
|
495
609
|
await client.query("BEGIN READ ONLY");
|
|
496
610
|
try {
|
|
497
611
|
const result2 = parameters && parameters.length > 0 ? await client.query(processedStatement, parameters) : await client.query(processedStatement);
|
|
498
612
|
await client.query("COMMIT");
|
|
499
|
-
|
|
613
|
+
const resultSet2 = {
|
|
614
|
+
sql: statements[0],
|
|
615
|
+
rows: result2.rows,
|
|
616
|
+
rowCount: result2.rowCount ?? result2.rows.length
|
|
617
|
+
};
|
|
618
|
+
SQLRowLimiter.flagTruncation(resultSet2, options.maxRows, probeApplied);
|
|
619
|
+
return { resultSets: [resultSet2] };
|
|
500
620
|
} catch (error) {
|
|
501
621
|
try {
|
|
502
622
|
await client.query("ROLLBACK");
|
|
503
623
|
} catch {
|
|
504
624
|
}
|
|
505
|
-
console.error(`[PostgreSQL executeSQL] ERROR: ${error.message}`);
|
|
506
|
-
console.error(`[PostgreSQL executeSQL] SQL: ${processedStatement}`);
|
|
507
|
-
if (parameters && parameters.length > 0) {
|
|
508
|
-
console.error(`[PostgreSQL executeSQL] Parameters: ${JSON.stringify(parameters)}`);
|
|
509
|
-
}
|
|
510
625
|
throw error;
|
|
511
626
|
}
|
|
512
627
|
}
|
|
513
628
|
let result;
|
|
514
629
|
if (parameters && parameters.length > 0) {
|
|
515
|
-
|
|
516
|
-
result = await client.query(processedStatement, parameters);
|
|
517
|
-
} catch (error) {
|
|
518
|
-
console.error(`[PostgreSQL executeSQL] ERROR: ${error.message}`);
|
|
519
|
-
console.error(`[PostgreSQL executeSQL] SQL: ${processedStatement}`);
|
|
520
|
-
console.error(`[PostgreSQL executeSQL] Parameters: ${JSON.stringify(parameters)}`);
|
|
521
|
-
throw error;
|
|
522
|
-
}
|
|
630
|
+
result = await client.query(processedStatement, parameters);
|
|
523
631
|
} else {
|
|
524
632
|
result = await client.query(processedStatement);
|
|
525
633
|
}
|
|
526
|
-
|
|
634
|
+
const resultSet = {
|
|
635
|
+
sql: statements[0],
|
|
636
|
+
rows: result.rows,
|
|
637
|
+
rowCount: result.rowCount ?? result.rows.length
|
|
638
|
+
};
|
|
639
|
+
SQLRowLimiter.flagTruncation(resultSet, options.maxRows, probeApplied);
|
|
640
|
+
return { resultSets: [resultSet] };
|
|
527
641
|
} else {
|
|
528
642
|
if (parameters && parameters.length > 0) {
|
|
529
643
|
throw new Error("Parameters are not supported for multi-statement queries in PostgreSQL");
|
|
530
644
|
}
|
|
531
|
-
|
|
532
|
-
let totalRowCount = 0;
|
|
645
|
+
const resultSets = [];
|
|
533
646
|
await client.query(options.readonly ? "BEGIN READ ONLY" : "BEGIN");
|
|
534
647
|
try {
|
|
535
648
|
for (let statement of statements) {
|
|
536
|
-
const processedStatement = SQLRowLimiter.
|
|
649
|
+
const { sql: processedStatement, probeApplied } = SQLRowLimiter.applyMaxRowsWithTruncationProbe(
|
|
650
|
+
statement,
|
|
651
|
+
options.maxRows,
|
|
652
|
+
"postgres"
|
|
653
|
+
);
|
|
537
654
|
const result = await client.query(processedStatement);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
655
|
+
const resultSet = {
|
|
656
|
+
sql: statement,
|
|
657
|
+
rows: result.rows ?? [],
|
|
658
|
+
rowCount: result.rowCount ?? result.rows?.length ?? 0
|
|
659
|
+
};
|
|
660
|
+
SQLRowLimiter.flagTruncation(resultSet, options.maxRows, probeApplied);
|
|
661
|
+
resultSets.push(resultSet);
|
|
544
662
|
}
|
|
545
663
|
await client.query("COMMIT");
|
|
546
664
|
} catch (error) {
|
|
@@ -550,7 +668,7 @@ var PostgresConnector = class _PostgresConnector {
|
|
|
550
668
|
}
|
|
551
669
|
throw error;
|
|
552
670
|
}
|
|
553
|
-
return {
|
|
671
|
+
return { resultSets };
|
|
554
672
|
}
|
|
555
673
|
} finally {
|
|
556
674
|
client.release();
|