import { invoke } from "@tauri-apps/api/core"; import { listen, type UnlistenFn } from "@tauri-apps/api/event"; import type { ConnectionConfig, DatabaseInfo, TableInfo, ObjectInfo, ObjectSource, ObjectSourceKind, ColumnInfo, IndexInfo, ForeignKeyInfo, TriggerInfo, QueryResult, InstalledPlugin, JdbcDriverInfo, JdbcPluginStatus, SavedSqlFile, SavedSqlFolder, SavedSqlLibrary, } from "@/types/database"; import type { AgentRuntimeSnapshot } from "@/lib/agentRuntimeSnapshot"; import type { AgentHandoffItem } from "@/lib/agentHandoff"; import type { AiConfig } from "@/stores/settingsStore"; export interface AiMessage { role: "user" | "assistant" | "system"; content: string; } export interface AiCompletionRequest { config: AiConfig; systemPrompt: string; messages: AiMessage[]; maxTokens?: number; temperature?: number; } export async function aiComplete(request: AiCompletionRequest): Promise { return invoke("ai_complete", { request }); } export interface AiStreamChunk { session_id: string; delta: string; reasoning_delta?: string; done: boolean; } export async function aiStream( sessionId: string, request: AiCompletionRequest, onChunk: (chunk: AiStreamChunk) => void, ): Promise { const unlisten: UnlistenFn = await listen("ai-stream-chunk", (event) => { if (event.payload.session_id === sessionId) { onChunk(event.payload); if (event.payload.done) unlisten(); } }); try { await invoke("ai_stream", { sessionId, request }); } catch (e) { unlisten(); throw e; } } export async function saveAiConfig(config: AiConfig): Promise { return invoke("save_ai_config", { config }); } export async function aiTestConnection(config: AiConfig): Promise { return invoke("ai_test_connection", { config }); } export async function aiCancelStream(sessionId: string): Promise { return invoke("ai_cancel_stream", { sessionId }); } export async function loadAiConfig(): Promise { return invoke("load_ai_config"); } export async function agentRuntimeUpdateSnapshot(snapshot: AgentRuntimeSnapshot): Promise { return invoke("agent_runtime_update_snapshot", { snapshot }); } export async function agentRuntimeLoadHandoffs(): Promise { return invoke("agent_runtime_load_handoffs"); } export async function agentRuntimeMarkHandoffShown(id: string): Promise { return invoke("agent_runtime_mark_handoff_shown", { id }); } export async function agentRuntimeRejectHandoff(id: string): Promise { return invoke("agent_runtime_reject_handoff", { id }); } // --- AI Conversations --- export interface AiChatMessage { role: string; content: string; reasoning?: string; } export interface AiConversation { id: string; title: string; connectionName: string; database: string; messages: AiChatMessage[]; createdAt: string; updatedAt: string; } export async function saveAiConversation(conversation: AiConversation): Promise { return invoke("save_ai_conversation", { conversation }); } export async function loadAiConversations(): Promise { return invoke("load_ai_conversations"); } export async function deleteAiConversation(id: string): Promise { return invoke("delete_ai_conversation", { id }); } export async function testConnection(config: ConnectionConfig): Promise { return invoke("test_connection", { config }); } export async function connectDb(config: ConnectionConfig): Promise { return invoke("connect_db", { config }); } export async function disconnectDb(connectionId: string): Promise { return invoke("disconnect_db", { connectionId }); } export async function listDatabases(connectionId: string): Promise { return invoke("list_databases", { connectionId }); } export async function saveSchemaCache(cacheKey: string, payload: unknown): Promise { return invoke("save_schema_cache", { cacheKey, payload }); } export async function loadSchemaCache(cacheKey: string): Promise { return invoke("load_schema_cache", { cacheKey }); } export async function deleteSchemaCachePrefix(prefix: string): Promise { return invoke("delete_schema_cache_prefix", { prefix }); } export async function listTables(connectionId: string, database: string, schema: string): Promise { return invoke("list_tables", { connectionId, database, schema }); } export async function listObjects(connectionId: string, database: string, schema: string): Promise { return invoke("list_objects", { connectionId, database, schema }); } export async function getObjectSource( connectionId: string, database: string, schema: string, name: string, objectType: ObjectSourceKind, ): Promise { return invoke("get_object_source", { connectionId, database, schema, name, objectType }); } export async function listSchemas(connectionId: string, database: string): Promise { return invoke("list_schemas", { connectionId, database }); } export async function getColumns( connectionId: string, database: string, schema: string, table: string, ): Promise { return invoke("get_columns", { connectionId, database, schema, table }); } export async function executeQuery( connectionId: string, database: string, sql: string, schema?: string, executionId?: string, ): Promise { return invoke("execute_query", { connectionId, database, sql, schema, executionId }); } export async function executeMulti( connectionId: string, database: string, sql: string, schema?: string, executionId?: string, ): Promise { return invoke("execute_multi", { connectionId, database, sql, schema, executionId }); } export async function cancelQuery(executionId: string): Promise { return invoke("cancel_query", { executionId }); } export async function executeBatch( connectionId: string, database: string, statements: string[], schema?: string, ): Promise { return invoke("execute_batch", { connectionId, database, statements, schema }); } export async function executeScript( connectionId: string, database: string, sql: string, schema?: string, ): Promise { return invoke("execute_script", { connectionId, database, sql, schema }); } export async function executeInTransaction( connectionId: string, database: string, statements: string[], schema?: string, ): Promise { return invoke("execute_in_transaction", { connectionId, database, statements, schema }); } export async function listIndexes( connectionId: string, database: string, schema: string, table: string, ): Promise { return invoke("list_indexes", { connectionId, database, schema, table }); } export async function listForeignKeys( connectionId: string, database: string, schema: string, table: string, ): Promise { return invoke("list_foreign_keys", { connectionId, database, schema, table }); } export async function listTriggers( connectionId: string, database: string, schema: string, table: string, ): Promise { return invoke("list_triggers", { connectionId, database, schema, table }); } export async function getTableDdl( connectionId: string, database: string, schema: string, table: string, ): Promise { return invoke("get_table_ddl", { connectionId, database, schema, table }); } export async function saveConnections(configs: ConnectionConfig[]): Promise { return invoke("save_connections", { configs }); } export async function loadConnections(): Promise { return invoke("load_connections"); } export async function listPlugins(): Promise { return invoke("list_plugins"); } export async function listJdbcDrivers(): Promise { return invoke("list_jdbc_drivers"); } export async function importJdbcDrivers(paths: string[]): Promise { return invoke("import_jdbc_drivers", { paths }); } export async function deleteJdbcDriver(path: string): Promise { return invoke("delete_jdbc_driver", { path }); } export async function jdbcPluginStatus(): Promise { return invoke("jdbc_plugin_status"); } export async function installJdbcPlugin(): Promise { return invoke("install_jdbc_plugin"); } export async function uninstallJdbcPlugin(): Promise { return invoke("uninstall_jdbc_plugin"); } export async function loadSavedSqlLibrary(): Promise { return invoke("load_saved_sql_library"); } export async function saveSavedSqlFolder(folder: SavedSqlFolder): Promise { return invoke("save_saved_sql_folder", { folder }); } export async function deleteSavedSqlFolder(id: string): Promise { return invoke("delete_saved_sql_folder", { id }); } export async function saveSavedSqlFile(file: SavedSqlFile): Promise { return invoke("save_saved_sql_file", { file }); } export async function deleteSavedSqlFile(id: string): Promise { return invoke("delete_saved_sql_file", { id }); } export async function saveSidebarLayout(layout: import("@/types/database").SidebarLayout): Promise { return invoke("save_sidebar_layout", { layout }); } export async function loadSidebarLayout(): Promise { return invoke("load_sidebar_layout"); } // --- Updates --- export interface UpdateInfo { current_version: string; latest_version: string; update_available: boolean; release_name: string; release_url: string; release_notes: string; } export async function checkForUpdates(): Promise { return invoke("check_for_updates"); } export async function getAppVersion(): Promise { const { getVersion } = await import("@tauri-apps/api/app"); return getVersion(); } // --- Redis --- export interface RedisKeyInfo { key_display: string; key_raw: string; key_type: string; ttl: number; size: number; value_preview: string; } export interface RedisValue { key_display: string; key_raw: string; key_type: string; ttl: number; value_is_binary: boolean; value: any; total?: number; scan_cursor?: number; } export interface RedisScanResult { cursor: number; keys: RedisKeyInfo[]; } export type RedisCommandSafety = "allowed" | "confirm" | "blocked"; export interface RedisCommandResult { command: string; safety: RedisCommandSafety; value: any; } export async function redisListDatabases(connectionId: string): Promise { return invoke("redis_list_databases", { connectionId }); } export async function redisScanKeys( connectionId: string, db: number, cursor: number, pattern: string, count: number, ): Promise { return invoke("redis_scan_keys", { connectionId, db, cursor, pattern, count }); } export async function redisGetValue(connectionId: string, db: number, keyRaw: string): Promise { return invoke("redis_get_value", { connectionId, db, keyRaw }); } export async function redisSetString( connectionId: string, db: number, keyRaw: string, value: string, ttl?: number, ): Promise { return invoke("redis_set_string", { connectionId, db, keyRaw, value, ttl }); } export async function redisDeleteKey(connectionId: string, db: number, keyRaw: string): Promise { return invoke("redis_delete_key", { connectionId, db, keyRaw }); } export async function redisHashSet( connectionId: string, db: number, keyRaw: string, field: string, value: string, ): Promise { return invoke("redis_hash_set", { connectionId, db, keyRaw, field, value }); } export async function redisHashDel(connectionId: string, db: number, keyRaw: string, field: string): Promise { return invoke("redis_hash_del", { connectionId, db, keyRaw, field }); } export async function redisListPush(connectionId: string, db: number, keyRaw: string, value: string): Promise { return invoke("redis_list_push", { connectionId, db, keyRaw, value }); } export async function redisListRemove(connectionId: string, db: number, keyRaw: string, index: number): Promise { return invoke("redis_list_remove", { connectionId, db, keyRaw, index }); } export async function redisSetAdd(connectionId: string, db: number, keyRaw: string, member: string): Promise { return invoke("redis_set_add", { connectionId, db, keyRaw, member }); } export async function redisSetRemove(connectionId: string, db: number, keyRaw: string, member: string): Promise { return invoke("redis_set_remove", { connectionId, db, keyRaw, member }); } export async function redisZadd( connectionId: string, db: number, keyRaw: string, member: string, score: number, ): Promise { return invoke("redis_zadd", { connectionId, db, keyRaw, member, score }); } export async function redisZrem(connectionId: string, db: number, keyRaw: string, member: string): Promise { return invoke("redis_zrem", { connectionId, db, keyRaw, member }); } export async function redisSetTtl(connectionId: string, db: number, keyRaw: string, ttl: number): Promise { return invoke("redis_set_ttl", { connectionId, db, keyRaw, ttl }); } export async function redisDeleteKeys(connectionId: string, db: number, keyRaws: string[]): Promise { return invoke("redis_delete_keys", { connectionId, db, keyRaws }); } export async function redisFlushDb(connectionId: string, db: number): Promise { return invoke("redis_flush_db", { connectionId, db }); } export async function redisExecuteCommand( connectionId: string, db: number, command: string, ): Promise { return invoke("redis_execute_command", { connectionId, db, command }); } export async function redisLoadMore( connectionId: string, db: number, keyRaw: string, keyType: string, cursor: number, count: number, ): Promise { return invoke("redis_load_more", { connectionId, db, keyRaw, keyType, cursor, count }); } // --- MongoDB --- export interface MongoDocumentResult { documents: any[]; total: number; } export async function mongoListDatabases(connectionId: string): Promise { return invoke("mongo_list_databases", { connectionId }); } export async function mongoListCollections(connectionId: string, database: string): Promise { return invoke("mongo_list_collections", { connectionId, database }); } export async function mongoFindDocuments( connectionId: string, database: string, collection: string, skip: number, limit: number, ): Promise { return invoke("mongo_find_documents", { connectionId, database, collection, skip, limit }); } export async function mongoInsertDocument( connectionId: string, database: string, collection: string, docJson: string, ): Promise { return invoke("mongo_insert_document", { connectionId, database, collection, docJson }); } export async function mongoUpdateDocument( connectionId: string, database: string, collection: string, id: string, docJson: string, ): Promise { return invoke("mongo_update_document", { connectionId, database, collection, id, docJson }); } export async function mongoDeleteDocument( connectionId: string, database: string, collection: string, id: string, ): Promise { return invoke("mongo_delete_document", { connectionId, database, collection, id }); } // --- History --- export interface HistoryEntry { id: string; connection_id?: string; connection_name: string; database: string; sql: string; executed_at: string; execution_time_ms: number; success: boolean; error?: string; activity_kind?: "query" | "data_change" | "schema_change" | "import" | "transfer"; operation?: string; target?: string; affected_rows?: number | null; rollback_sql?: string | null; details_json?: string | null; } export async function saveHistory(entry: HistoryEntry): Promise { return invoke("save_history", { entry }); } export async function loadHistory(limit: number, offset: number): Promise { return invoke("load_history", { limit, offset }); } export async function clearHistory(): Promise { return invoke("clear_history"); } export async function deleteHistoryEntry(id: string): Promise { return invoke("delete_history_entry", { id }); } // --- SQL File Execution --- export type SqlFileStatus = | "started" | "running" | "statementDone" | "statementFailed" | "done" | "error" | "cancelled"; export interface SqlFileRequest { executionId: string; connectionId: string; database: string; filePath: string; continueOnError: boolean; } export interface SqlFilePreview { fileName: string; filePath: string; sizeBytes: number; preview: string; } export interface SqlFileProgress { executionId: string; status: SqlFileStatus; statementIndex: number; successCount: number; failureCount: number; affectedRows: number; elapsedMs: number; statementSummary: string; error?: string | null; } export async function previewSqlFile(filePath: string): Promise { return invoke("preview_sql_file", { filePath }); } export async function executeSqlFile(request: SqlFileRequest): Promise { return invoke("execute_sql_file", { request }); } export async function cancelSqlFileExecution(executionId: string): Promise { return invoke("cancel_sql_file_execution", { executionId }); } export async function listenSqlFileProgress(handler: (progress: SqlFileProgress) => void): Promise { return listen("sql-file-progress", (event) => handler(event.payload)); } // --- Data Transfer --- export type TransferMode = "append" | "overwrite" | "upsert"; export interface TransferRequest { transferId: string; sourceConnectionId: string; sourceDatabase: string; sourceSchema: string; targetConnectionId: string; targetDatabase: string; targetSchema: string; tables: string[]; createTable: boolean; mode: TransferMode; batchSize: number; } export interface TransferProgress { transferId: string; table: string; tableIndex: number; totalTables: number; rowsTransferred: number; totalRows: number | null; status: "running" | "tableDone" | "done" | "error" | "cancelled"; error: string | null; } export async function startTransfer( request: TransferRequest, onProgress: (progress: TransferProgress) => void, ): Promise { const unlisten: UnlistenFn = await listen("transfer-progress", (event) => { if (event.payload.transferId === request.transferId) { onProgress(event.payload); if (event.payload.status === "done" || event.payload.status === "error" || event.payload.status === "cancelled") { unlisten(); } } }); try { await invoke("start_transfer", { request }); } catch (e) { unlisten(); throw e; } } export async function cancelTransfer(transferId: string): Promise { return invoke("cancel_transfer", { transferId }); } // --- Table File Import --- export type TableImportMode = "append" | "truncate"; export type TableImportStatus = "running" | "done" | "error" | "cancelled"; export interface TableImportColumnMapping { sourceColumn: string; targetColumn: string; } export interface TableImportPreview { fileName: string; filePath: string; fileType: string; sizeBytes: number; columns: string[]; rows: unknown[][]; totalRows: number; } export interface TableImportRequest { importId: string; connectionId: string; database: string; schema: string; table: string; filePath: string; mappings: TableImportColumnMapping[]; mode: TableImportMode; batchSize: number; } export interface TableImportSummary { importId: string; rowsImported: number; totalRows: number; } export interface TableImportProgress { importId: string; status: TableImportStatus; rowsImported: number; totalRows: number; error?: string | null; } export async function previewTableImportFile(filePath: string): Promise { return invoke("preview_table_import_file", { filePath }); } export async function importTableFile( request: TableImportRequest, onProgress: (progress: TableImportProgress) => void, ): Promise { const unlisten: UnlistenFn = await listen("table-import-progress", (event) => { if (event.payload.importId === request.importId) { onProgress(event.payload); if (event.payload.status === "done" || event.payload.status === "error" || event.payload.status === "cancelled") { unlisten(); } } }); try { return await invoke("import_table_file", { request }); } catch (e) { unlisten(); throw e; } } export async function cancelTableImport(importId: string): Promise { return invoke("cancel_table_import", { importId }); }