fix(remote): serve the database commands from the remote server (#1029)

A remote window sends a command to openidea-server only when the server registers it; none of the db_* commands were registered, so they ran locally, where a remote window has no project ("no project is open in this window"). The command bodies move from src-tauri into ide_host::ops::db, the Tauri commands become thin wrappers, and the remote dispatcher registers the same ops, with cancellation for execute / table page / explain. db_export_file stays local because exports are written on the user's machine.

Fixes #1019

Co-authored-by: a-rookie-of-C-language <[email protected]>
Цей коміт міститься в:
arookieofcтаa-rookie-of-C-language authored and GitHub committed 2026-11-04 00:03:38 +08:00
1 джерело 8e4c9f6f61
коміт f00ce451ac
5 files changed
+520 -184

No files matched your search

+6 -32
Переглянути файл
@@ -973,17 +973,8 @@ export const commands = {
proxyCheckConnection: (proxy: ProxySettings, url: string) => typedError<string, IdeError>(__TAURI_INVOKE("proxy_check_connection", { proxy, url })),
dbSources: () => typedError<DataSource[], IdeError>(__TAURI_INVOKE("db_sources")),
dbSaveSources: (sources: DataSource[]) => typedError<null, IdeError>(__TAURI_INVOKE("db_save_sources", { sources })),
/**
* Remembers the password of data source `id` for the session, and in the OS
* saved passwords when `save` (`None` forgets it).
*/
dbSetPassword: (id: string, password: string | null, save: boolean) => typedError<null, IdeError>(__TAURI_INVOKE("db_set_password", { id, password, save })),
/** Remembers the SSH password / key passphrase of a data source (see `db_set_password`). */
dbSetSshSecret: (id: string, secret: string | null, save: boolean) => typedError<null, IdeError>(__TAURI_INVOKE("db_set_ssh_secret", { id, secret, save })),
/**
* Trusts the SSH host key that made the last connection of `id` fail with
* "Unknown SSH host key" (records it in `~/.ssh/known_hosts`).
*/
dbTrustSshHost: (id: string) => typedError<null, IdeError>(__TAURI_INVOKE("db_trust_ssh_host", { id })),
/** Test Connection: connects with `config` as edited (not necessarily saved). */
sshTest: (config: SshConfiguration, secret: string | null) => typedError<string, IdeError>(__TAURI_INVOKE("ssh_test", { config, secret })),
@@ -1054,51 +1045,33 @@ export const commands = {
* (and the project's `remoteEnv` on a remote host); running ones keep theirs.
*/
envReload: () => typedError<EnvReloaded, IdeError>(__TAURI_INVOKE("env_reload")),
/** Test Connection: connects with unsaved settings and returns the server version. */
dbTest: (source: DataSource, password: string | null, sshSecret: string | null) => typedError<string, IdeError>(__TAURI_INVOKE("db_test", { source, password, sshSecret })),
dbConnected: () => typedError<string[], IdeError>(__TAURI_INVOKE("db_connected")),
/** Connects (fails with `permissionDenied` when the password is missing or wrong). */
dbConnect: (id: string) => typedError<null, IdeError>(__TAURI_INVOKE("db_connect", { id })),
dbDisconnect: (id: string) => typedError<null, IdeError>(__TAURI_INVOKE("db_disconnect", { id })),
/** Databases of the server of data source `id` (PostgreSQL); connect to one as `<id>:<database>`. */
dbDatabases: (id: string) => typedError<DbDatabases, IdeError>(__TAURI_INVOKE("db_databases", { id })),
dbSchemas: (id: string) => typedError<string[], IdeError>(__TAURI_INVOKE("db_schemas", { id })),
dbTables: (id: string, schema: string) => typedError<DbTableInfo[], IdeError>(__TAURI_INVOKE("db_tables", { id, schema })),
dbTableDetails: (id: string, schema: string, table: string) => typedError<DbTableDetails, IdeError>(__TAURI_INVOKE("db_table_details", { id, schema, table })),
/** The DDL of table or view `table` (Go to DDL, Generate DDL). */
dbDdl: (id: string, schema: string, table: string) => typedError<string, IdeError>(__TAURI_INVOKE("db_ddl", { id, schema, table })),
/** The routines and sequences of `schema` (the tree's `routines` / `sequences`). */
dbSchemaObjects: (id: string, schema: string) => typedError<DbSchemaObjects, IdeError>(__TAURI_INVOKE("db_schema_objects", { id, schema })),
/** The definition of a routine, trigger or sequence (Go to DDL, Quick Documentation). */
dbObjectDdl: (id: string, schema: string, kind: DbObjectKind, name: string) => typedError<string, IdeError>(__TAURI_INVOKE("db_object_ddl", { id, schema, kind, name })),
/** Explain Plan: the execution plan of `statement` on `id`, without running it. */
dbExplain: (request: RequestId, id: string, statement: string) => typedError<DbPlanNode[], IdeError>(__TAURI_INVOKE("db_explain", { request, id, statement })),
/** The statements data source `id` ran, newest first (Browse Query History). */
dbHistory: (id: string) => typedError<DbHistoryEntry[], IdeError>(__TAURI_INVOKE("db_history", { id })),
/** Removes statements from the query history of `id` (`None`: all of them). */
dbRemoveHistory: (id: string, texts: string[] | null) => typedError<null, IdeError>(__TAURI_INVOKE("db_remove_history", { id, texts })),
/** Tables, columns and foreign keys for SQL completion. */
dbCompletion: (id: string) => typedError<DbCompletion, IdeError>(__TAURI_INVOKE("db_completion", { id })),
/** Writes exported result data (CSV, JSON, SQL…) to `path`. */
/**
* Writes exported result data (CSV, JSON, SQL…) to `path`. Stays in the
* desktop shell: the path comes from a local save dialog, and a remote
* window exports through its local fs commands instead.
*/
dbExportFile: (path: string, text: string) => typedError<null, IdeError>(__TAURI_INVOKE("db_export_file", { path, text })),
/**
* Switches a data source between auto-commit and manual commit (leaving
* manual mode rolls back what was not committed).
*/
dbSetManualCommit: (id: string, manual: boolean) => typedError<null, IdeError>(__TAURI_INVOKE("db_set_manual_commit", { id, manual })),
/** Commits or rolls back the open transaction of a manual-commit data source. */
dbFinishTransaction: (id: string, commit: boolean) => typedError<null, IdeError>(__TAURI_INVOKE("db_finish_transaction", { id, commit })),
/** Statements a console runs: the selection's (`from < to`) or the one at the caret (`from`). */
dbStatements: (id: string, text: string, from: number, to: number) => typedError<SqlStatement[], IdeError>(__TAURI_INVOKE("db_statements", { id, text, from, to })),
/**
* Runs `statements` in order on data source `id`, stopping at the first
* error. Cancel with `cancel_request(request)`.
*/
dbExecute: (request: RequestId, id: string, statements: SqlStatement[], maxRows: number) => typedError<DbStatementOutcome[], IdeError>(__TAURI_INVOKE("db_execute", { request, id, statements, maxRows })),
dbTablePage: (request: RequestId, id: string, schema: string, table: string, filter: string | null, sort: DbSortKey[], offset: number, limit: number) => typedError<DbTablePage, IdeError>(__TAURI_INVOKE("db_table_page", { request, id, schema, table, filter, sort, offset, limit })),
/** Submits the table editor's changes in one transaction; returns the rows changed. */
dbApplyEdits: (id: string, schema: string, table: string, edits: DbRowEdit[]) => typedError<number | null, IdeError>(__TAURI_INVOKE("db_apply_edits", { id, schema, table, edits })),
/** The query console file of data source `id` (`<appData>/consoles/db/<id>/console.sql`), created on first use. */
dbConsolePath: (id: string) => typedError<IpcPath, IdeError>(__TAURI_INVOKE("db_console_path", { id })),
};
@@ -2403,6 +2376,7 @@ export type DbSslMode = "disable" | "prefer" | "require" |
/** [`DbSslMode::VerifyCa`], and check that the certificate names the host. */
"verifyFull";
/** One statement of a console run. */
export type DbStatementOutcome = {
statement: SqlStatement,
result: DbQueryResult | null,