fix(xugu): place public synonyms after schemas

This commit is contained in:
Elias authored and GitHub committed 2026-08-15 21:55:54 +08:00
1 parent 868502326c
commit 5bfb07eef0
4 files changed
+81 -12

No files matched your search

+31 -10
View File
@@ -119,7 +119,7 @@ import { appendConnectionErrorHints, isMysqlMissingPasswordFailure } from "@/lib
import { connectionNeedsPasswordPrompt } from "@/lib/connection/connectionPassword";
import { appendVisibleDatabaseSelection } from "@/lib/connection/connectionVisibleDatabases";
import { buildXuguTypeMemberNodes, isXuguTypeMemberContainer } from "@/lib/sidebar/xuguTypeMembers";
import { isXuguPublicSynonymScope, xuguSchemaDisplayName, XUGU_PUBLIC_SYNONYM_SCOPE } from "@/lib/sidebar/xuguPublicSynonyms";
import { isXuguPublicSynonymScope, sortXuguSchemaInfos, xuguSchemaDisplayName, XUGU_PUBLIC_SYNONYM_SCOPE } from "@/lib/sidebar/xuguPublicSynonyms";
import { filterNacosNamespacesForSidebar, normalizeNacosNamespacesForDisplay } from "@/lib/nacos/nacosNamespaceVisibility";
import { buildPackageMemberNodes, markPackageNodesExpandable } from "@/lib/sidebar/packageMembers";
import { configuredDatabaseProductName, connectionConfigFingerprint, normalizeDatabaseConnectionInfo } from "@/lib/connection/connectionDatabaseInfo";
@@ -1543,6 +1543,18 @@ export const useConnectionStore = defineStore("connection", () => {
return sidebarObjectKindsForDatabase(dbType);
}
function sidebarObjectTypesForScope(config: ConnectionConfig | undefined, schema?: string): DatabaseObjectTreeKind[] {
if (config?.db_type === "xugu" && isXuguPublicSynonymScope(schema)) {
return ["SYNONYM"];
}
return supportedSidebarObjectTypes(config);
}
function objectTreeCacheVersion(config: ConnectionConfig | undefined, schema: string | undefined, baseVersion: string): string {
const scopedVersion = config?.db_type === "xugu" && isXuguPublicSynonymScope(schema) ? `${baseVersion}-public-synonyms` : baseVersion;
return ownerAwareMetadataCacheVersion(config, scopedVersion);
}
function sortSidebarSchemaInfos(schemas: readonly SchemaInfo[]): SchemaInfo[] {
const byName = new Map<string, SchemaInfo>();
for (const schema of schemas) {
@@ -1550,7 +1562,7 @@ export const useConnectionStore = defineStore("connection", () => {
if (!name) continue;
byName.set(name, { name, comment: schema.comment ?? null });
}
return sortSidebarNames([...byName.keys()]).map((name) => byName.get(name)!);
return sortXuguSchemaInfos([...byName.values()], compareSidebarNames);
}
function buildExtensionManagementNode(connectionId: string, database: string): TreeNode {
@@ -1570,7 +1582,7 @@ export const useConnectionStore = defineStore("connection", () => {
const objectTreeProfileCacheKey = driverProfileObjectTreeProfileForConnection(config)?.cacheKey;
// objects-v8: object-group listing SQL gained a pg_type branch for
// PostgreSQL-family user-defined types; older cached lists miss TYPE nodes.
const baseCacheVersion = ownerAwareMetadataCacheVersion(config, config?.db_type === "oracle" ? "objects-v7" : "objects-v8");
const baseCacheVersion = objectTreeCacheVersion(config, node.schema, config?.db_type === "oracle" ? "objects-v7" : "objects-v8");
const cacheVersion = objectTreeProfileCacheKey ? `${baseCacheVersion}:${objectTreeProfileCacheKey}` : baseCacheVersion;
return schemaCacheKey(node.connectionId || "", node.database || "", node.schema || "", node.type, cacheVersion);
}
@@ -4353,7 +4365,9 @@ export const useConnectionStore = defineStore("connection", () => {
if (useCachedChildren(node, options, load)) return;
const config = getConfig(connectionId);
const showSystemSchemas = config?.show_system_schemas === true;
const cacheVersion = ownerAwareMetadataCacheVersion(config, config?.db_type === "xugu" ? "schemas-v4" : "schemas-v3");
// schemas-v5 invalidates cached children created before the public
// synonym scope was placed after all real schemas.
const cacheVersion = ownerAwareMetadataCacheVersion(config, config?.db_type === "xugu" ? "schemas-v5" : "schemas-v3");
const cacheKey = schemaCacheKey(connectionId, database, cacheVersion, showSystemSchemas ? "show-system" : "hide-system");
if (!options?.force) {
const cached = await loadPersistedTreeChildren(node, cacheKey, load);
@@ -4723,7 +4737,7 @@ export const useConnectionStore = defineStore("connection", () => {
async function loadTables(connectionId: string, database: string, schema?: string, options?: LoadTreeOptions) {
const configForScope = getConfig(connectionId);
const simpleObjectDisplayForScope = useSettingsStore().editorSettings.sidebarObjectDisplay === "simple";
const objectTypesForScope = simpleObjectDisplayForScope ? supportedSidebarObjectTypes(configForScope) : undefined;
const objectTypesForScope = simpleObjectDisplayForScope ? sidebarObjectTypesForScope(configForScope, schema) : undefined;
const searchFilter = activeTreeLoadSearchFilter(options);
const querySchemaForScope = connectionObjectTreeQuerySchema(configForScope, database, schema);
const effectiveSchemaForScope = connectionObjectTreeNodeSchema(configForScope, database, schema);
@@ -4735,7 +4749,7 @@ export const useConnectionStore = defineStore("connection", () => {
});
if (!options?.force && simpleObjectDisplayForScope && !searchFilter && !options?.sidebarTableSearchParentId && !tableNameFilterForScope) {
const nodeId = schema ? `${connectionId}:${database}:${schema}` : `${connectionId}:${database}`;
const cacheKey = schemaCacheKey(connectionId, database, schema || "", ownerAwareMetadataCacheVersion(configForScope, "objects-simple-v8"));
const cacheKey = schemaCacheKey(connectionId, database, schema || "", objectTreeCacheVersion(configForScope, schema, "objects-simple-v8"));
if (await hydrateTreeNodeFromCache(findNode(treeNodes.value, nodeId), cacheKey)) {
void loadTables(connectionId, database, schema, { ...options, force: true }).catch(() => undefined);
return;
@@ -4769,7 +4783,8 @@ export const useConnectionStore = defineStore("connection", () => {
const searchFilter = activeTreeLoadSearchFilter(options);
const config = getConfig(connectionId);
const objectTreeProfile = driverProfileObjectTreeProfileForConnection(config);
const baseCacheVersion = ownerAwareMetadataCacheVersion(config, simpleObjectDisplay ? "objects-simple-v8" : "objects-grouped-v8");
const isPublicSynonymScope = config?.db_type === "xugu" && isXuguPublicSynonymScope(schema);
const baseCacheVersion = objectTreeCacheVersion(config, schema, simpleObjectDisplay ? "objects-simple-v8" : "objects-grouped-v8");
const cacheVersion = !simpleObjectDisplay && objectTreeProfile?.cacheKey ? `${baseCacheVersion}:${objectTreeProfile.cacheKey}` : baseCacheVersion;
const cacheKey = schemaCacheKey(connectionId, database, schema || "", cacheVersion);
const querySchema = connectionObjectTreeQuerySchema(config, database, schema);
@@ -4789,10 +4804,10 @@ export const useConnectionStore = defineStore("connection", () => {
}
}
const nonTableObjectTypes = simpleObjectDisplay ? supportedSidebarObjectTypes(config).filter((objectType) => objectType !== "TABLE") : [];
const nonTableObjectTypes = simpleObjectDisplay ? sidebarObjectTypesForScope(config, schema).filter((objectType) => objectType !== "TABLE") : [];
let children: TreeNode[];
let nextObjectCount: number | undefined;
if (simpleObjectDisplay) {
if (simpleObjectDisplay && !isPublicSynonymScope) {
const pageSize = sidebarObjectGroupPageSize();
const page = await loadPagedSimpleTableChildren({
nodeId,
@@ -4808,13 +4823,19 @@ export const useConnectionStore = defineStore("connection", () => {
});
children = page.hasMore && !searchFilter ? appendTableTreeLoadMoreNode(page.children, buildLoadMoreNode(node, page.nextOffset, pageSize), page.loadMoreParent) : page.children;
nextObjectCount = page.objectCount;
} else if (simpleObjectDisplay) {
// The synthetic public scope contains no tables. Avoid issuing a
// table-list query against the protocol namespace; supplemental
// object loading below will add only its SYNONYM entries.
children = [];
nextObjectCount = 0;
} else {
children = buildObjectGroupPlaceholderNodes({
nodeId,
connectionId,
database,
schema: effectiveSchema,
objectTypes: supportedSidebarObjectTypes(config),
objectTypes: sidebarObjectTypesForScope(config, schema),
groupOverrides: objectTreeProfile?.groupOverrides,
});
if (!schema && isPostgresLikeForExtensions(config?.db_type)) {