fix(saved-sql): 修复 SQL 库连接关联丢失与历史文件不可见

* fix: 持久化并显示 SQL 库连接关联

* fix: 补充 SQL 库关联状态翻译

* chore: 修复数据标签页策略格式

---------

Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
This commit is contained in:
zipgandzipg authored and GitHub committed 2026-08-05 23:58:32 +08:00
1 parent 580b70e1d4
commit 445b6473f4
18 files changed
+336 -115

No files matched your search

+29 -8
View File
@@ -103,6 +103,10 @@ interface OpenSavedSqlOptions {
targetMode?: SavedSqlOpenTargetMode;
}
interface UpdateExecutionTargetOptions {
persistSavedSqlTarget?: boolean;
}
type DroppedTableObjectType = "TABLE" | "VIEW" | "MATERIALIZED_VIEW";
interface DroppedTableObjectTarget {
@@ -2568,12 +2572,13 @@ export const useQueryStore = defineStore("query", () => {
}
function applySavedSqlExecutionTarget(tab: QueryTab, target: SavedSqlExecutionTarget) {
updateConnection(tab.id, target.connectionId, target.database);
const options = { persistSavedSqlTarget: false };
updateConnection(tab.id, target.connectionId, target.database, options);
if (tab.catalog !== target.catalog || tab.database !== target.database) {
if (tab.catalog !== undefined || target.catalog !== undefined) updateCatalog(tab.id, target.catalog, target.database);
else updateDatabase(tab.id, target.database);
if (tab.catalog !== undefined || target.catalog !== undefined) updateCatalog(tab.id, target.catalog, target.database, options);
else updateDatabase(tab.id, target.database, options);
}
updateSchema(tab.id, target.schema);
updateSchema(tab.id, target.schema, options);
}
function openSavedSql(file: SavedSqlFile, options: OpenSavedSqlOptions = {}) {
@@ -2653,7 +2658,19 @@ export const useQueryStore = defineStore("query", () => {
tabs.value = orderPinnedFirst(tabs.value, (item) => !!item.pinned);
}
function updateDatabase(id: string, database: string) {
function persistSavedSqlExecutionTarget(tab: QueryTab, options: UpdateExecutionTargetOptions) {
if (options.persistSavedSqlTarget === false || tab.mode !== "query" || !tab.savedSqlId) return;
const savedSqlStore = useSavedSqlStore();
void savedSqlStore
.updateFileExecutionTarget(tab.savedSqlId, {
connectionId: tab.connectionId,
database: tab.database,
schema: tab.schema,
})
.catch((error) => console.warn("[DBX][saved-sql:target:error]", error));
}
function updateDatabase(id: string, database: string, options: UpdateExecutionTargetOptions = {}) {
const tab = tabs.value.find((t) => t.id === id);
if (!tab || tab.database === database) return;
rollbackTabTransaction(tab);
@@ -2668,9 +2685,10 @@ export const useQueryStore = defineStore("query", () => {
tab.resultSortedSql = undefined;
clearExplain(tab);
tab.tableMeta = undefined;
persistSavedSqlExecutionTarget(tab, options);
}
function updateCatalog(id: string, catalog: string | undefined, database: string) {
function updateCatalog(id: string, catalog: string | undefined, database: string, options: UpdateExecutionTargetOptions = {}) {
const tab = tabs.value.find((candidate) => candidate.id === id);
if (!tab || (tab.catalog === catalog && tab.database === database)) return;
rollbackTabTransaction(tab);
@@ -2686,9 +2704,10 @@ export const useQueryStore = defineStore("query", () => {
tab.resultSortedSql = undefined;
clearExplain(tab);
tab.tableMeta = undefined;
persistSavedSqlExecutionTarget(tab, options);
}
function updateSchema(id: string, schema: string | undefined) {
function updateSchema(id: string, schema: string | undefined, options: UpdateExecutionTargetOptions = {}) {
const tab = tabs.value.find((t) => t.id === id);
if (!tab || tab.schema === schema) return;
rollbackTabTransaction(tab);
@@ -2703,9 +2722,10 @@ export const useQueryStore = defineStore("query", () => {
}
tab.schema = schema;
if (tab.mode === "objects") tab.objectBrowser = { ...tab.objectBrowser, schema, viewport: undefined };
persistSavedSqlExecutionTarget(tab, options);
}
function updateConnection(id: string, connectionId: string, database = "") {
function updateConnection(id: string, connectionId: string, database = "", options: UpdateExecutionTargetOptions = {}) {
const tab = tabs.value.find((t) => t.id === id);
if (!tab || tab.connectionId === connectionId) return;
rollbackTabTransaction(tab, { resetAutoCommit: true });
@@ -2723,6 +2743,7 @@ export const useQueryStore = defineStore("query", () => {
tab.resultSortedSql = undefined;
clearExplain(tab);
tab.tableMeta = undefined;
persistSavedSqlExecutionTarget(tab, options);
}
function clearInvalidDataTabSortState(tab: QueryTab, columns: NonNullable<QueryTab["tableMeta"]>["columns"]): boolean {
+83 -5
View File
@@ -25,6 +25,12 @@ interface SaveFileInput {
sql: string;
}
interface SavedSqlExecutionTargetInput {
connectionId: string;
database: string;
schema?: string;
}
function nowIso() {
return new Date().toISOString();
}
@@ -95,6 +101,9 @@ export const useSavedSqlStore = defineStore("savedSql", () => {
let pendingSync: Promise<void> | null = null;
let initFromStoragePromise: Promise<void> | null = null;
const pendingFolderCreates = new Map<string, Promise<SavedSqlFolder>>();
const fileTargetRevisions = new Map<string, number>();
const pendingFileTargetSaves = new Map<string, Promise<SavedSqlFile | undefined>>();
const persistedFileTargets = new Map<string, SavedSqlExecutionTargetInput & { updatedAt: string }>();
const version = ref(0);
function bumpVersion() {
@@ -256,6 +265,79 @@ export const useSavedSqlStore = defineStore("savedSql", () => {
return saved;
}
function updateFileExecutionTarget(id: string, target: SavedSqlExecutionTargetInput): Promise<SavedSqlFile | undefined> {
const existing = getFile(id);
if (!existing) return Promise.resolve(undefined);
if (existing.connectionId === target.connectionId && existing.database === target.database && existing.schema === target.schema) {
return Promise.resolve(existing);
}
if (!persistedFileTargets.has(id)) {
persistedFileTargets.set(id, {
connectionId: existing.connectionId,
database: existing.database,
schema: existing.schema,
updatedAt: existing.updatedAt,
});
}
const revision = (fileTargetRevisions.get(id) ?? 0) + 1;
fileTargetRevisions.set(id, revision);
files.value = files.value.map((file) => (file.id === id ? { ...file, ...target, updatedAt: nowIso() } : file));
bumpVersion();
const previousSave = pendingFileTargetSaves.get(id) ?? Promise.resolve(undefined);
const save = previousSave
.catch(() => undefined)
.then(async () => {
if (fileTargetRevisions.get(id) !== revision) return getFile(id);
const loaded = await ensureFileContent(id);
if (!loaded || fileTargetRevisions.get(id) !== revision) return getFile(id);
const candidate: SavedSqlFile = {
...loaded,
...target,
sqlLoaded: true,
updatedAt: nowIso(),
};
files.value = files.value.map((file) => (file.id === id ? candidate : file));
bumpVersion();
try {
const saved = await api.saveSavedSqlFile(candidate);
persistedFileTargets.set(id, {
connectionId: saved.connectionId,
database: saved.database,
schema: saved.schema,
updatedAt: saved.updatedAt,
});
if (fileTargetRevisions.get(id) !== revision) return getFile(id);
const current = getFile(id);
const persisted = { ...saved, sql: current?.sql ?? saved.sql, sqlLoaded: current?.sqlLoaded ?? true };
files.value = files.value.map((file) => (file.id === id ? persisted : file));
bumpVersion();
await syncToLocalDirectory();
return persisted;
} catch (error) {
if (fileTargetRevisions.get(id) === revision) {
const persistedTarget = persistedFileTargets.get(id);
if (persistedTarget) files.value = files.value.map((file) => (file.id === id ? { ...file, ...persistedTarget } : file));
bumpVersion();
}
throw error;
}
});
pendingFileTargetSaves.set(id, save);
const cleanup = () => {
if (pendingFileTargetSaves.get(id) !== save) return;
pendingFileTargetSaves.delete(id);
persistedFileTargets.delete(id);
};
void save.then(cleanup, cleanup);
return save;
}
async function renameFile(id: string, name: string) {
const existing = getFile(id);
if (!existing) return;
@@ -555,10 +637,6 @@ export const useSavedSqlStore = defineStore("savedSql", () => {
return allFiles.value.filter((f) => !f.folderId);
}
function orphanedFileIds(activeConnectionIds: Set<string>) {
return new Set(files.value.filter((f) => !activeConnectionIds.has(f.connectionId)).map((f) => f.id));
}
return {
folders,
files,
@@ -574,6 +652,7 @@ export const useSavedSqlStore = defineStore("savedSql", () => {
renameFolder,
deleteFolder,
saveFile,
updateFileExecutionTarget,
renameFile,
recordFileUsage,
deleteFile,
@@ -588,6 +667,5 @@ export const useSavedSqlStore = defineStore("savedSql", () => {
allFiles,
filesInFolder,
filesWithoutFolder,
orphanedFileIds,
};
});