fix(xugu): exclude synthetic scopes from schema export

This commit is contained in:
Elias authored and GitHub committed 2026-09-06 10:25:16 +08:00
1 parent 6886fde709
commit 5d65be03a3
3 files changed
+55 -4

No files matched your search

@@ -0,0 +1,37 @@
import { describe, expect, it } from "vitest";
import { buildAllDatabaseExportPlan, filterExportableSchemas } from "@/lib/export/databaseExport";
import { XUGU_PUBLIC_SYNONYM_SCOPE, XUGU_SCHEDULER_JOB_SCOPE } from "@/lib/sidebar/xuguPublicSynonyms";
describe("database export schema selection", () => {
it("hides Xugu synthetic tree scopes while preserving real schemas", () => {
const schemas = ["APP_TEST", "GUEST", XUGU_PUBLIC_SYNONYM_SCOPE, XUGU_SCHEDULER_JOB_SCOPE];
expect(filterExportableSchemas(schemas, "xugu")).toEqual(["APP_TEST", "GUEST"]);
});
it("does not apply Xugu filtering to other database types", () => {
const schemas = ["APP_TEST", XUGU_PUBLIC_SYNONYM_SCOPE, XUGU_SCHEDULER_JOB_SCOPE];
expect(filterExportableSchemas(schemas, "postgres")).toEqual(schemas);
});
it("excludes synthetic scopes from an all-database Xugu export plan", () => {
expect(
buildAllDatabaseExportPlan({
databases: ["SHOP_DEMO"],
schemaAware: true,
dbType: "xugu",
schemasByDatabase: {
SHOP_DEMO: ["APP_TEST", XUGU_PUBLIC_SYNONYM_SCOPE, XUGU_SCHEDULER_JOB_SCOPE],
},
}),
).toEqual([
{
database: "SHOP_DEMO",
schema: "APP_TEST",
fileStem: "SHOP_DEMO",
displayName: "SHOP_DEMO",
},
]);
});
});
+15 -1
View File
@@ -3,6 +3,7 @@ import * as api from "@/lib/backend/api.ts";
import { buildTableSelectSql } from "@/lib/table/tableSelectSql.ts";
import { uuid } from "@/lib/common/utils.ts";
import { SINGLE_DATABASE_TYPES } from "@/lib/database/databaseCapabilitySets";
import { isXuguSyntheticScope } from "@/lib/sidebar/xuguPublicSynonyms";
export const DATABASE_EXPORT_ROW_LIMIT = 10_000;
export const DATABASE_EXPORT_PAGE_SIZE = 500;
@@ -76,6 +77,19 @@ export interface AllDatabaseExportPlanItem {
displayName: string;
}
/**
* Return schemas that can be exported as ordinary schema-owned objects.
*
* Xugu exposes database-global namespaces (public synonyms and scheduler jobs)
* through reserved synthetic schema names so the sidebar can reuse its normal
* tree loading path. They are not real schemas and must not be offered by the
* schema export selector.
*/
export function filterExportableSchemas(schemas: readonly string[], databaseType?: DatabaseType): string[] {
if (databaseType !== "xugu") return [...schemas];
return schemas.filter((schema) => !isXuguSyntheticScope(schema));
}
export interface DatabaseBackupSnapshotOptions {
connectionId: string;
database: string;
@@ -153,7 +167,7 @@ export function buildAllDatabaseExportPlan(options: AllDatabaseExportPlanInput):
}));
}
return options.databases.flatMap((database) => {
const schemas = options.schemaAware ? (options.schemasByDatabase?.[database] ?? []).filter((schema) => schema.trim()) : [database];
const schemas = options.schemaAware ? filterExportableSchemas(options.schemasByDatabase?.[database] ?? [], options.dbType).filter((schema) => schema.trim()) : [database];
const exportSchemas = schemas.length > 0 ? schemas : [database];
const includeSchemaInFileName = options.schemaAware && exportSchemas.length > 1;