首頁 >web前端 >js教程 >從 VSCode 擴充功能管理 TOML 設定 - DBChat 第 8 部分

從 VSCode 擴充功能管理 TOML 設定 - DBChat 第 8 部分

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-22 04:32:111042瀏覽

Shrijith Venkatrama,Hexmos 的創始人,正在建立 LiveAPI,這是一個超級方便的工具,只需幾分鐘即可從您的程式碼生成出色的 API 文件,從而簡化工程工作流程。

在本教學系列中,我正在為自己建立 DBChat——一個簡單的工具,用於使用 AI 聊天來探索和改進資料庫。

請參閱先前的文章以獲取更多上下文:

  1. 建立 DBChat - 使用簡單的聊天探索和改進您的資料庫(第一部分)
  2. DBChat:在 Golang 中啟動一個玩具 REPL(第二部分)
  3. DBChat 第三部分 - 設定、連接和轉儲資料庫
  4. 透過 DBChat 和 Gemini 與您的資料庫聊天(第四部分)
  5. 語言伺服器協定 - 建置 DBChat(第五部分)
  6. 製作 DBChat VSCode 擴充 - 與 LSP 後端進行乒乓球互動(第六部分)
  7. 為 DBChat 啟動 VSCode 擴充 UI(第七部分)

在 VSCode 擴充功能中為 DBChat 建置 TOML 連線管理器 UI

在先前的文章中,我們在 DBChat VSCode 擴充功能中建立了一個簡單的聊天 UI 和資料庫連接表單的框架。

在這篇文章中,我將示範 DBChat 擴充功能如何操作 ~/.dbchat.toml 設定檔的 [connections] 部分以新增/更新/刪除條目。

為了喚醒您的記憶,設定檔應該具有以下結構:

<code># DBChat 示例配置文件
# 将此文件复制到 ~/.dbchat.toml 并根据需要修改

[connections]
# 格式:name = "connection_string"
local = "postgresql://postgres:postgres@localhost:5432/postgres"
liveapi = "postgresql://user:pwd@ip:5432/db_name" 

[llm]
gemini_key = "the_key"</code>

結果

DBChat 連線清單:

Manage TOML Configuration From VSCode Extension - DBChat Part 8

DBChat 新增/編輯連線:

Manage TOML Configuration From VSCode Extension - DBChat Part 8

對於編輯和更新,我們還有一個確認提示以避免錯誤。

處理建立連線請求

首先,安裝 toml 擴充:

<code> npm install @iarna/toml</code>

我們得到一些新的導入:

<code>import * as fs from 'fs/promises';
import * as path from 'path';
import * as os from 'os';
import * as TOML from '@iarna/toml';</code>

關鍵結構是一個訊息處理程序,它將接收所有三個操作的事件:

<code>        const messageHandler = this._view.webview.onDidReceiveMessage(
            async (message) => {
                console.log('Received message:', message);
                switch (message.command) {
                    case 'saveConnection':
                        console.log('Processing saveConnection command');
                        const success = await this._saveConnection(message.name, message.connectionString);
                        if (success) {
                            console.log('Connection saved successfully, closing form');
                            this._showingConnectionForm = false;
                            this._updateView();
                        } else {
                            console.log('Connection not saved, keeping form open');
                        }
                        break;
                    case 'cancel':
                        console.log('Processing cancel command');
                        this._showingConnectionForm = false;
                        this._updateView();
                        break;
                    case 'editConnection':
                        this._showingConnectionForm = true;
                        this._editingConnection = message.name;
                        // First update the view to show the form
                        await this._updateView();
                        // Then send the prefill message after a short delay to ensure the form exists
                        setTimeout(() => {
                            this._view.webview.postMessage({ 
                                command: 'prefillForm', 
                                name: message.name, 
                                connectionString: message.connectionString 
                            });
                        }, 100);
                        break;
                    case 'deleteConnection':
                        const choice = await vscode.window.showWarningMessage(
                            `Are you sure you want to delete connection "${message.name}"?`,
                            'Yes',
                            'No'
                        );
                        if (choice === 'Yes') {
                            const deleted = await this._deleteConnection(message.name);
                            if (deleted) {
                                await this._updateView();  // Update view after successful deletion
                                vscode.window.showInformationMessage(`Connection "${message.name}" deleted successfully.`);
                            }
                        }
                        break;
                }
            }
        );

        // Add message handler to subscriptions for cleanup
        context.subscriptions.push(messageHandler);</code>

保存連線非常簡單:

