Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/components/layout/__tests__/useConnectionSwitching.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,29 @@ describe("editor tab and selected connection agree (#788)", () => {
expect(activeTab()?.connectionId).toBe("sqlite-1");
expect(useEditorStore.getState().tabs.find((t) => t.id === "tab-0")?.connectionId).toBe("dev");
});

it("drops the old server's profile from a tab a SQLite file takes over (#962)", () => {
// The tab's server is gone, so the file takes the tab rather than a new one.
setConnections([], null);
const { result } = renderHook(() => useConnectionSwitching());
useSqliteStore.setState({ sessions: [{ id: "sqlite-1", path: "data.db" } as unknown as SqliteSession] });

act(() => result.current.attachSqliteSession("sqlite-1"));

expect(activeTab()?.id).toBe("tab-0");
expect(activeTab()?.connectionId).toBe("sqlite-1");
// Kept, it would reconnect p-dev and bind the tab back to it at the next start.
expect(activeTab()?.profileId).toBeUndefined();
});

it("replaces the old server's profile on a tab a new server takes over", () => {
setConnections([], null);
const { result } = renderHook(() => useConnectionSwitching());
setConnections([prod], "prod");

act(() => result.current.attachNewConnection(prod));

expect(activeTab()?.id).toBe("tab-0");
expect(activeTab()?.profileId).toBe("p-prod");
});
});
5 changes: 4 additions & 1 deletion src/components/layout/useConnectionSwitching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ export function useConnectionSwitching() {
if (active && !activeHasServer) {
// Only a tab with no live server is taken over, so this does not
// normally move a session; through the guard all the same (#843).
requestTabConnection(active.id, connectionId, conn?.database ?? undefined, conn?.profile_id);
// A SQLite file has no profile. `null` drops the one the tab still has
// from the server it was on, which would otherwise send it back there
// at the next start (#962).
requestTabConnection(active.id, connectionId, conn?.database ?? undefined, conn?.profile_id ?? null);
return;
}
openTabFor(connectionId, conn);
Expand Down
4 changes: 3 additions & 1 deletion src/components/schema/SchemaTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ export function SchemaTree({ connectionId }: { connectionId: string }) {
const selectDatabase = (dbName: string) => {
if (!activeTabId) return;
const conn = activeConnections.find((c) => c.id === connectionId);
requestTabConnection(activeTabId, connectionId, dbName, conn?.profile_id);
// `null` for a tree with no profile (a SQLite file), so the tab does not
// keep the profile of the server it is moved from (#962).
requestTabConnection(activeTabId, connectionId, dbName, conn?.profile_id ?? null);
};

// Tracks pending single-click timers keyed by "db.name"
Expand Down
2 changes: 1 addition & 1 deletion src/stores/editorStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ interface EditorState {
* server where its transaction is open (#843). `setTabConnection` sets it
* unconditionally.
*/
requestTabConnection: (id: string, connectionId: string, database?: string, profileId?: string) => void;
requestTabConnection: (id: string, connectionId: string, database?: string, profileId?: string | null) => void;
setActiveTab: (id: string) => void;
updateTabContent: (id: string, content: string) => void;
/**
Expand Down
Loading