fix(tabs): reuse data tabs only for the same table
This commit is contained in:
16 files changed
+115
-23
No files matched your search
@@ -221,6 +221,10 @@ describe("query execution schema", () => {
|
||||
});
|
||||
|
||||
describe("object tree node schema", () => {
|
||||
it("ignores database-shaped schema metadata for MySQL tables", () => {
|
||||
expect(connectionObjectTreeNodeSchema({ db_type: "mysql" }, "app", "app")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("uses the SQLite database alias to qualify attached tables", () => {
|
||||
expect(connectionObjectTreeNodeSchema({ db_type: "sqlite" }, "analytics")).toBe("analytics");
|
||||
});
|
||||
|
||||
@@ -52,11 +52,11 @@ describe("dataTabOpenPolicy", () => {
|
||||
const existing = dataTab("users", "users");
|
||||
existing.tableMeta = { schema: "public", tableName: "users", columns: [], primaryKeys: [] };
|
||||
|
||||
expect(findExistingDataTabCandidate([existing], usersTarget, { openMode: "new-tab", reuseScope: "database" })).toBeUndefined();
|
||||
expect(findExistingDataTabCandidate([existing], usersTarget, { openMode: "new-tab", reuseScope: "same-table" })).toBeUndefined();
|
||||
expect(findExistingDataTabCandidate([existing], usersTarget, { openMode: "new-tab", reuseScope: "none" })).toBeUndefined();
|
||||
});
|
||||
|
||||
it("applies none, same-table, and database reuse scopes independently", () => {
|
||||
it("only reuses the same table when reuse is enabled", () => {
|
||||
const sameTable = dataTab("users", "users");
|
||||
sameTable.tableMeta = { schema: "public", tableName: "users", columns: [], primaryKeys: [] };
|
||||
const otherTable = dataTab("orders", "orders");
|
||||
@@ -64,7 +64,13 @@ describe("dataTabOpenPolicy", () => {
|
||||
expect(findExistingDataTabCandidate([sameTable], usersTarget, { openMode: "default", reuseScope: "none" })).toBeUndefined();
|
||||
expect(findExistingDataTabCandidate([sameTable], usersTarget, { openMode: "default", reuseScope: "same-table" })).toEqual({ tab: sameTable, match: "same-table" });
|
||||
expect(findExistingDataTabCandidate([otherTable], usersTarget, { openMode: "default", reuseScope: "same-table" })).toBeUndefined();
|
||||
expect(findExistingDataTabCandidate([otherTable], usersTarget, { openMode: "default", reuseScope: "database" })).toEqual({ tab: otherTable, match: "database" });
|
||||
});
|
||||
|
||||
it("does not reuse a same-name table from another schema", () => {
|
||||
const archiveUsers = dataTab("archive-users", "users", "archive");
|
||||
archiveUsers.tableMeta = { schema: "archive", tableName: "users", columns: [], primaryKeys: [] };
|
||||
|
||||
expect(findExistingDataTabCandidate([archiveUsers], usersTarget, { openMode: "default", reuseScope: "same-table" })).toBeUndefined();
|
||||
});
|
||||
|
||||
it("allows metadata to update a tab that still points to the requested table", () => {
|
||||
|
||||
@@ -175,11 +175,11 @@ export function metadataSchemaForConnection(connection: JdbcDialectConnection |
|
||||
export function connectionObjectTreeNodeSchema(connection: JdbcDialectConnection | undefined, database: string, schema?: string): string | undefined {
|
||||
if (connection?.db_type === "jdbc" && inferJdbcDialect(connection) === "databend") return schema || database;
|
||||
if (connectionUsesDatabaseObjectTreeMode(connection)) return undefined;
|
||||
if (schema) return schema;
|
||||
const type = effectiveDatabaseTypeForConnection(connection);
|
||||
if (type === "informix") return undefined;
|
||||
if (type === "sqlite") return database;
|
||||
return isSchemaAware(type) ? database : undefined;
|
||||
if (type === "informix") return schema || undefined;
|
||||
if (type === "sqlite") return schema || database;
|
||||
if (!type) return schema;
|
||||
return isSchemaAware(type) ? schema || database : undefined;
|
||||
}
|
||||
|
||||
/** Maps a database type to the corresponding CodeMirror SQL dialect name used by QueryEditor and DdlViewDialog. */
|
||||
|
||||
@@ -2,7 +2,7 @@ import { matchesModifierOnlyShortcut, type ShortcutLikeEvent } from "@/lib/edito
|
||||
import type { QueryTab, TreeNodeType } from "@/types/database";
|
||||
|
||||
export type DataTabOpenMode = "default" | "new-tab";
|
||||
export type DataTabReuseScope = "none" | "same-table" | "database";
|
||||
export type DataTabReuseScope = "none" | "same-table";
|
||||
|
||||
type DataTabLike = Pick<QueryTab, "id" | "mode" | "connectionId" | "database" | "schema" | "title" | "tableMeta" | "tableMetaUpdatedAt">;
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface DataTabTarget {
|
||||
|
||||
export type ExistingDataTabCandidate<T extends DataTabLike> = {
|
||||
tab: T;
|
||||
match: "same-table" | "database";
|
||||
match: "same-table";
|
||||
};
|
||||
|
||||
const dataNodeTypes = new Set<TreeNodeType>(["table", "view", "materialized_view"]);
|
||||
@@ -53,8 +53,5 @@ export function findExistingDataTabCandidate<T extends DataTabLike>(tabs: T[], t
|
||||
|
||||
const sameTable = tabs.find((tab) => isSameTable(tab, target));
|
||||
if (sameTable) return { tab: sameTable, match: "same-table" };
|
||||
if (options.reuseScope === "same-table") return undefined;
|
||||
|
||||
const sameDatabase = tabs.find((tab) => isSameDatabase(tab, target));
|
||||
return sameDatabase ? { tab: sameDatabase, match: "database" } : undefined;
|
||||
return undefined;
|
||||
}
|
||||
Reference in new issue
Block a user