🐛 fix(sql-editor): 修复对象跳转卡死与过程模板缺失CREATE

- 跳过大 SQL 的全局对象装饰扫描,避免 Ctrl/Cmd 点击对象时读取整篇编辑器文本

- 存储过程和函数源码片段缺少 CREATE 时自动补 CREATE OR REPLACE

- 增加过程修改模板与大 SQL 对象跳转回归测试
This commit is contained in:
Syngnat
2026-06-04 16:05:40 +08:00
parent 8f7c790700
commit f7217583a3
4 changed files with 129 additions and 2 deletions

View File

@@ -747,6 +747,59 @@ describe('QueryEditor external SQL save', () => {
expect(stopPropagation).toHaveBeenCalled();
});
it('does not read the full editor model when ctrl/cmd clicking objects in large SQL', async () => {
editorState.value = [
...Array.from({ length: 4000 }, (_, index) => `-- filler ${index + 1}`),
'select * from analytics.events where id = 1',
].join('\n');
autoFetchState.visible = true;
backendApp.DBGetDatabases.mockResolvedValueOnce({ success: true, data: [{ Database: 'main' }, { Database: 'analytics' }] });
backendApp.DBGetTables
.mockResolvedValueOnce({ success: true, data: [{ Tables_in_main: 'users' }] })
.mockResolvedValueOnce({ success: true, data: [{ Tables_in_analytics: 'events' }] });
backendApp.DBGetAllColumns
.mockResolvedValueOnce({ success: true, data: [] })
.mockResolvedValueOnce({ success: true, data: [] });
await act(async () => {
create(<QueryEditor tab={createTab({ query: editorState.value, dbName: 'main' })} />);
});
await act(async () => {
await Promise.resolve();
await Promise.resolve();
});
editorState.editor.getModel().getValue.mockClear();
editorState.editor.getModel().getValueLength.mockClear();
const lineNumber = editorState.value.split('\n').length;
const preventDefault = vi.fn();
const stopPropagation = vi.fn();
await act(async () => {
editorState.mouseDownListeners[0]?.({
target: { position: { lineNumber, column: 27 } },
event: {
browserEvent: { button: 0, buttons: 1 },
ctrlKey: true,
metaKey: false,
preventDefault,
stopPropagation,
},
});
});
expect(editorState.editor.getModel().getValueLength).not.toHaveBeenCalled();
expect(editorState.editor.getModel().getValue).not.toHaveBeenCalled();
expect(storeState.addTab).toHaveBeenCalledWith(expect.objectContaining({
type: 'table',
connectionId: 'conn-1',
dbName: 'analytics',
tableName: 'events',
}));
expect(preventDefault).toHaveBeenCalled();
expect(stopPropagation).toHaveBeenCalled();
});
it('shows link-style hover feedback when ctrl/cmd is pressed over a navigable identifier', async () => {
editorState.value = 'select * from analytics.events where id = 1';
autoFetchState.visible = true;