@zz1996/dbhub-dameng 0.1.4 → 0.1.6
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.
|
@@ -11,8 +11,9 @@ import dmdb from "dmdb";
|
|
|
11
11
|
var DEFAULT_OPERATION_TIMEOUT_MS = 11e4;
|
|
12
12
|
var RESOURCE_CLEANUP_TIMEOUT_MS = 2e3;
|
|
13
13
|
var DamengOperationTimeoutError = class extends Error {
|
|
14
|
-
constructor(message) {
|
|
14
|
+
constructor(message, label) {
|
|
15
15
|
super(message);
|
|
16
|
+
this.label = label;
|
|
16
17
|
this.name = "DamengOperationTimeoutError";
|
|
17
18
|
}
|
|
18
19
|
};
|
|
@@ -102,6 +103,8 @@ var DamengConnector = class _DamengConnector {
|
|
|
102
103
|
this.poolAlias = connectionConfig.poolAlias;
|
|
103
104
|
this.connectionTimeoutMs = config?.connectionTimeoutSeconds !== void 0 ? config.connectionTimeoutSeconds * 1e3 : 5e3;
|
|
104
105
|
this.operationTimeoutMs = config?.queryTimeoutSeconds !== void 0 ? config.queryTimeoutSeconds * 1e3 : DEFAULT_OPERATION_TIMEOUT_MS;
|
|
106
|
+
connectionConfig.connectTimeout ?? (connectionConfig.connectTimeout = this.connectionTimeoutMs);
|
|
107
|
+
connectionConfig.queueTimeout ?? (connectionConfig.queueTimeout = this.connectionTimeoutMs);
|
|
105
108
|
await this.closeRegisteredPool(connectionConfig.poolAlias);
|
|
106
109
|
await this.validateDirectConnection(connectionConfig);
|
|
107
110
|
createdPool = await dmdb.createPool(connectionConfig);
|
|
@@ -217,6 +220,64 @@ var DamengConnector = class _DamengConnector {
|
|
|
217
220
|
);
|
|
218
221
|
return rows.map((row) => this.rowValue(row, "TABLE_NAME")).filter(this.isPresent).map((name) => ({ name, schema: owner }));
|
|
219
222
|
}
|
|
223
|
+
async searchColumns(pattern, schema, table, limit = 100) {
|
|
224
|
+
const owner = await this.resolveSchema(schema);
|
|
225
|
+
const rowLimit = this.normalizeLimit(limit);
|
|
226
|
+
const bindValues = [
|
|
227
|
+
owner,
|
|
228
|
+
this.normalizeLikePattern(pattern),
|
|
229
|
+
...table ? [this.normalizeIdentifier(table)] : []
|
|
230
|
+
];
|
|
231
|
+
const tablePredicate = table ? "AND c.TABLE_NAME = :3" : "";
|
|
232
|
+
const rows = await this.queryRows(
|
|
233
|
+
`
|
|
234
|
+
SELECT COLUMN_NAME,
|
|
235
|
+
TABLE_NAME,
|
|
236
|
+
DATA_TYPE,
|
|
237
|
+
DATA_LENGTH,
|
|
238
|
+
DATA_PRECISION,
|
|
239
|
+
DATA_SCALE,
|
|
240
|
+
NULLABLE,
|
|
241
|
+
DATA_DEFAULT,
|
|
242
|
+
COMMENTS
|
|
243
|
+
FROM (
|
|
244
|
+
SELECT c.COLUMN_NAME,
|
|
245
|
+
c.TABLE_NAME,
|
|
246
|
+
c.DATA_TYPE,
|
|
247
|
+
c.DATA_LENGTH,
|
|
248
|
+
c.DATA_PRECISION,
|
|
249
|
+
c.DATA_SCALE,
|
|
250
|
+
c.NULLABLE,
|
|
251
|
+
c.DATA_DEFAULT,
|
|
252
|
+
cc.COMMENTS,
|
|
253
|
+
c.COLUMN_ID
|
|
254
|
+
FROM ALL_TAB_COLUMNS c
|
|
255
|
+
LEFT JOIN ALL_COL_COMMENTS cc
|
|
256
|
+
ON cc.OWNER = c.OWNER
|
|
257
|
+
AND cc.TABLE_NAME = c.TABLE_NAME
|
|
258
|
+
AND cc.COLUMN_NAME = c.COLUMN_NAME
|
|
259
|
+
WHERE c.OWNER = :1
|
|
260
|
+
AND c.COLUMN_NAME LIKE :2
|
|
261
|
+
${tablePredicate}
|
|
262
|
+
ORDER BY c.TABLE_NAME, c.COLUMN_ID
|
|
263
|
+
)
|
|
264
|
+
WHERE ROWNUM <= ${rowLimit}
|
|
265
|
+
`,
|
|
266
|
+
bindValues
|
|
267
|
+
);
|
|
268
|
+
return rows.map((row) => {
|
|
269
|
+
const description = this.rowValue(row, "COMMENTS");
|
|
270
|
+
return {
|
|
271
|
+
name: this.rowValue(row, "COLUMN_NAME") ?? "",
|
|
272
|
+
table: this.rowValue(row, "TABLE_NAME") ?? "",
|
|
273
|
+
schema: owner,
|
|
274
|
+
type: this.formatDataType(row),
|
|
275
|
+
nullable: this.rowValue(row, "NULLABLE") === "Y",
|
|
276
|
+
default: this.rowValue(row, "DATA_DEFAULT") ?? null,
|
|
277
|
+
...description ? { description } : {}
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
}
|
|
220
281
|
async getViews(schema) {
|
|
221
282
|
const owner = await this.resolveSchema(schema);
|
|
222
283
|
const rows = await this.queryRows(
|
|
@@ -436,6 +497,20 @@ var DamengConnector = class _DamengConnector {
|
|
|
436
497
|
});
|
|
437
498
|
}
|
|
438
499
|
async withConnection(fn) {
|
|
500
|
+
try {
|
|
501
|
+
return await this.withConnectionAttempt(fn);
|
|
502
|
+
} catch (error) {
|
|
503
|
+
if (!this.isConnectionAcquisitionFailure(error)) {
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
console.error(
|
|
507
|
+
`Retrying Dameng source '${this.sourceId}' after connection acquisition failure: ${error instanceof Error ? error.message : String(error)}`
|
|
508
|
+
);
|
|
509
|
+
await this.ensurePool();
|
|
510
|
+
return this.withConnectionAttempt(fn);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
async withConnectionAttempt(fn) {
|
|
439
514
|
await this.ensurePool();
|
|
440
515
|
const pool = this.pool;
|
|
441
516
|
if (!pool) {
|
|
@@ -444,16 +519,15 @@ var DamengConnector = class _DamengConnector {
|
|
|
444
519
|
let conn = null;
|
|
445
520
|
let shouldRelease = true;
|
|
446
521
|
try {
|
|
447
|
-
conn = await this.
|
|
448
|
-
pool.getConnection(),
|
|
449
|
-
this.connectionTimeoutMs,
|
|
450
|
-
"Dameng connection acquisition"
|
|
451
|
-
);
|
|
522
|
+
conn = await this.acquireConnectionWithTimeout(pool);
|
|
452
523
|
return await fn(conn);
|
|
453
524
|
} catch (error) {
|
|
454
525
|
if (error instanceof DamengOperationTimeoutError) {
|
|
455
526
|
shouldRelease = false;
|
|
456
527
|
this.markPoolUnhealthy(error.message);
|
|
528
|
+
} else if (!conn && this.isConnectionAcquisitionFailure(error)) {
|
|
529
|
+
shouldRelease = false;
|
|
530
|
+
this.markPoolUnhealthy(error instanceof Error ? error.message : String(error));
|
|
457
531
|
}
|
|
458
532
|
throw error;
|
|
459
533
|
} finally {
|
|
@@ -462,6 +536,21 @@ var DamengConnector = class _DamengConnector {
|
|
|
462
536
|
}
|
|
463
537
|
}
|
|
464
538
|
}
|
|
539
|
+
async acquireConnectionWithTimeout(pool) {
|
|
540
|
+
const acquisition = pool.getConnection();
|
|
541
|
+
try {
|
|
542
|
+
return await this.withTimeout(
|
|
543
|
+
acquisition,
|
|
544
|
+
this.connectionTimeoutMs,
|
|
545
|
+
"Dameng connection acquisition"
|
|
546
|
+
);
|
|
547
|
+
} catch (error) {
|
|
548
|
+
if (error instanceof DamengOperationTimeoutError) {
|
|
549
|
+
void acquisition.then((conn) => this.releaseConnectionQuietly(conn)).catch(() => void 0);
|
|
550
|
+
}
|
|
551
|
+
throw error;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
465
554
|
async ensurePool() {
|
|
466
555
|
if (this.pool) {
|
|
467
556
|
return;
|
|
@@ -523,7 +612,7 @@ var DamengConnector = class _DamengConnector {
|
|
|
523
612
|
let timer;
|
|
524
613
|
const timeout = new Promise((_, reject) => {
|
|
525
614
|
timer = setTimeout(() => {
|
|
526
|
-
reject(new DamengOperationTimeoutError(`${label} timed out after ${timeoutMs}ms
|
|
615
|
+
reject(new DamengOperationTimeoutError(`${label} timed out after ${timeoutMs}ms`, label));
|
|
527
616
|
}, timeoutMs);
|
|
528
617
|
});
|
|
529
618
|
try {
|
|
@@ -556,6 +645,18 @@ var DamengConnector = class _DamengConnector {
|
|
|
556
645
|
);
|
|
557
646
|
}
|
|
558
647
|
}
|
|
648
|
+
isConnectionAcquisitionFailure(error) {
|
|
649
|
+
if (error instanceof DamengOperationTimeoutError) {
|
|
650
|
+
return error.label === "Dameng connection acquisition";
|
|
651
|
+
}
|
|
652
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
653
|
+
return [
|
|
654
|
+
"Connection request timeout in queue",
|
|
655
|
+
"Pool cannot open more connections",
|
|
656
|
+
"\u83B7\u53D6\u8FDE\u63A5\u8BF7\u6C42\u7B49\u5F85\u8D85\u65F6",
|
|
657
|
+
"\u8FDE\u63A5\u6C60\u5DF2\u8FBE\u5230\u6700\u5927\u8FDE\u63A5\u6570"
|
|
658
|
+
].some((item) => message.includes(item));
|
|
659
|
+
}
|
|
559
660
|
executeOptions(extra = {}) {
|
|
560
661
|
return {
|
|
561
662
|
outFormat: dmdb.OUT_FORMAT_OBJECT,
|
package/dist/index.js
CHANGED
|
@@ -586,6 +586,36 @@ async function searchColumns(connector, pattern, schemaFilter, tableFilter, deta
|
|
|
586
586
|
for (const schemaName of schemasToSearch) {
|
|
587
587
|
if (results.length >= limit) break;
|
|
588
588
|
try {
|
|
589
|
+
const searchableConnector = connector;
|
|
590
|
+
if (searchableConnector.searchColumns) {
|
|
591
|
+
const matchedColumns = await searchableConnector.searchColumns(
|
|
592
|
+
pattern,
|
|
593
|
+
schemaName,
|
|
594
|
+
tableFilter,
|
|
595
|
+
limit - results.length
|
|
596
|
+
);
|
|
597
|
+
for (const column of matchedColumns) {
|
|
598
|
+
if (results.length >= limit) break;
|
|
599
|
+
if (detailLevel === "names") {
|
|
600
|
+
results.push({
|
|
601
|
+
name: column.name,
|
|
602
|
+
table: column.table,
|
|
603
|
+
schema: column.schema
|
|
604
|
+
});
|
|
605
|
+
} else {
|
|
606
|
+
results.push({
|
|
607
|
+
name: column.name,
|
|
608
|
+
table: column.table,
|
|
609
|
+
schema: column.schema,
|
|
610
|
+
type: column.type,
|
|
611
|
+
nullable: column.nullable,
|
|
612
|
+
default: column.default,
|
|
613
|
+
...column.description ? { description: column.description } : {}
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
589
619
|
let tablesToSearch;
|
|
590
620
|
if (tableFilter) {
|
|
591
621
|
tablesToSearch = [tableFilter];
|
|
@@ -1835,7 +1865,7 @@ var connectorModules = [
|
|
|
1835
1865
|
{ load: () => import("./sqlite-IOUAYHGE.js"), name: "SQLite", driver: "node:sqlite" },
|
|
1836
1866
|
{ load: () => import("./mysql-A43SL7UM.js"), name: "MySQL", driver: "mysql2" },
|
|
1837
1867
|
{ load: () => import("./mariadb-7F72IRB4.js"), name: "MariaDB", driver: "mariadb" },
|
|
1838
|
-
{ load: () => import("./dameng-
|
|
1868
|
+
{ load: () => import("./dameng-27LNS5MO.js"), name: "Dameng", driver: "dmdb" }
|
|
1839
1869
|
];
|
|
1840
1870
|
loadConnectors(connectorModules).then(() => main()).catch((error) => {
|
|
1841
1871
|
console.error("Fatal error:", error);
|