<code>    private async _saveConnection(name: string, connectionString: string): Promise<boolean> {
        console.log('Starting _saveConnection with:', { name, connectionString });
        try {
            const configPath = path.join(os.homedir(), 'dbchat.toml');
            console.log('Config path:', configPath);

            let config: any = {
                connections: {},
                llm: {}
            };
            console.log('Initial config structure:', config);

            // Read existing config if it exists
            try {
                console.log('Attempting to read existing config file...');
                const fileContent = await fs.readFile(configPath, 'utf-8');
                console.log('Existing file content:', fileContent);

                console.log('Parsing TOML content...');
                config = TOML.parse(fileContent);
                console.log('Parsed config:', config);

                // Ensure connections section exists
                config.connections = config.connections || {};
                console.log('Config after ensuring connections exist:', config);
            } catch (error: any) {
                console.log('Error reading config:', error);
                if (error.code !== 'ENOENT') {
                    console.error('Unexpected error reading config:', error);
                    throw error;
                }
                console.log('Config file does not exist, will create new one');
            }

            // Check if connection already exists
            if (config.connections[name]) {
                console.log(`Connection "${name}" already exists, showing confirmation dialog`);
                const choice = await vscode.window.showWarningMessage(
                    `Connection "${name}" already exists. Do you want to overwrite it?`,
                    'Yes',
                    'No'
                );
                console.log('User choice for overwrite:', choice);

                if (choice !== 'Yes') {
                    console.log('User declined to overwrite, returning false');
                    return false;
                }
            }

            // Update the connection
            config.connections[name] = connectionString;
            console.log('Updated config:', config);

            // Convert config to TOML and write back to file
            console.log('Converting config to TOML...');
            const tomlContent = TOML.stringify(config);
            console.log('Generated TOML content:', tomlContent);

            // Preserve the header comments
            const finalContent = `# DBChat Sample Configuration File
# Copy this file to ~/.dbchat.toml and modify as needed

${tomlContent}`;
            console.log('Final content to write:', finalContent);

            console.log('Writing to file...');
            await fs.writeFile(configPath, finalContent, 'utf-8');
            console.log('File written successfully');

            // Update view immediately after successful file write
            this._showingConnectionForm = false;
            console.log('Form hidden, updating view');
            this._updateView();

            await vscode.window.showInformationMessage(`Connection "${name}" saved successfully!`, { modal: false });
            return true;
        } catch (error) {
            console.error('Error in _saveConnection:', error);
            if (error instanceof Error) {
                console.error('Error stack:', error.stack);
            }
            await vscode.window.showErrorMessage(`Failed to save connection: ${error}`);
            return false;
        }
    }
</boolean></code>

列出連接

<code>    private async _getConnections(): Promise {
        try {
            const configPath = path.join(os.homedir(), 'dbchat.toml');
            const fileContent = await fs.readFile(configPath, 'utf-8');
            const config = TOML.parse(fileContent);
            return config.connections || {};
        } catch (error) {
            console.error('Error reading connections:', error);
            return {};
        }
    }</code>

刪除連線

<code>    private async _deleteConnection(name: string): Promise<boolean> {
        try {
            const configPath = path.join(os.homedir(), 'dbchat.toml');
            const fileContent = await fs.readFile(configPath, 'utf-8');
            const config = TOML.parse(fileContent);

            if (!config.connections || !config.connections[name]) {
                await vscode.window.showErrorMessage(`Connection "${name}" not found.`);
                return false;
            }

            delete config.connections[name];

            const tomlContent = TOML.stringify(config);
            const finalContent = `# DBChat Sample Configuration File
# Copy this file to ~/.dbchat.toml and modify as needed

${tomlContent}`;

            await fs.writeFile(configPath, finalContent, 'utf-8');
            // Show message after file operations are complete
            vscode.window.showInformationMessage(`Connection "${name}" deleted successfully.`);
            return true;
        } catch (error) {
            console.error('Error deleting connection:', error);
            vscode.window.showErrorMessage(`Failed to delete connection: ${error}`);
            return false;
        }
    }
</boolean></code>

這就是這篇文章的全部內容。透過這個結構,我們實作了一個基本的資料庫連線清單、新增、刪除和更新操作。

後續步驟

由於我們有一個基本的資料庫設定機制,接下來我們將致力於啟用連接到特定配置、獲取模式、與資料庫聊天等功能 - 使用 golang LSP。

以上是從 VSCode 擴充功能管理 TOML 設定 - DBChat 第 8 部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn