🐛 fix(sql-editor): 修复新建查询关闭应用未提示保存

This commit is contained in:
Syngnat
2026-06-29 13:02:23 +08:00
parent 3a471bc1aa
commit ded531a3c2
2 changed files with 79 additions and 6 deletions

View File

@@ -57,7 +57,7 @@ describe('sqlEditorApplicationQuit', () => {
})]);
});
it('collects dirty saved-query tabs and ignores unnamed temporary query tabs', async () => {
it('collects dirty saved-query tabs and unnamed temporary query tabs', async () => {
const savedQuery = createSavedQuery();
const savedTab = createQueryTab({
id: 'tab-2',
@@ -75,7 +75,7 @@ describe('sqlEditorApplicationQuit', () => {
const targets = await collectApplicationQuitUnsavedSQLTargets([savedTab, unnamedTab], [savedQuery], vi.fn());
expect(targets).toHaveLength(1);
expect(targets).toHaveLength(2);
expect(targets[0]).toMatchObject({
kind: 'saved-query',
tabId: 'tab-2',
@@ -84,9 +84,30 @@ describe('sqlEditorApplicationQuit', () => {
connectionId: 'conn-1',
dbName: 'main',
});
expect(targets[1]).toMatchObject({
kind: 'unsaved-query',
tabId: 'tab-3',
title: 'New query',
draft: 'select * from draft_only;',
connectionId: 'conn-1',
dbName: 'main',
});
});
it('saves external SQL files and existing saved queries before application quit', async () => {
it('ignores blank unnamed temporary query tabs', async () => {
const unnamedTab = createQueryTab({
id: 'tab-3',
title: 'New query',
query: '',
});
setQueryTabDraft('tab-3', ' ');
const targets = await collectApplicationQuitUnsavedSQLTargets([unnamedTab], [], vi.fn());
expect(targets).toEqual([]);
});
it('saves external SQL files, existing saved queries, and unnamed query drafts before application quit', async () => {
const saveQuery = vi.fn(async (query: SavedQuery) => query);
const writeSQLFile = vi.fn(async () => ({ success: true }));
@@ -107,6 +128,14 @@ describe('sqlEditorApplicationQuit', () => {
connectionId: 'conn-2',
dbName: 'reporting',
},
{
kind: 'unsaved-query',
tabId: 'tab-3',
title: 'New query',
draft: 'select 3;',
connectionId: 'conn-3',
dbName: 'scratch',
},
], saveQuery, writeSQLFile);
expect(writeSQLFile).toHaveBeenCalledWith('/tmp/file.sql', 'select 1;');
@@ -116,5 +145,11 @@ describe('sqlEditorApplicationQuit', () => {
connectionId: 'conn-2',
dbName: 'reporting',
}));
expect(saveQuery).toHaveBeenCalledWith(expect.objectContaining({
name: 'New query',
sql: 'select 3;',
connectionId: 'conn-3',
dbName: 'scratch',
}));
});
});

View File

@@ -31,6 +31,14 @@ export type ApplicationQuitUnsavedSQLTarget =
draft: string;
connectionId: string;
dbName: string;
}
| {
kind: 'unsaved-query';
tabId: string;
title: string;
draft: string;
connectionId: string;
dbName: string;
};
export type ReadSQLFileForQuit = (filePath: string) => Promise<QueryResultLike>;
@@ -64,6 +72,13 @@ const hasSavedQueryUnsavedChanges = (
|| dbName !== toTrimmedString(savedQuery.dbName);
};
let applicationQuitSavedQueryIdSeed = 0;
const createApplicationQuitSavedQueryId = (): string => {
applicationQuitSavedQueryIdSeed += 1;
return `saved-${Date.now()}-${applicationQuitSavedQueryIdSeed}`;
};
export const buildApplicationQuitUnsavedSQLLabel = (
targets: ApplicationQuitUnsavedSQLTarget[],
): string => {
@@ -105,9 +120,20 @@ export const collectApplicationQuitUnsavedSQLTargets = async (
continue;
}
const savedQuery = resolveSavedQueryForTab(tab, savedQueries);
if (!savedQuery) continue;
const draft = getQueryTabDraft(tab.id, String(tab.query ?? ''));
const savedQuery = resolveSavedQueryForTab(tab, savedQueries);
if (!savedQuery) {
if (!draft.trim()) continue;
targets.push({
kind: 'unsaved-query',
tabId: tab.id,
title: resolveTabTitle(tab, 'SQL Query'),
draft,
connectionId: toTrimmedString(tab.connectionId),
dbName: toTrimmedString(tab.dbName),
});
continue;
}
if (!hasSavedQueryUnsavedChanges(tab, savedQuery, draft)) continue;
targets.push({
kind: 'saved-query',
@@ -137,11 +163,23 @@ export const saveApplicationQuitUnsavedSQLTargets = async (
continue;
}
if (target.kind === 'saved-query') {
await saveQuery({
...target.savedQuery,
sql: target.draft,
connectionId: target.connectionId,
dbName: target.dbName,
});
continue;
}
await saveQuery({
...target.savedQuery,
id: createApplicationQuitSavedQueryId(),
name: target.title,
sql: target.draft,
connectionId: target.connectionId,
dbName: target.dbName,
createdAt: Date.now(),
});
}
};