首页 > web前端 > js教程 > 从 VSCode 扩展管理 TOML 配置 - DBChat 第 8 部分

从 VSCode 扩展管理 TOML 配置 - DBChat 第 8 部分

Mary-Kate Olsen
发布: 2025-01-22 04:32:11
原创
977 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板