fix(sql): preserve file associations and list selection

This commit is contained in:
zipg authored and GitHub committed 2026-08-13 11:44:55 +08:00
1 parent 2e27f7a66a
commit e5a3917f7d
25 files changed
+558 -186

No files matched your search

+27 -21
View File
@@ -58,7 +58,7 @@ import { uuid } from "@/lib/common/utils";
import { isMacOS, isWindows } from "@/lib/backend/platform";
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
import { openQueryResultArchiveFile } from "@/lib/query/queryResultArchiveFile";
import { rememberExternalSqlFileTarget, resolveExternalSqlFileTarget } from "@/lib/sql/externalSqlFileTarget";
import { rememberExternalSqlFileTarget, resolveExternalSqlFileTarget, unassociatedExternalSqlFileTarget } from "@/lib/sql/externalSqlFileTarget";
import { externalSqlFileOpenErrorMessage, readBrowserSqlFile, sqlFileTitleFromPath } from "@/lib/sql/sqlFileOpen";
import type { ConnectionConfig, DatabaseType, ObjectSourceKind, QueryTab } from "@/types/database";
import { parseConnectionDeepLink, type ConnectionDeepLinkDraft } from "@/lib/connection/connectionDeepLink";
@@ -1015,7 +1015,7 @@ async function writeExternalSqlTab(tab: QueryTab, options: { closeAfterSave?: bo
expectedMissing: options.expectedMissing,
});
if (result.kind !== "written") return "retry";
rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId: tab.connectionId, database: tab.database });
rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId: tab.connectionId, database: tab.database, catalog: tab.catalog });
queryStore.markExternalSqlFileSaved(tab.id, result.version);
toast(t("savedSql.saved"), 2000);
if (options.closeAfterSave) queryStore.closeTab(tab.id, { force: true });
@@ -1080,6 +1080,7 @@ async function saveTabForCloseAll(tabId: string): Promise<boolean> {
folderId: existing?.folderId,
name: existing?.name || defaultSavedSqlName(tab.title),
database: target.database,
catalog: target.catalog,
schema: target.schema,
sql: tab.sql,
});
@@ -1146,6 +1147,7 @@ async function handleSaveTab(tabId: string) {
folderId: existing.folderId,
name: existing.name,
database: target.database,
catalog: target.catalog,
schema: target.schema,
sql: tab.sql,
});
@@ -1182,6 +1184,7 @@ async function openSaveSqlDialog() {
folderId: existing.folderId,
name: existing.name,
database: target.database,
catalog: target.catalog,
schema: target.schema,
sql: tab.sql,
});
@@ -1277,6 +1280,7 @@ async function confirmSaveSqlToLibrary() {
folderId: saveSqlFolderId.value === ROOT_SAVED_SQL_FOLDER ? undefined : saveSqlFolderId.value,
name: defaultSavedSqlName(name),
database: target.database,
catalog: target.catalog,
schema: target.schema,
sql: tab.sql,
});
@@ -1296,7 +1300,7 @@ async function saveExternalSqlTabAs(tab: QueryTab): Promise<boolean> {
const saved = await api.saveExternalSqlFile(defaultSavedSqlName(tab.title), tab.sql);
if (!saved) return false;
queryStore.linkExternalSqlPath(tab.id, saved.path, sqlFileTitleFromPath(saved.path), saved.version);
rememberExternalSqlFileTarget(saved.path, { connectionId: tab.connectionId, database: tab.database });
rememberExternalSqlFileTarget(saved.path, { connectionId: tab.connectionId, database: tab.database, catalog: tab.catalog });
invalidateSaveSqlFolderSelection();
showSaveSqlDialog.value = false;
closePendingSavedTab();
@@ -1314,14 +1318,13 @@ async function saveActiveSqlAsLocalFile() {
}
function applyExternalSqlFileTarget(tab: QueryTab, path: string) {
const target = resolveExternalSqlFileTarget(path, (savedConnectionId) => !!connectionStore.getConfig(savedConnectionId), {
connectionId: tab.connectionId,
database: tab.database,
});
const target = resolveExternalSqlFileTarget(path, (savedConnectionId) => !!connectionStore.getConfig(savedConnectionId), unassociatedExternalSqlFileTarget());
if (target.connectionId !== tab.connectionId) {
queryStore.updateConnection(tab.id, target.connectionId, target.database);
} else if (target.database !== tab.database) {
queryStore.updateDatabase(tab.id, target.database);
}
if (target.catalog !== tab.catalog || target.database !== tab.database) {
if (target.catalog !== undefined || tab.catalog !== undefined) queryStore.updateCatalog(tab.id, target.catalog, target.database);
else queryStore.updateDatabase(tab.id, target.database);
}
}
@@ -1392,11 +1395,8 @@ async function openSqlFilePath(path: string) {
try {
await desktopOpenTabsRestorationBarrier?.settled;
const snapshot = await api.readExternalSqlFileSnapshot(path);
const connectionId = connectionStore.activeConnectionId || activeTab.value?.connectionId || connectionStore.connections[0]?.id || "";
const connection = connectionId ? connectionStore.getConfig(connectionId) : undefined;
const database = activeTab.value?.database || (connection ? resolveDefaultDatabase(connection, []) : "");
const target = resolveExternalSqlFileTarget(path, (savedConnectionId) => !!connectionStore.getConfig(savedConnectionId), { connectionId, database });
queryStore.openExternalSqlFile(target.connectionId, target.database, path, snapshot.content, snapshot.version);
const target = resolveExternalSqlFileTarget(path, (savedConnectionId) => !!connectionStore.getConfig(savedConnectionId), unassociatedExternalSqlFileTarget());
queryStore.openExternalSqlFile(target.connectionId, target.database, path, snapshot.content, snapshot.version, target.catalog);
} catch (e: any) {
toast(t("toolbar.sqlOpenFailed", { message: externalSqlFileOpenErrorMessage(e, (key, params) => t(key, params)) }), 5000);
}
@@ -1647,7 +1647,8 @@ async function openSavedSqlFromWelcome(fileId: string) {
const file = await savedSqlStore.ensureFileContent(fileId);
if (!file) return;
const tabId = queryStore.openSavedSql(file);
connectionStore.activeConnectionId = queryStore.tabs.find((tab) => tab.id === tabId)?.connectionId ?? file.connectionId;
const openedConnectionId = queryStore.tabs.find((tab) => tab.id === tabId)?.connectionId ?? file.connectionId;
if (openedConnectionId) connectionStore.activeConnectionId = openedConnectionId;
void savedSqlStore.recordFileUsage(file.id);
toast(t("welcome.fileOpened", { name: file.name }), 2000);
}
@@ -1817,13 +1818,16 @@ async function changeActiveConnection(connectionId: string) {
if (!tab) return;
const connection = connectionStore.getConfig(connectionId);
if (!connection) return;
queryStore.updateConnection(tab.id, connectionId, resolveDefaultDatabase(connection, []));
const initialDatabase = resolveDefaultDatabase(connection, []);
queryStore.updateConnection(tab.id, connectionId, initialDatabase);
if (tab.externalSqlPath) rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId, database: initialDatabase, catalog: undefined });
connectionStore.activeConnectionId = connectionId;
try {
await connectionStore.ensureConnected(connectionId);
const options = await getDatabaseOptions(connectionId);
const database = resolveDefaultDatabase(connection, options);
queryStore.updateDatabase(tab.id, database);
if (tab.externalSqlPath) rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId, database, catalog: undefined });
if (connection.default_schema || connection.db_type === "oracle") {
try {
// A configured default wins. Otherwise Oracle returns the session's current schema first.
@@ -1850,6 +1854,7 @@ function changeActiveDatabase(database: string) {
const tab = activeTab.value;
if (tab) {
queryStore.updateDatabase(tab.id, database);
if (tab.externalSqlPath) rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId: tab.connectionId, database, catalog: tab.catalog });
if (databaseRequiredTabId.value === tab.id && database) {
databaseRequiredTabId.value = null;
}
@@ -1858,7 +1863,10 @@ function changeActiveDatabase(database: string) {
function changeActiveCatalog(catalog: string | undefined, database: string) {
const tab = activeTab.value;
if (tab) queryStore.updateCatalog(tab.id, catalog, database);
if (tab) {
queryStore.updateCatalog(tab.id, catalog, database);
if (tab.externalSqlPath) rememberExternalSqlFileTarget(tab.externalSqlPath, { connectionId: tab.connectionId, database, catalog });
}
}
async function setActiveDatabaseAsDefault() {
@@ -1987,10 +1995,8 @@ async function handleQuickOpenSelect(item: any) {
if (item.type === "sql_file" && item.filePath) {
try {
const snapshot = await api.readExternalSqlFileSnapshot(item.filePath);
const connectionId = connectionStore.activeConnectionId || connectionStore.connections[0]?.id || "";
const connection = connectionId ? connectionStore.getConfig(connectionId) : undefined;
const database = connection ? resolveDefaultDatabase(connection, []) : "";
queryStore.openExternalSqlFile(connectionId, database, item.filePath, snapshot.content, snapshot.version);
const target = resolveExternalSqlFileTarget(item.filePath, (savedConnectionId) => !!connectionStore.getConfig(savedConnectionId), unassociatedExternalSqlFileTarget());
queryStore.openExternalSqlFile(target.connectionId, target.database, item.filePath, snapshot.content, snapshot.version, target.catalog);
} catch (e: any) {
toast(
externalSqlFileOpenErrorMessage(e, (key, params) => t(key, params)),