@zz1996/dbhub-dameng 0.1.2 → 0.1.3

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.
@@ -23,22 +23,30 @@ Expected: ${expectedFormat}`
23
23
  const url = new SafeURL(dsn);
24
24
  const schema = url.pathname ? decodeURIComponent(url.pathname.substring(1)) : void 0;
25
25
  const port = url.port ? parseInt(url.port, 10) : 5236;
26
- const queryParams = [];
26
+ const queryParams = {};
27
+ const queryStringParts = [];
27
28
  url.forEachSearchParam((value, key) => {
28
- queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
29
+ queryParams[key] = value;
30
+ queryStringParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
29
31
  });
30
- const connectString = `dm://${encodeURIComponent(url.username)}:${encodeURIComponent(url.password)}@${url.hostname}:${port}${queryParams.length > 0 ? `?${queryParams.join("&")}` : ""}`;
31
32
  const connectionConfig = {
32
- connectString,
33
+ connectString: `dm://${encodeURIComponent(url.username)}:${encodeURIComponent(url.password)}@${url.hostname}:${port}${queryStringParts.length > 0 ? `?${queryStringParts.join("&")}` : ""}`,
34
+ directConnectString: `${url.hostname}:${port}`,
33
35
  user: url.username,
34
36
  password: url.password,
35
37
  schema: schema || void 0,
36
38
  poolMin: 0,
37
- poolMax: 4
39
+ poolMax: 4,
40
+ ...queryParams
38
41
  };
39
42
  if (config?.connectionTimeoutSeconds !== void 0) {
43
+ connectionConfig.connectTimeout = config.connectionTimeoutSeconds * 1e3;
40
44
  connectionConfig.queueTimeout = config.connectionTimeoutSeconds * 1e3;
41
45
  }
46
+ if (config?.queryTimeoutSeconds !== void 0) {
47
+ connectionConfig.sessionTimeout = config.queryTimeoutSeconds;
48
+ connectionConfig.socketTimeout = config.queryTimeoutSeconds * 1e3 + 1e3;
49
+ }
42
50
  return connectionConfig;
43
51
  } catch (error) {
44
52
  throw new Error(
@@ -80,10 +88,6 @@ var DamengConnector = class _DamengConnector {
80
88
  connectionConfig.poolAlias = this.buildPoolAlias();
81
89
  this.defaultSchema = connectionConfig.schema ?? null;
82
90
  this.poolAlias = connectionConfig.poolAlias;
83
- this.queryTimeoutMs = void 0;
84
- if (config?.queryTimeoutSeconds !== void 0) {
85
- this.queryTimeoutMs = config.queryTimeoutSeconds * 1e3;
86
- }
87
91
  await this.closeRegisteredPool(connectionConfig.poolAlias);
88
92
  await this.validateDirectConnection(connectionConfig);
89
93
  createdPool = await dmdb.createPool(connectionConfig);
@@ -135,6 +139,17 @@ var DamengConnector = class _DamengConnector {
135
139
  `);
136
140
  return rows.map((row) => this.rowValue(row, "SCHEMA_NAME")).filter(this.isPresent);
137
141
  }
142
+ async schemaExists(schema) {
143
+ const rows = await this.queryRows(
144
+ `
145
+ SELECT COUNT(*) AS CNT
146
+ FROM ALL_USERS
147
+ WHERE USERNAME = :1
148
+ `,
149
+ [this.normalizeIdentifier(schema)]
150
+ );
151
+ return Number(this.rowValue(rows[0], "CNT") ?? 0) > 0;
152
+ }
138
153
  async getDefaultSchema() {
139
154
  return this.defaultSchema;
140
155
  }
@@ -151,6 +166,25 @@ var DamengConnector = class _DamengConnector {
151
166
  );
152
167
  return rows.map((row) => this.rowValue(row, "TABLE_NAME")).filter(this.isPresent);
153
168
  }
169
+ async searchTables(pattern, schema, limit = 100) {
170
+ const owner = await this.resolveSchema(schema);
171
+ const rowLimit = this.normalizeLimit(limit);
172
+ const rows = await this.queryRows(
173
+ `
174
+ SELECT TABLE_NAME
175
+ FROM (
176
+ SELECT TABLE_NAME
177
+ FROM ALL_TABLES
178
+ WHERE OWNER = :1
179
+ AND TABLE_NAME LIKE :2
180
+ ORDER BY TABLE_NAME
181
+ )
182
+ WHERE ROWNUM <= ${rowLimit}
183
+ `,
184
+ [owner, this.normalizeLikePattern(pattern)]
185
+ );
186
+ return rows.map((row) => this.rowValue(row, "TABLE_NAME")).filter(this.isPresent).map((name) => ({ name, schema: owner }));
187
+ }
154
188
  async getViews(schema) {
155
189
  const owner = await this.resolveSchema(schema);
156
190
  const rows = await this.queryRows(
@@ -381,14 +415,26 @@ var DamengConnector = class _DamengConnector {
381
415
  executeOptions(extra = {}) {
382
416
  return {
383
417
  outFormat: dmdb.OUT_FORMAT_OBJECT,
384
- ...this.queryTimeoutMs !== void 0 && { queryTimeout: this.queryTimeoutMs },
385
418
  ...extra
386
419
  };
387
420
  }
388
421
  async validateDirectConnection(config) {
389
422
  let conn = null;
390
423
  try {
391
- conn = await dmdb.getConnection(config.connectString);
424
+ const {
425
+ directConnectString,
426
+ poolAlias,
427
+ poolMin,
428
+ poolMax,
429
+ queueRequests,
430
+ queueTimeout,
431
+ ...directConfig
432
+ } = config;
433
+ const directConn = await dmdb.getConnection({
434
+ ...directConfig,
435
+ connectString: directConnectString ?? config.connectString
436
+ });
437
+ conn = directConn;
392
438
  await conn.execute("SELECT 1 AS OK", [], this.executeOptions());
393
439
  } finally {
394
440
  if (conn) {
@@ -427,6 +473,12 @@ var DamengConnector = class _DamengConnector {
427
473
  normalizeIdentifier(identifier) {
428
474
  return /[a-z]/.test(identifier) ? identifier.toUpperCase() : identifier;
429
475
  }
476
+ normalizeLikePattern(pattern) {
477
+ return /[a-z]/.test(pattern) ? pattern.toUpperCase() : pattern;
478
+ }
479
+ normalizeLimit(limit) {
480
+ return Math.max(1, Math.min(1e3, Math.floor(limit)));
481
+ }
430
482
  normalizeRows(rows) {
431
483
  return rows.map((row) => {
432
484
  if (!Array.isArray(row)) {
package/dist/index.js CHANGED
@@ -431,23 +431,25 @@ async function searchTables(connector, pattern, schemaFilter, detailLevel, limit
431
431
  for (const schemaName of schemasToSearch) {
432
432
  if (results.length >= limit) break;
433
433
  try {
434
- const tables = await connector.getTables(schemaName);
435
- const matched = tables.filter((table) => regex.test(table));
436
- for (const tableName of matched) {
434
+ const searchableConnector = connector;
435
+ const matched = searchableConnector.searchTables ? await searchableConnector.searchTables(pattern, schemaName, limit - results.length) : (await connector.getTables(schemaName)).filter((table) => regex.test(table)).map((name) => ({ name, schema: schemaName }));
436
+ for (const tableMatch of matched) {
437
437
  if (results.length >= limit) break;
438
+ const tableName = tableMatch.name;
439
+ const matchedSchema = tableMatch.schema;
438
440
  if (detailLevel === "names") {
439
441
  results.push({
440
442
  name: tableName,
441
- schema: schemaName
443
+ schema: matchedSchema
442
444
  });
443
445
  } else if (detailLevel === "summary") {
444
446
  try {
445
- const columns = await connector.getTableSchema(tableName, schemaName);
446
- const rowCount = await getTableRowCount(connector, tableName, schemaName);
447
- const comment = await getTableComment(connector, tableName, schemaName);
447
+ const columns = await connector.getTableSchema(tableName, matchedSchema);
448
+ const rowCount = await getTableRowCount(connector, tableName, matchedSchema);
449
+ const comment = await getTableComment(connector, tableName, matchedSchema);
448
450
  results.push({
449
451
  name: tableName,
450
- schema: schemaName,
452
+ schema: matchedSchema,
451
453
  column_count: columns.length,
452
454
  row_count: rowCount,
453
455
  ...comment ? { comment } : {}
@@ -455,20 +457,20 @@ async function searchTables(connector, pattern, schemaFilter, detailLevel, limit
455
457
  } catch (error) {
456
458
  results.push({
457
459
  name: tableName,
458
- schema: schemaName,
460
+ schema: matchedSchema,
459
461
  column_count: null,
460
462
  row_count: null
461
463
  });
462
464
  }
463
465
  } else {
464
466
  try {
465
- const columns = await connector.getTableSchema(tableName, schemaName);
466
- const indexes = await connector.getTableIndexes(tableName, schemaName);
467
- const rowCount = await getTableRowCount(connector, tableName, schemaName);
468
- const comment = await getTableComment(connector, tableName, schemaName);
467
+ const columns = await connector.getTableSchema(tableName, matchedSchema);
468
+ const indexes = await connector.getTableIndexes(tableName, matchedSchema);
469
+ const rowCount = await getTableRowCount(connector, tableName, matchedSchema);
470
+ const comment = await getTableComment(connector, tableName, matchedSchema);
469
471
  results.push({
470
472
  name: tableName,
471
- schema: schemaName,
473
+ schema: matchedSchema,
472
474
  column_count: columns.length,
473
475
  row_count: rowCount,
474
476
  ...comment ? { comment } : {},
@@ -489,7 +491,7 @@ async function searchTables(connector, pattern, schemaFilter, detailLevel, limit
489
491
  } catch (error) {
490
492
  results.push({
491
493
  name: tableName,
492
- schema: schemaName,
494
+ schema: matchedSchema,
493
495
  error: `Unable to fetch full details: ${error.message}`
494
496
  });
495
497
  }
@@ -759,10 +761,10 @@ function createSearchDatabaseObjectsToolHandler(sourceId) {
759
761
  }
760
762
  }
761
763
  if (schema) {
762
- const schemas = await connector.getSchemas();
763
- if (!schemas.includes(schema)) {
764
+ const exists = connector.schemaExists ? await connector.schemaExists(schema) : (await connector.getSchemas()).includes(schema);
765
+ if (!exists) {
764
766
  success = false;
765
- errorMessage = `Schema '${schema}' does not exist. Available schemas: ${schemas.join(", ")}`;
767
+ errorMessage = `Schema '${schema}' does not exist`;
766
768
  return createToolErrorResponse(errorMessage, "SCHEMA_NOT_FOUND");
767
769
  }
768
770
  }
@@ -1833,7 +1835,7 @@ var connectorModules = [
1833
1835
  { load: () => import("./sqlite-IOUAYHGE.js"), name: "SQLite", driver: "node:sqlite" },
1834
1836
  { load: () => import("./mysql-A43SL7UM.js"), name: "MySQL", driver: "mysql2" },
1835
1837
  { load: () => import("./mariadb-7F72IRB4.js"), name: "MariaDB", driver: "mariadb" },
1836
- { load: () => import("./dameng-UJELBZ5R.js"), name: "Dameng", driver: "dmdb" }
1838
+ { load: () => import("./dameng-JYMTC4HE.js"), name: "Dameng", driver: "dmdb" }
1837
1839
  ];
1838
1840
  loadConnectors(connectorModules).then(() => main()).catch((error) => {
1839
1841
  console.error("Fatal error:", error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zz1996/dbhub-dameng",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "mcpName": "io.github.zuozh11/dbhub-dameng",
5
5
  "description": "Local fork of DBHub with Dameng/DM8 database connector support",
6
6
  "repository": {