fix(transfer): list Dameng schemas as databases
This commit is contained in:
1 parent
b7f1820e12
commit
0b86d8278d
3 files changed
+74
-14
No files matched your search
@@ -1,7 +1,9 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { fetchSqlFileTargetOptions } from "@/composables/useDatabaseOptions";
|
||||
import { databaseOptionsForConnection, fetchNamespaceOptionsForConnection, fetchSqlFileTargetOptions, namespaceOptionsAreSchemas, useDatabaseOptions } from "@/composables/useDatabaseOptions";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
ensureConnected: vi.fn(),
|
||||
getConfig: vi.fn(),
|
||||
listDatabases: vi.fn(),
|
||||
listSchemas: vi.fn(),
|
||||
}));
|
||||
@@ -12,10 +14,13 @@ vi.mock("@/lib/backend/api", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("@/stores/connectionStore", () => ({
|
||||
useConnectionStore: vi.fn(),
|
||||
useConnectionStore: () => ({
|
||||
ensureConnected: mocks.ensureConnected,
|
||||
getConfig: mocks.getConfig,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("fetchSqlFileTargetOptions", () => {
|
||||
describe("namespace options", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
@@ -23,7 +28,7 @@ describe("fetchSqlFileTargetOptions", () => {
|
||||
it("uses Dameng schemas so independent schemas remain selectable", async () => {
|
||||
mocks.listSchemas.mockResolvedValue(["APP_USER", "REPORTING", "SYS"]);
|
||||
|
||||
const options = await fetchSqlFileTargetOptions("connection-1", {
|
||||
const options = await fetchNamespaceOptionsForConnection("connection-1", {
|
||||
db_type: "dameng",
|
||||
database: "APP_USER",
|
||||
visible_databases: ["APP_USER", "REPORTING"],
|
||||
@@ -37,7 +42,7 @@ describe("fetchSqlFileTargetOptions", () => {
|
||||
it("honors the configured Dameng schema filter before the legacy database filter", async () => {
|
||||
mocks.listSchemas.mockResolvedValue(["APP_USER", "REPORTING", "ARCHIVE"]);
|
||||
|
||||
const options = await fetchSqlFileTargetOptions("connection-1", {
|
||||
const options = await fetchNamespaceOptionsForConnection("connection-1", {
|
||||
db_type: "dameng",
|
||||
database: "APP_USER",
|
||||
visible_databases: ["APP_USER", "REPORTING"],
|
||||
@@ -50,7 +55,7 @@ describe("fetchSqlFileTargetOptions", () => {
|
||||
it("preserves listDatabases and visible database filtering for other databases", async () => {
|
||||
mocks.listDatabases.mockResolvedValue([{ name: "app" }, { name: "analytics" }, { name: "postgres" }]);
|
||||
|
||||
const options = await fetchSqlFileTargetOptions("connection-2", {
|
||||
const options = await fetchNamespaceOptionsForConnection("connection-2", {
|
||||
db_type: "postgres",
|
||||
database: "app",
|
||||
visible_databases: ["analytics"],
|
||||
@@ -61,15 +66,53 @@ describe("fetchSqlFileTargetOptions", () => {
|
||||
expect(mocks.listSchemas).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("preserves visible database filtering for MongoDB transfer options", () => {
|
||||
expect(
|
||||
databaseOptionsForConnection(["app", "analytics", "admin"], {
|
||||
db_type: "mongodb",
|
||||
visible_databases: ["analytics"],
|
||||
}),
|
||||
).toEqual(["analytics"]);
|
||||
});
|
||||
|
||||
it("propagates metadata loading errors", async () => {
|
||||
const error = new Error("schema metadata failed");
|
||||
mocks.listSchemas.mockRejectedValue(error);
|
||||
|
||||
await expect(
|
||||
fetchNamespaceOptionsForConnection("connection-1", {
|
||||
db_type: "dameng",
|
||||
database: "APP_USER",
|
||||
}),
|
||||
).rejects.toBe(error);
|
||||
});
|
||||
|
||||
it("keeps the SQL file target on the shared namespace loader", async () => {
|
||||
mocks.listSchemas.mockResolvedValue(["APP_USER", "REPORTING"]);
|
||||
|
||||
await expect(
|
||||
fetchSqlFileTargetOptions("connection-1", {
|
||||
db_type: "dameng",
|
||||
database: "APP_USER",
|
||||
}),
|
||||
).rejects.toBe(error);
|
||||
).resolves.toEqual(["APP_USER", "REPORTING"]);
|
||||
});
|
||||
|
||||
it("identifies only Dameng top-level options as schemas", () => {
|
||||
expect(namespaceOptionsAreSchemas({ db_type: "dameng" })).toBe(true);
|
||||
expect(namespaceOptionsAreSchemas({ db_type: "oracle" })).toBe(false);
|
||||
expect(namespaceOptionsAreSchemas({ db_type: "postgres" })).toBe(false);
|
||||
});
|
||||
|
||||
it("does not expand the global database options composable to Dameng schemas", async () => {
|
||||
mocks.getConfig.mockReturnValue({ db_type: "dameng" });
|
||||
mocks.listDatabases.mockResolvedValue([]);
|
||||
|
||||
const { databaseOptions, loadDatabaseOptions } = useDatabaseOptions();
|
||||
await loadDatabaseOptions("connection-1");
|
||||
|
||||
expect(databaseOptions.value["connection-1"]).toEqual([]);
|
||||
expect(mocks.listDatabases).toHaveBeenCalledWith("connection-1");
|
||||
expect(mocks.listSchemas).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ import { usesTreeSchemaMode } from "@/lib/database/databaseCapabilities";
|
||||
import type { ConnectionConfig } from "@/types/database";
|
||||
import * as api from "@/lib/backend/api";
|
||||
|
||||
type SqlFileTargetConnection = Pick<ConnectionConfig, "database" | "db_type" | "driver_profile" | "visible_databases" | "visible_schemas">;
|
||||
type NamespaceOptionsConnection = Pick<ConnectionConfig, "database" | "db_type" | "driver_profile" | "visible_databases" | "visible_schemas">;
|
||||
|
||||
export function databaseOptionsForConnection(databaseNames: string[], connection: Pick<ConnectionConfig, "db_type" | "visible_databases"> | undefined): string[] {
|
||||
const names = filterDatabaseNamesForConnection(databaseNames, connection);
|
||||
@@ -13,7 +13,11 @@ export function databaseOptionsForConnection(databaseNames: string[], connection
|
||||
return names;
|
||||
}
|
||||
|
||||
export async function fetchSqlFileTargetOptions(connectionId: string, connection: SqlFileTargetConnection): Promise<string[]> {
|
||||
export function namespaceOptionsAreSchemas(connection: Pick<ConnectionConfig, "db_type"> | undefined): boolean {
|
||||
return connection?.db_type === "dameng";
|
||||
}
|
||||
|
||||
export async function fetchNamespaceOptionsForConnection(connectionId: string, connection: NamespaceOptionsConnection): Promise<string[]> {
|
||||
if (connection.db_type === "dameng") {
|
||||
const database = connection.database || "";
|
||||
// Dameng users and schemas are not interchangeable: independent schemas
|
||||
@@ -29,6 +33,10 @@ export async function fetchSqlFileTargetOptions(connectionId: string, connection
|
||||
);
|
||||
}
|
||||
|
||||
export async function fetchSqlFileTargetOptions(connectionId: string, connection: NamespaceOptionsConnection): Promise<string[]> {
|
||||
return fetchNamespaceOptionsForConnection(connectionId, connection);
|
||||
}
|
||||
|
||||
export function useDatabaseOptions() {
|
||||
const connectionStore = useConnectionStore();
|
||||
|
||||
|
||||
Reference in new issue
Block a user