fix(metadata): await object cache invalidation on connection refresh

This commit is contained in:
soddygo authored and GitHub committed 2026-09-15 12:21:18 +08:00
1 parent f95650f039
commit faf259fcc2
17 files changed
+536 -32

No files matched your search

@@ -162,6 +162,7 @@ import { formatSqlForDisplay, sqlFormatDialectForDbType } from "@/lib/sql/sqlFor
import { omitDdlIdentifierQuotes } from "@/lib/sql/ddlDisplay";
import { getTableStructureCapabilities } from "@/lib/table/tableStructureCapabilities";
import { connectionObjectTreeNodeSchema, connectionObjectTreeQuerySchema, connectionTableSqlSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
import { isObjectCacheInvalidationError } from "@/lib/metadata/objectCacheInvalidationError";
import { hasTreeNodeDatabaseContext } from "@/lib/sidebar/treeNodeContext";
import {
defaultPasteTableMode,
@@ -2191,6 +2192,19 @@ function openElasticsearchIndexMetadata(kind: ElasticsearchIndexMetadataKind) {
async function refresh() {
const node = activeNode.value;
if (node.type === "connection" && node.connectionId) {
try {
await connectionStore.refreshConnectionTreeNode(node);
} catch (e: any) {
if (isObjectCacheInvalidationError(e)) {
toast(t("connection.objectCacheRefreshFailed", { message: translateBackendError(t, e) }), 5000);
return;
}
toast(t("connection.connectFailed", { message: translateBackendError(t, e) }), 5000);
openDriverStoreForInstallError(e?.message || String(e), node);
}
return;
}
try {
await connectionStore.refreshTreeNode(node);
} catch (e: any) {
@@ -0,0 +1,31 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../SidebarTreeRuntimeHost.vue", import.meta.url), "utf8");
/**
* Secondary evidence for the connection-node refresh wiring. The primary
* behavioral coverage lives in connectionStore.refresh.spec.ts and the
* metadata cache specs; this guards the component-side routing and error
* classification without mounting the full sidebar tree host.
*/
describe("SidebarTreeRuntimeHost connection refresh cache invalidation", () => {
it("routes connection-node refresh through the awaited strict store method", () => {
expect(source).toMatch(/if \(node\.type === "connection" && node\.connectionId\) \{\s*try \{\s*await connectionStore\.refreshConnectionTreeNode\(node\);/);
});
it("reports object cache failures distinctly without opening the driver store", () => {
const connectionBranch = source.slice(source.indexOf("await connectionStore.refreshConnectionTreeNode(node);"), source.indexOf("await connectionStore.refreshTreeNode(node);", source.indexOf("await connectionStore.refreshConnectionTreeNode(node);")));
const cacheFailureBlock = connectionBranch.match(/if \(isObjectCacheInvalidationError\(e\)\) \{[\s\S]*?\n\s*return;\s*\n/);
expect(cacheFailureBlock).not.toBeNull();
expect(cacheFailureBlock![0]).toContain('t("connection.objectCacheRefreshFailed"');
expect(cacheFailureBlock![0]).not.toContain("openDriverStoreForInstallError");
});
it("keeps the regular refresh path and its connection-error handling for other nodes", () => {
const refresh = source.slice(source.indexOf("async function refresh()"), source.indexOf("async function copyName()"));
const nonConnection = refresh.slice(refresh.indexOf("await connectionStore.refreshTreeNode(node);"));
expect(nonConnection).toMatch(/toast\(t\("connection\.connectFailed"/);
expect(nonConnection).toContain("openDriverStoreForInstallError");
});
});