mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-30 00:19:35 +00:00
feat(app): open sql files in editor
This commit is contained in:
+31
-1
@@ -36,6 +36,7 @@ import { resolveDefaultDatabase } from "@/lib/defaultDatabase";
|
||||
import { buildExecutableObjectSourceSql, objectSourceSaveExecutionMode } from "@/lib/objectSourceEditor";
|
||||
import { resolveExecutableSql } from "@/lib/sqlExecutionTarget";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
import { sqlFileTitleFromPath } from "@/lib/sqlFileOpen";
|
||||
import {
|
||||
isCloseTabShortcut,
|
||||
isExecuteSqlShortcut,
|
||||
@@ -152,7 +153,7 @@ const { getDatabaseOptions } = useDatabaseOptions();
|
||||
const { openLineageTarget, openDatabaseSearchTarget, onStructureEditorSaved, openTableTarget } =
|
||||
useNavigationTargets(dialogs);
|
||||
const { onExecuteSql, onReloadData, onPaginate, onSort } = useDataGridActions(activeTab);
|
||||
const { setupTauriListeners, cleanupTauriListeners } = useTauriEvents({ openTableTarget });
|
||||
const { setupTauriListeners, cleanupTauriListeners } = useTauriEvents({ openTableTarget, openSqlFilePath });
|
||||
|
||||
const appVersion = ref("");
|
||||
const isClassicLayout = computed(() => settingsStore.editorSettings.appLayout === "classic");
|
||||
@@ -341,6 +342,34 @@ async function openSqlFile() {
|
||||
}
|
||||
}
|
||||
|
||||
async function openSqlFilePath(path: string) {
|
||||
if (!isTauriRuntime()) return;
|
||||
try {
|
||||
const { readTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
const content = await readTextFile(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 tabId = queryStore.createTab(connectionId, database, sqlFileTitleFromPath(path), "query");
|
||||
queryStore.updateSql(tabId, content);
|
||||
} catch (e: any) {
|
||||
toast(t("toolbar.sqlOpenFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async function openPendingSqlFiles() {
|
||||
if (!isTauriRuntime()) return;
|
||||
try {
|
||||
const paths = await api.pendingOpenSqlFiles();
|
||||
for (const path of paths) {
|
||||
await openSqlFilePath(path);
|
||||
}
|
||||
} catch {
|
||||
/* ignore startup file-open probing errors */
|
||||
}
|
||||
}
|
||||
|
||||
async function newQuery() {
|
||||
const connId = connectionStore.activeConnectionId || connectionStore.connections[0]?.id;
|
||||
if (!connId) return;
|
||||
@@ -614,6 +643,7 @@ onMounted(async () => {
|
||||
})
|
||||
.catch(() => {});
|
||||
setupTauriListeners();
|
||||
void openPendingSqlFiles();
|
||||
console.log(`[STARTUP] onMounted sync done: ${(performance.now() - mountStart).toFixed(0)}ms`);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@ import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import type { NavigationTarget } from "@/composables/useNavigationTargets";
|
||||
|
||||
export function useTauriEvents(deps: { openTableTarget: (target: NavigationTarget) => Promise<void> }) {
|
||||
export function useTauriEvents(deps: {
|
||||
openTableTarget: (target: NavigationTarget) => Promise<void>;
|
||||
openSqlFilePath: (path: string) => Promise<void>;
|
||||
}) {
|
||||
const connectionStore = useConnectionStore();
|
||||
const queryStore = useQueryStore();
|
||||
const unlistenHandles: Array<() => void> = [];
|
||||
@@ -66,6 +69,21 @@ export function useTauriEvents(deps: { openTableTarget: (target: NavigationTarge
|
||||
console.error("[DBX] mcp-execute-query error:", e);
|
||||
}
|
||||
}).then((unlisten) => unlistenHandles.push(unlisten));
|
||||
|
||||
listen<string[]>("dbx-open-sql-files", async (event) => {
|
||||
try {
|
||||
for (const path of event.payload) {
|
||||
await deps.openSqlFilePath(path);
|
||||
}
|
||||
import("@tauri-apps/api/window").then(({ getCurrentWindow }) =>
|
||||
getCurrentWindow()
|
||||
.setFocus()
|
||||
.catch(() => {}),
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("[DBX] dbx-open-sql-files error:", e);
|
||||
}
|
||||
}).then((unlisten) => unlistenHandles.push(unlisten));
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ export const previewSqlFile = forward("previewSqlFile");
|
||||
export const executeSqlFile = forward("executeSqlFile");
|
||||
export const cancelSqlFileExecution = forward("cancelSqlFileExecution");
|
||||
export const listenSqlFileProgress = forward("listenSqlFileProgress");
|
||||
export const pendingOpenSqlFiles = forward("pendingOpenSqlFiles");
|
||||
|
||||
// Data Transfer
|
||||
export const startTransfer = forward("startTransfer");
|
||||
|
||||
@@ -416,6 +416,10 @@ export async function listenSqlFileProgress(_handler: (progress: SqlFileProgress
|
||||
return () => {};
|
||||
}
|
||||
|
||||
export async function pendingOpenSqlFiles(): Promise<string[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Data Transfer
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
export function isSqlFilePath(path: string): boolean {
|
||||
return /\.sql$/i.test(path.trim());
|
||||
}
|
||||
|
||||
export function sqlFileTitleFromPath(path: string): string {
|
||||
const trimmed = path.trim();
|
||||
const normalized = trimmed.replace(/\\/g, "/");
|
||||
const name = normalized.split("/").filter(Boolean).pop();
|
||||
return name || "script.sql";
|
||||
}
|
||||
|
||||
export function externalSqlFilePaths(paths: string[]): string[] {
|
||||
return paths.filter(isSqlFilePath);
|
||||
}
|
||||
@@ -80,6 +80,10 @@ export async function loadAiConfig(): Promise<AiConfig | null> {
|
||||
return invoke("load_ai_config");
|
||||
}
|
||||
|
||||
export async function pendingOpenSqlFiles(): Promise<string[]> {
|
||||
return invoke("pending_open_sql_files");
|
||||
}
|
||||
|
||||
// --- AI Conversations ---
|
||||
|
||||
export interface AiChatMessage {
|
||||
|
||||
Reference in New Issue
Block a user