@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.
Files changed (32) hide show
  1. package/README.md +126 -137
  2. package/dbhub.dameng.toml.example +4 -11
  3. package/dist/{chunk-SQA2ISDE.js → chunk-2JL4KCP5.js} +21 -119
  4. package/dist/chunk-3RJRH3CN.js +121 -0
  5. package/dist/chunk-4276LPPU.js +179 -0
  6. package/dist/chunk-FU2ZJE4E.js +16 -0
  7. package/dist/chunk-HDPZAIDL.js +155 -0
  8. package/dist/{chunk-2A2QF3CS.js → chunk-HGU7ILEZ.js} +215 -68
  9. package/dist/{chunk-IPK7BYBL.js → chunk-JFWX35TB.js} +0 -1
  10. package/dist/chunk-O3PEWKBB.js +302 -0
  11. package/dist/dameng-NKF7NZKE.js +250 -0
  12. package/dist/index.js +461 -251
  13. package/dist/{mariadb-7F72IRB4.js → mariadb-MMC6WMEG.js} +86 -53
  14. package/dist/{mysql-A43SL7UM.js → mysql-TESH7KKV.js} +126 -50
  15. package/dist/{postgres-VFNLBWMF.js → postgres-C24SBQ4I.js} +154 -36
  16. package/dist/public/assets/index-BJ-1UrcV.css +1 -0
  17. package/dist/public/assets/index-BdBaFSHd.js +148 -0
  18. package/dist/public/assets/postgres-BpcazhJg.svg +22 -0
  19. package/dist/public/assets/sqlserver-ByfFYYpV.svg +11 -0
  20. package/dist/public/favicon.svg +57 -0
  21. package/dist/public/index.html +14 -0
  22. package/dist/public/logo-full-light.svg +58 -0
  23. package/dist/{registry-XSX2VZTD.js → registry-WVSFVS35.js} +3 -2
  24. package/dist/{sqlite-IOUAYHGE.js → sqlite-7BNGDMBZ.js} +57 -42
  25. package/dist/sqlserver-KZPPK67Q.js +1042 -0
  26. package/package.json +22 -65
  27. package/dist/chunk-RTB262PR.js +0 -60
  28. package/dist/chunk-ZNQTMARG.js +0 -127
  29. package/dist/dameng-5KYI5JBK.js +0 -898
  30. package/dist/sqlserver-OE4SFH4B.js +0 -587
  31. package/docs/README.md +0 -14
  32. 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-IPK7BYBL.js";
6
+ } from "./chunk-JFWX35TB.js";
7
+ import {
8
+ obfuscateDSNPassword
9
+ } from "./chunk-3RJRH3CN.js";
4
10
  import {
5
- SQLRowLimiter
6
- } from "./chunk-ZNQTMARG.js";
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-SQA2ISDE.js";
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 pg from "pg";
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 } = pg;
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
- poolConfig.query_timeout = queryTimeoutSeconds * 1e3;
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 = 'BASE TABLE'
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 = 'r'
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.applyMaxRows(statements[0], options.maxRows);
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
- return { rows: result2.rows, rowCount: result2.rowCount ?? result2.rows.length };
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
- try {
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
- return { rows: result.rows, rowCount: result.rowCount ?? result.rows.length };
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
- let allRows = [];
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.applyMaxRows(statement, options.maxRows);
649
+ const { sql: processedStatement, probeApplied } = SQLRowLimiter.applyMaxRowsWithTruncationProbe(
650
+ statement,
651
+ options.maxRows,
652
+ "postgres"
653
+ );
537
654
  const result = await client.query(processedStatement);
538
- if (result.rows && result.rows.length > 0) {
539
- allRows.push(...result.rows);
540
- }
541
- if (result.rowCount) {
542
- totalRowCount += result.rowCount;
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 { rows: allRows, rowCount: totalRowCount };
671
+ return { resultSets };
554
672
  }
555
673
  } finally {
556
674
  client.release();