diff --git a/docs/docs.json b/docs/docs.json index db6ba373..79791031 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -202,6 +202,103 @@ ] } ] + }, + { + "language": "zh", + "tabs": [ + { + "tab": "文档", + "groups": [ + { + "group": "快速开始", + "pages": [ + "zh/index", + "zh/quickstart", + "zh/installation", + "zh/changelog" + ] + }, + { + "group": "数据库连接", + "pages": [ + "zh/databases/overview", + "zh/databases/connection-urls", + "zh/databases/mysql", + "zh/databases/postgresql", + "zh/databases/sqlite", + "zh/databases/mongodb", + "zh/databases/redis", + "zh/databases/redshift", + "zh/databases/oracle", + "zh/databases/clickhouse", + "zh/databases/mssql", + "zh/databases/oracle", + "zh/databases/ssh-tunneling" + ] + }, + { + "group": "功能特性", + "pages": [ + "zh/features/sql-editor", + "zh/features/data-grid", + "zh/features/autocomplete", + "zh/features/table-structure", + "zh/features/table-operations", + "zh/features/filtering", + "zh/features/change-tracking", + "zh/features/tabs", + "zh/features/import-export", + "zh/features/query-history", + "zh/features/ai-chat", + "zh/features/keyboard-shortcuts", + "zh/features/deep-links", + "zh/features/safe-mode" + ] + }, + { + "group": "自定义", + "pages": [ + "zh/customization/settings", + "zh/customization/appearance", + "zh/customization/editor-settings" + ] + } + ] + }, + { + "tab": "API", + "groups": [ + { + "group": "API 参考", + "pages": ["zh/api/overview"] + }, + { + "group": "许可证", + "icon": "key", + "pages": [ + "zh/api/activate", + "zh/api/validate", + "zh/api/deactivate" + ] + } + ] + }, + { + "tab": "开发", + "groups": [ + { + "group": "参与贡献", + "pages": [ + "zh/development/setup", + "zh/development/architecture", + "zh/development/code-style", + "zh/development/building", + "zh/development/plugin-registry" + ] + } + ] + } + ] } ], "global": { diff --git a/docs/zh/api/activate.mdx b/docs/zh/api/activate.mdx new file mode 100644 index 00000000..72911cb4 --- /dev/null +++ b/docs/zh/api/activate.mdx @@ -0,0 +1,4 @@ +--- +title: 激活许可证 +openapi: POST /v1/license/activate +--- diff --git a/docs/zh/api/deactivate.mdx b/docs/zh/api/deactivate.mdx new file mode 100644 index 00000000..fee3a42a --- /dev/null +++ b/docs/zh/api/deactivate.mdx @@ -0,0 +1,4 @@ +--- +title: 停用许可证 +openapi: POST /v1/license/deactivate +--- diff --git a/docs/zh/api/overview.mdx b/docs/zh/api/overview.mdx new file mode 100644 index 00000000..2e4fa7b3 --- /dev/null +++ b/docs/zh/api/overview.mdx @@ -0,0 +1,122 @@ +--- +title: 概述 +description: 用于许可证激活、验证和停用的 REST API,支持 RSA-SHA256 签名响应 +--- + +## 基础 URL + +``` +https://api.tablepro.app/v1 +``` + +## 端点 + +三个端点用于许可证生命周期管理: + +| 方法 | 端点 | 描述 | +| ------ | -------- | ----------- | +| `POST` | `/license/activate` | 在某台设备上激活许可证 | +| `POST` | `/license/validate` | 验证已激活的许可证 | +| `POST` | `/license/deactivate` | 从某台设备停用许可证 | + +## 请求格式 + +所有请求必须为 JSON 格式,并携带 `Content-Type: application/json` 头部。 + +### 公共参数 + +| 参数 | 类型 | 描述 | +| --------- | ---- | ----------- | +| `license_key` | `string` | 许可证密钥,格式为 `XXXXX-XXXXX-XXXXX-XXXXX-XXXXX`(字母数字) | +| `machine_id` | `string` | 设备标识符的 SHA-256 哈希值(64 位十六进制字符) | + +## 响应格式 + +成功的激活和验证响应会返回已签名的许可证数据: + +```json +{ + "data": { + "email": "john@example.com", + "expires_at": "2027-02-11T00:00:00+00:00", + "issued_at": "2026-02-12T10:30:00+00:00", + "license_key": "ABCDE-12345-FGHIJ-67890-KLMNO", + "status": "active" + }, + "signature": "base64-encoded-signature" +} +``` + +`signature` 字段是 `data` 对象的 RSA-SHA256 加密签名。可在客户端使用公钥验证以确保响应完整性。 + +## 响应签名 + +所有成功的激活和验证响应都经过加密签名: + +1. `data` 对象的字段按键名字母顺序排序 +2. 排序后的对象进行 JSON 编码 +3. JSON 字符串使用 RSA-SHA256 签名 +4. 签名以 Base64 格式返回 + +这使客户端能够验证许可证数据未被篡改。 + +## 速率限制 + +所有端点都有速率限制。速率限制信息包含在响应头中: + +| 头部 | 描述 | +| ------ | ----------- | +| `X-RateLimit-Limit` | 当前窗口期内允许的最大请求数 | +| `X-RateLimit-Remaining` | 当前窗口期内剩余的请求数 | +| `X-RateLimit-Reset` | 窗口期重置的 Unix 时间戳 | + +超出限制时,API 返回 `429`: + +```json +{ + "message": "Too many requests.", + "retry_after": 60 +} +``` + +## 错误处理 + +错误响应采用统一格式: + +```json +{ + "message": "Human-readable error message." +} +``` + +### 状态码 + +| 状态码 | 描述 | +| ---- | ----------- | +| `200` | 成功 | +| `403` | 许可证已暂停、已过期或设备未激活 | +| `404` | 未找到许可证密钥 | +| `409` | 已达激活数量上限 | +| `422` | 验证错误(请求参数无效) | +| `429` | 超出速率限制 | + +### 验证错误 + +`422` 响应包含字段级别的详细信息: + +```json +{ + "message": "The given data was invalid.", + "errors": { + "license_key": ["The license key field is required."], + "machine_id": ["The machine id must be 64 characters."] + } +} +``` + +## 许可证状态 + +| 状态 | 描述 | +| ------ | ----------- | +| `active` | 许可证有效且可用 | +| `suspended` | 许可证已暂停,无法激活或验证 | diff --git a/docs/zh/api/validate.mdx b/docs/zh/api/validate.mdx new file mode 100644 index 00000000..8b9ff454 --- /dev/null +++ b/docs/zh/api/validate.mdx @@ -0,0 +1,4 @@ +--- +title: 验证许可证 +openapi: POST /v1/license/validate +--- diff --git a/docs/zh/changelog.mdx b/docs/zh/changelog.mdx new file mode 100644 index 00000000..fb6d1320 --- /dev/null +++ b/docs/zh/changelog.mdx @@ -0,0 +1,554 @@ +--- +title: "更新日志" +description: "TablePro 产品更新与公告" +rss: true +--- + + + ### 新功能 + + - **DuckDB 支持**: 连接 `.duckdb` 文件,通过 SQL 查询 CSV/Parquet/JSON 文件,浏览 schema 和管理 extension + - **MongoDB Auth Database**: 配置 `authSource` 以使用任意数据库进行认证,不再局限于默认的 `admin` + - **安全模式分级**: 每个连接 6 个级别(Silent、Alert、Alert Full、Safe Mode、Safe Mode Full、Read-Only),替代原来的只读开关,支持确认对话框和 Touch ID/密码认证 + - **预览标签页**: 单击打开临时预览标签页,双击或编辑将其升级为永久标签页 + - **导入插件系统**: SQL 导入功能提取为 `.tableplugin` 包,支持 `.sql` 和 `.gz` 压缩文件 + - **从 Finder 打开 SQLite**: 双击 `.sqlite`、`.sqlite3`、`.db3`、`.s3db`、`.sl3` 和 `.sqlitedb` 文件即可直接打开 + - **插件安装提示**: 连接不支持的数据库类型时,自动提示安装缺失的驱动插件 + + ### 改进 + + - Oracle 和 ClickHouse 改为可下载的插件,减小应用包体积 + - SQLite 驱动从内置包提取为可下载插件 + - 导出插件选项(CSV、XLSX、JSON、SQL、MQL)现在跨应用重启保持设置 + - 插件可以声明设置界面,在 Settings > Plugins 中渲染 + - MSSQL 和 ClickHouse 使用真正的 prepared statements,消除字符串拼接 + - MSSQL、Oracle、ClickHouse 和 SQLite 支持批量查询操作,消除 N+1 模式 + - 所有数据库驱动统一错误格式和本地化错误消息 + - 标准化参数绑定,支持类型感知的数字处理和 NULL 字面量 + + ### 错误修复 + + - 修复 MongoDB Read Preference、Write Concern 和 Redis Database 不能跨应用重启保持的问题 + - 修复 PostgreSQL、Redshift、MSSQL 和 ClickHouse 的 DELETE 和 UPDATE 查询在 WHERE 子句中使用所有列而非主键的问题 + - 修复 MongoDB、Redis 和 ClickHouse 连接始终启用 SSL/TLS 的问题 + - 修复 Redis 侧边栏点击后数据短暂显示随即变空的问题 + - 修复 MongoDB 在未指定数据库名称时显示 "Invalid database name" 的问题 + - 修复结果在 100K 行处被截断时静默丢弃而未报告给界面的问题 + + + + ### 错误修复 + + - 修复切换数据库或 schema 后恢复标签页时旧过滤条件导致的重复错误 + - 修复切换数据库/schema 时侧边栏显示旧表而非加载指示器的问题 + - 修复 macOS 15 及更早版本上无表匹配过滤条件时侧边栏搜索框消失的问题 + - 修复已禁用的插件数据库类型仍出现在连接表单选择器中的问题 + - 修复连接失败时主窗口未在重新打开欢迎界面前关闭的问题 + + + + ### 新功能 + + - **插件系统**: 全部 8 个数据库驱动和 5 种导出格式提取为运行时加载的 `.tableplugin` 包,支持第三方插件 + - **插件市场**: 从 GitHub 托管的注册表中浏览、搜索和安装插件,支持校验和验证 + - **Settings > Plugins**: 管理已安装的插件:启用/禁用、从文件或市场安装、查看详情 + - **ClickHouse 支持**: 查询 ClickHouse 数据库,支持进度跟踪、EXPLAIN 变体、TLS/HTTPS、服务端取消和 Parts 视图 + - **启动命令**: 连接后运行自定义 SQL(例如 `SET time_zone`),通过 Connection > Advanced 标签页配置 + - **简体中文本地化**: 整个应用 UI 的完整 zh-Hans 翻译 + + ### 改进 + + - 每个连接减少约 80-130 MB 内存占用:移除专用 ping 驱动、延迟加载插件、RowBuffer 去重、元数据驱动合并 + - 将每个编辑器的 NSEvent 监听器合并为共享单例(每个事件从 O(n) 降为 O(1)) + - 项目重新组织为按领域划分的子目录 + + ### 错误修复 + + - 修复使用默认连接颜色时检查器分隔线溢出到工具栏区域的问题 + - 修复检查器切换因动画期间同步写入 UserDefaults 而卡顿的问题 + + + + ### 新功能 + + - **Oracle Database 支持**: 通过 OCI (Oracle Call Interface) 连接 Oracle 数据库 + - **数据库 URL Scheme**: 从终端直接打开连接,如 `open "mysql://user@host/db" -a TablePro`,支持 MySQL、PostgreSQL、SQLite、MongoDB、Redis、MSSQL 和 Oracle + - **SSH Agent 认证**: 使用 SSH Agent 进行隧道认证,兼容 1Password SSH Agent、Secretive 和 ssh-agent + - **多跳 SSH**: 链式多个 SSH 跳板(ProxyJump)通过堡垒机访问数据库,可在连接表单中配置跳板主机或从 `~/.ssh/config` 导入 + + ### 改进 + + - 将 CodeEditLanguages xcframework(38 种语法)替换为仅编译 SQL、Bash 和 JavaScript 的本地包,应用体积减少约 55% + + ### 错误修复 + + - 修复会话状态对象在每次打开标签页时重新创建导致 5 个标签页占用 785MB 内存的泄漏问题 + - 修复 DataGrid 中为每个单元格分配字段编辑器导致创建 180+ 个 NSTextView 实例而非共享一个的问题 + - 修复连接切换器中弹窗关闭路径未全部移除 NSEvent 监听器的问题 + - 修复 FreeTDS `disconnect()` 中 `dbproc` 在未持有锁的情况下被设为 nil 的竞态条件 + - 修复 TabStateStorage 中 JSON 编码和文件 I/O 阻塞主线程的问题 + - 修复 MySQL/MariaDB 在表操作中收到 `BEGIN` 而非 `START TRANSACTION` 的问题 + - 修复编辑自定义端口的连接时端口重置为默认值的问题 + - 修复 `MainContentCoordinator`、`LibPQConnection` 和 `VimKeyInterceptor` 中的数据竞争问题 + - 修复 SSH askpass 脚本写入时权限为全局可读的问题 + - 修复连接有孤立 group ID 时欢迎界面显示空白面板的问题 + - 修复恢复连接时多个标签页同时自动执行查询的问题 + - 修复 MySQL `SHOW CREATE TABLE` 查询中未转义标识符允许通过表名进行 SQL 注入的问题 + - 修复 `QueryResultRow` 的相等性比较忽略单元格值导致 SwiftUI 无法重新渲染已更新行的问题 + - 修复侧边栏搜索中 `Cmd+Delete` 清除查询编辑器内容的问题 + + + + ### 新功能 + + - **PostgreSQL 数据库和 Schema 切换**: 通过 ⌘K 切换 PostgreSQL 连接的数据库和 schema + + + + ### 新功能 + + - **Microsoft SQL Server 支持**: 通过 FreeTDS 连接 SQL Server 2017+ 数据库,支持 schema 浏览、表结构、索引、外键和分页查询 + - **无主键编辑和删除**: 在没有主键的表中也可以编辑和删除行 + + ### 错误修复 + + - 修复 MSSQL 连接在未配置默认数据库时断开并重新连接后丢失已选数据库的问题 + - 修复在没有主键的表上 DELETE 操作因缺少行数据而被静默丢弃的问题 + - 修复应用启动时 CPU 和内存占用过高的问题,原因是存储初始化阻塞、健康监控不同步和过多的重试循环 + - 修复数据库切换器加载缓慢的问题,将 N+1 元数据查询替换为批量查询 + - 修复 Redis 键浏览缓慢的问题,将 TYPE 和 TTL 命令通过 pipeline 合并为一次往返 + - 修复 SQL 导出启动缓慢的问题,批量处理 COUNT(*) 查询和依赖查询 + - 修复 AI Chat schema 加载缓慢的问题,在一次批量查询中获取所有外键 + - 修复 geometry 解析、Redis 驱动和自动补全评分中 O(n) 字符串操作导致 CPU 占用过高的问题 + + + + ### 新功能 + + - **Redis 支持**: 连接 Redis 数据库,支持键值浏览、数据库级侧边栏(db0-db15)、TTL 管理和交互式 CLI + - **TablePlus 兼容 URL**: 通过命令行打开数据库,如 `open -a TablePro "postgresql://user@host/db"`,支持 schema 切换、打开表、筛选、颜色和环境标签 + + ### 错误修复 + + - 修复侧边栏搜索框和主内容区域背景颜色未与 macOS 毛玻璃效果融合的问题 + - 修复 MySQL 中 POINT 和 geometry 列显示空值以及侧边栏中类型标签错误的问题 + + + + ### 新功能 + + - **Amazon Redshift 支持**: 连接 Amazon Redshift 数据仓库 + - **Deep Links**: 通过 `tablepro://` URL 打开连接、表、查询和导入连接 + - **复制为 URL**: 右键点击连接,复制其详情为连接字符串(例如 `mysql://user:pass@host/db`) + - **自动显示检查器**: 选择行时自动打开右侧边栏(Settings > Data Grid) + - **Homebrew Cask**: 通过 `brew install --cask tablepro` 安装 + + ### 改进 + + - ENUM 和 SET 列现在单击即可打开选择器,带有箭头指示器,与布尔列行为一致 + + ### 错误修复 + + - 修复在同一连接内切换数据库(Cmd+K)时表标签页打开状态下出现 "Table not found" 错误的问题 + - 修复右侧边栏状态在原生窗口标签页之间无法持久化的问题 + + + + ### 错误修复 + + - 修复 macOS 合并标签页组时 MySQL 第二个标签页显示空行的问题 + - 修复使用方括号语法时 MongoDB 标签页名称显示 "MQL Query" 而非集合名称的问题 + + + + ### 新功能 + + - **环境颜色指示器**: 工具栏根据连接颜色显示微妙的色调,便于快速识别环境 + - **SSH Tunnel URL 导入**: 从 SSH tunnel URL 导入数据库连接(例如 `mysql+ssh://`、`postgresql+ssh://`) + - **连接分组**: 将数据库连接组织到带有彩色标题的文件夹中 + + ### 改进 + + - 工具栏现在使用 macOS 原生溢出行为,History/Export/Import 移至二级操作菜单 + - 重新设计右侧边栏详情面板,采用紧凑字段布局和类型感知编辑器 + + ### 错误修复 + + - 修复打开新标签页时工具栏短暂显示 "MySQL" 且缺少版本信息的问题 + - 修复从欢迎界面连接后键盘快捷键不工作直到打开第二个标签页的问题 + - 修复窗口较窄时工具栏溢出菜单只显示一个项目的问题 + - 修复 AI 聊天中 MongoDB 代码块显示 "SQL" 标签且缺少语法高亮的问题 + + + + ### 新功能 + + - **多数据库连接**: 为不同的数据库连接打开独立窗口,每个窗口拥有独立的会话隔离 + - **MongoDB 支持**: 连接 MongoDB 数据库,支持集合浏览、文档查看和 MQL 导出 + - **从 URL 导入**: 直接从连接字符串导入数据库连接(例如 `postgresql://user:pass@host:5432/db`) + - **全新关于窗口**: 新的 About 窗口,包含版本信息和 Website、GitHub、Documentation 的快捷链接 + + ### 改进 + + - 发布说明现在显示在 Sparkle 更新窗口中 + + ### 错误修复 + + - 修复新行(Cmd+I)和复制的行在手动刷新前不显示在数据网格中的问题 + - 修复 PostgreSQL SSH tunnel 连接因 SSL 配置未保留而失败并提示 "no encryption" 的问题 + - 修复 PostgreSQL SSL `sslrootcert` 被无条件传递导致 Required 模式下证书验证失败的问题 + + + + ### 错误修复 + + - 修复应用包未进行 ad-hoc 签名的问题:未包含 dylib 时签名步骤被跳过 + + + + ### 错误修复 + + - 修复 Sparkle 自动更新因 "improperly signed" 错误而失败的问题:发布 ZIP 文件现在保留 framework 符号链接并包含正确的 ad-hoc 代码签名 + + + + ### 新功能 + + - **SQL 编辑器 Vim 模式**: 完整的 Vim 键位绑定,支持 Normal/Insert/Visual 模式、motion(`w`、`b`、`e`、`^`、`_`)、操作符和 `:w`/`:q` 命令,在编辑器设置中切换 + - **PostgreSQL Schema 切换**: 通过 ⌘K 数据库切换器浏览和切换 schema(`public`、`auth`、自定义 schema) + + ### 改进 + + - 查询历史操作转换为原生 Swift async/await,响应更快 + - 导出和导入服务合并,减少 UI 更新开销 + - 应用启动使用结构化 Task 重试循环替代 dispatch chain + + ### 错误修复 + + - 修复单元格编辑显示修改背景(黄色)但按 Enter 后恢复为原始值的问题 + - 修复撤销新插入行的单元格编辑时数据同步不正确的问题 + - 修复自动补全弹窗可见时 Vim Escape 键不工作的问题 + - 修复 SQL 编辑器中 Copy/Cut(⌘C/⌘X)不工作的问题 + - 修复 Vim yank/delete 不同步到系统剪贴板的问题 + - 修复多个 Vim motion 和 Visual 模式选择问题 + - 修复 SQL 编辑器生命周期中的事件监听器和内存泄漏问题 + - 修复 tab registry、sorted row cache 和 schema provider 导致的无限内存增长问题 + - 修复后台标签页无限期保留完整结果数据的问题 + - 修复 macOS 14.x 上因缺少 libpq 符号导致崩溃的问题:现使用内置静态库 + - 修复多窗口打开时从 AI Chat 或历史记录插入 SQL 产生重复标签页的问题 + - 修复多个 coordinator 生命周期问题(teardown、destroy、cancellation) + - 修复 DataGridView 在每次版本更新时不必要地重新配置列的问题 + - 修复 ConnectionHealthMonitor 故障检测缓慢的问题:现支持即时健康检查 + + + + ### 新功能 + + - **原生 macOS 窗口标签页**: 标签栏现在由 macOS 原生渲染,与 Finder、Safari 和 Xcode 的标签页完全一致,自动支持深色/浅色模式、拖拽排序和 "Merge All Windows" + - **独立标签页窗口**: 每个标签页都是完全独立的窗口,拥有自己的侧边栏、编辑器和状态,标签页之间不再共享状态 + + ### 改进 + + - **标签页切换性能**: Schema 现在按连接缓存,新标签页复用已加载的 schema 而非重新从数据库获取(每个标签页节省 500ms-2s) + - **后台 Schema 加载**: Schema 并发加载,表数据立即显示,自动补全 schema 在后台加载 + - **侧边栏 MVVM 重构**: 侧边栏表列表迁移至可测试的 `SidebarViewModel` 架构,提取了 `TableRowView` 和上下文菜单组件 + - 窗口标题在直接导航(侧边栏点击、外键导航)后动态更新 + - 10+ 项 SwiftUI 渲染优化,防止跨窗口的 O(N) 视图级联 + + ### 错误修复 + + - 修复打开第二个表标签页后侧边栏丢失键盘焦点(方向键导航)的问题 + - 修复点击在新原生窗口标签页中打开的表时侧边栏激活状态闪烁的问题 + - 修复在新原生窗口标签页中打开第二个表时侧边栏丢失激活状态的问题 + - 修复通过 Cmd+K 切换数据库后侧边栏不刷新的问题 + - 修复空状态下 Cmd+W 无响应的问题:现在关闭连接窗口并断开连接 + - 修复 Cmd+K 切换数据库时所有窗口都弹出错误提示的问题 + - 修复点击侧边栏中的表替换当前标签页而非打开新标签页的问题 + - 修复任何标签页上按 Cmd+W 断开整个会话的问题 + - 修复空状态下 Cmd+T 创建两个原生标签页而非一个的问题 + - 修复原生标签页标题显示 "SQL Query" 而非表名的问题 + - 修复最后一个标签页上按 Cmd+W 断开会话而非返回空状态的问题 + + + + ### 新功能 + + - **搜索与筛选联动**: 快速搜索和行筛选现在可以同时使用,两者同时激活时条件通过 AND 组合,实现精确数据发现 + - **外键导航**: 外键列在每个单元格中显示可点击的箭头图标,点击即可跳转到引用表,并自动筛选到关联行 + + ### 改进 + + - **即时元数据加载**: 外键箭头、列信息和行数现在通过专用的并行连接加载,消除首次打开表时 200-300ms 的延迟 + - **即时分页**: 来自数据库元数据的估算行数随数据立即显示;精确计数在后台静默更新 + - Import SQL 文件预览新增语法高亮 + - XLSX 导出遵循 Excel 每个工作表 100 万行的限制,内存占用更低 + - 多行单元格编辑现在使用可滚动的覆盖编辑器,导航更便捷 + - MySQL 结果获取切换到流式模式,减少大结果集的内存占用 + - 30+ 项内部性能优化,涵盖 SQL 编辑器、标签页切换、数据网格、导出和持久化 + + ### 错误修复 + + - 修复查询执行时忽略 AND/OR 筛选逻辑模式的问题 + - 修复筛选面板状态(筛选条件、可见性、搜索、逻辑模式)在切换标签页时不保持的问题 + - 修复切换到新标签页时外键导航筛选被清除的问题 + - 修复 PostgreSQL 和 SQLite 的 LIKE/NOT LIKE 表达式缺少 ESCAPE 子句的问题 + - 修复 SQLite regex 筛选静默回退到 LIKE 子字符串匹配的问题 + - 修复 PostgreSQL SQL 导出的问题:换行符/制表符转义、缺少枚举类型、types 和 sequences 缺少 DROP IF EXISTS + - 修复 PostgreSQL C 连接器中的内存管理问题(free 与 deallocate) + - 修复 FTS5 搜索遇到 *、OR、AND 等特殊字符时报错的问题 + + + + ### 错误修复 + + - **PostgreSQL SQL 导出**: 修复所有 PostgreSQL 表的 DDL 导出失败并提示 "Failed to fetch DDL" 的问题 + + + + ### 改进 + + - 欢迎窗口现在使用 macOS 原生毛玻璃半透明效果 + - 通过在渲染周期间缓存 row provider 和 change manager 提升标签页切换性能 + + ### 错误修复 + + - **MySQL/MariaDB 超时**: 自动检测服务器类型以使用正确的超时变量(MySQL 使用 `max_execution_time`,MariaDB 使用 `max_statement_time`) + - **DataGrid 滚动**: 行视图回收、O(1) 字符串长度检查、缓存字体、减少合成开销、延迟无障碍标签 + - 消除标签页切换时选择同步反馈循环导致的冗余更新 + - 通过在标签页切换时批量处理状态变更减少 SwiftUI 重渲染级联 + + + + ### 改进 + + - 将通用 SwiftUI 颜色替换为 macOS 原生系统颜色,正确支持深色模式、毛玻璃效果和无障碍适配 + - 使用语义化标签颜色(`quaternaryLabelColor`、`tertiaryLabelColor`)替代硬编码透明度 + - 使用原生 `shadowColor` 替代 `Color.black` 作为阴影颜色 + - 将 iOS 风格的 Capsule 徽章替换为 RoundedRectangle,更符合 macOS 原生风格 + + + + ### 性能 + + - **45 项性能修复**,涵盖内存、CPU、数据处理、网络和 I/O: + - **内存**: 引用式行缓冲、索引排序缓存、流式 XLSX 导出、驱动级行限制(100K 上限)、移除冗余字符串拷贝、schema provider 弱引用、撤销栈深度上限、字典式待处理变更、Task 中使用 weak self、断开连接时清除缓存数据、AI 聊天消息上限 + - **CPU**: 移除数据库驱动中昂贵的 Unicode 操作、缓存 SQL formatter 中 100+ 个正则表达式、异步 Keychain 读取、缓存常用正则表达式、O(1) 变更查找索引 + - **数据**: 为无保护查询自动添加 LIMIT、所有驱动的行限制上限、通过 INFORMATION_SCHEMA 批量获取列信息、索引排列排序缓存、缓存 row provider、剪贴板 50K 行上限、用 Int 替代 UUID 作为行 ID + - **网络**: 二阶段元数据缓存、PostgreSQL 连接超时、通过 mysql_kill/PQcancel/sqlite3_interrupt 取消查询、侧边栏加载保护、为 AI 复用缓存 schema + - **I/O**: 限流历史清理、异步历史存储迁移、合并 onChange 处理器 + + + + ### 新功能 + + - **内联 AI 建议**: SQL 编辑器中的幽灵文本补全,停止输入后自动触发,按 Tab 接受,按 Escape 取消 + - **Schema 感知补全**: 内联建议使用当前连接数据库中的实际表名和列名(缓存 30 秒 TTL) + - **VoiceOver 无障碍**: 为数据网格、筛选面板、工具栏按钮、编辑器标签栏和侧边栏控件添加无障碍标签 + + ### 改进 + + - 将通知观察者迁移至异步序列,适配现代 Swift 并发模型 + - 将标签页状态持久化从 UserDefaults 迁移至 Application Support 中的文件存储,加快应用启动速度 + - 将菜单和工具栏命令重构为 `@FocusedObject` 模式:直接方法调用替代全局通知 + - 重新设计连接表单,采用标签页布局(常规 / SSH Tunnel / SSL/TLS / 高级) + - 连接表单 UI 升级为 macOS 原生分组表单风格,自动标签对齐 + - SQLite 连接仅显示相关标签页(常规和高级) + - 为查询历史存储添加 async/await 包装方法 + + ### 错误修复 + + - 修复 SQLite 驱动中的线程安全竞态条件:使用专用 actor 序列化所有 handle 访问 + - 修复 SwiftUI sheet 显示可靠性问题:将多个 `.sheet` modifier 合并为单个 `.sheet(item:)` + - 修复 SSH tunnel 设置阻塞 UI 的问题:用异步端口探测替代同步进程等待 + - 修复 MySQL 和 PostgreSQL 连接清理中的潜在死锁 + - SQL 编辑器现在遵循 macOS 无障碍文本大小偏好设置并实时更新 + - 修复更新检查器中的循环引用和 SQL 编辑器 coordinator 中的泄漏观察者 + - 消除标签页切换延迟:跨切换保持 NSView 存活,将 I/O 移至后台线程 + - 将标签页切换 CPU 峰值从 40-60% 降至约 10-20%,消除冗余数据网格重载 + - 打开表时立即显示数据:元数据在后台加载,不阻塞数据网格 + - 消除点击侧边栏中已打开表时 20-80ms 的开销 + - 修复 Keychain 写入静默失败的问题:现在检查并记录返回值 + - 为所有 Keychain 查询添加服务标识符,防止与其他应用冲突 + - 修复导入对话框和 AI 提供商设置中的异步任务泄漏 + + + + ### 新功能 + + - **AI 聊天面板**: 右侧面板,支持多提供商(Claude、OpenAI、OpenRouter、Ollama、自定义端点)的 AI 辅助 SQL 查询,包括 schema 感知上下文、markdown 渲染和带复制/插入到编辑器按钮的代码块 + - **AI 提供商设置**: 在 Settings > AI 中配置多个 AI 提供商,管理 API key、端点配置、模型选择和连接测试 + - **AI 功能路由**: 将 AI 功能(聊天、解释查询、修复错误、内联建议)映射到特定的提供商和模型 + - **连接级 AI 策略**: 在连接表单中控制每个连接的 AI 访问权限(始终允许、每次询问、从不允许) + - **键盘快捷键自定义**: 在 Settings > Keyboard 中重新绑定任意菜单快捷键,支持按键录制 UI、冲突检测和 "恢复默认" + - **结构视图撤销/重做**: 结构编辑器中所有列、索引和外键操作的完整撤销/重做支持(⌘Z / ⇧⌘Z) + - **结构视图类型选择器**: 数据库特定的类型选择器弹窗:可搜索、按类别分组,支持自由输入参数化类型如 `VARCHAR(255)` + - **结构视图下拉菜单**: Nullable、Auto Inc 和 Unique 列的 YES/NO 下拉菜单 + - **标签页复用设置**: Settings > Tabs 中的选项,点击侧边栏新表时复用干净的表标签页 + - **切换连接快捷键**: ⌘⌥C 快速打开连接切换器弹窗 + - **SQL 自动补全增强**: 新的子句类型(RETURNING、UNION、OVER/PARTITION BY)、智能子句转换、JOIN 中的限定列建议、复合关键词、更丰富的列元数据、关键词文档和扩展的函数/关键词覆盖 + + ### 改进 + + - 将 5 个 NSPopover 控制器(Enum、Set、TypePicker、JSONEditor、ForeignKey)迁移至 SwiftUI,使用共享 `PopoverPresenter` 工具 + - 将 AppKit 历史面板(5 个文件)替换为纯 SwiftUI `HistoryPanelView` + - 将 `ExportTableOutlineView`(757 行)替换为 SwiftUI `ExportTableTreeView`(约 146 行) + - 将 `KeyEventHandler` NSViewRepresentable 替换为原生 `.onKeyPress()` modifier + - 改进布局架构:消除 KVO 观察 hack 和递归视图树遍历 + - 结构标签页网格列现在在数据加载时自动调整大小 + - SQL 自动补全现在使用 50ms 防抖和优化的模糊匹配 + + ### 错误修复 + + - 修复结构视图撤销/重做不工作的问题:撤销删除不再重复行,撤销删除未保存项目现在正常工作 + - 修复存在验证错误时结构视图保存按钮仍然可用的问题 + - 修复结构视图在 MySQL/MariaDB 上错误处理多列外键和列重命名的问题 + - 修复 PostgreSQL DDL 标签页缺少约束和主键检测的问题 + - 修复驱动 schema 查询中表名/数据库名含特殊字符时的 SQL 注入漏洞 + - 修复 SQL 编辑器撤销/重做(⌘Z / ⇧⌘Z)被响应链不匹配阻断的问题 + - 修复 SQL 自动补全问题:子查询子句检测、块注释处理、数据库特定类型、CREATE TABLE 后的 schema 建议、函数补全插入不完整括号 + - 修复排序时数据网格列顺序闪烁/交换的问题 + - 修复 "复制列名" 和 "按列筛选" 上下文菜单复制排序指示器的问题 + - 修复 AI 聊天 "每次询问" 策略静默变为 "始终允许" 的问题 + + + + ### 新功能 + + - **SQL 预览**: 提交更改前,通过新的工具栏按钮(眼睛图标)或快捷键(⌘⇧P)查看所有待执行的 SQL 语句 + - **多列排序**: Shift+点击列标题将列添加到排序列表;普通点击替换为单列排序。标题中显示优先级指示器(1▲、2▼) + - **带表头复制**: 通过 ⇧⌘C 或数据网格上下文菜单,复制选中行时附带列标题作为第一行 TSV + - **列宽持久化**: 调整后的列宽在标签页会话中跨分页、排序和筛选重载保持不变 + - **危险查询确认**: 没有 WHERE 子句的 DELETE/UPDATE 语句现在会弹出确认对话框,列出受影响的查询 + - **SQL 编辑器水平滚动**: 长行水平滚动,不自动换行 + - **查找面板滚动定位**: SQL 编辑器查找面板现在在导航时滚动到每个匹配位置 + + ### 改进 + + - 最低 macOS 版本从 13.5 (Ventura) 提升至 14.0 (Sonoma) + - 将导出/导入快捷键从 ⌘E/⌘I 改为 ⇧⌘E/⇧⌘I,避免与标准文本编辑快捷键冲突 + - URLSession 现在在分析和许可服务中等待网络连接 + - 改进 SQL 语句解析器以处理字符串字面量中的反斜杠转义,防止危险查询检测的误报 + + ### 错误修复 + + - 修复切换浅色和深色模式时 SQL 编辑器不更新颜色的问题 + - 修复侧边栏保留上次刷新后已移除的表的旧选择状态和待处理操作的问题 + + + + ### 错误修复 + + - 修复 macOS 13 (Ventura) x86_64 上启动崩溃的问题,原因是在设置单例初始化期间在 `NSApplication` 初始化前访问了 `NSApp.appearance` + + + + ### 错误修复 + + - 修复 SQL 编辑器中粘贴后语法高亮不生效的问题,通过延迟帧变更通知使可见范围在布局后重新计算 + - 修复插入新行后数据网格不刷新的问题 + + + + ### 新功能 + + - **语言设置**: 在 Settings > General 中选择系统语言、English 或 Vietnamese,包含完整的越南语本地化(637 个字符串) + - **ENUM/SET 列编辑器**: 双击 ENUM 列弹出可搜索下拉菜单,SET 列显示带 OK/Cancel 按钮的多选复选框 + - **PostgreSQL 枚举支持**: 通过 `pg_enum` 系统表查找用户自定义枚举类型 + - **SQLite 伪枚举检测**: 基于 CHECK 约束的 SQLite 列枚举检测 + - **连接健康监控**: 自动 30 秒健康检查,带指数退避自动重连(3 次重试) + - **匿名使用分析**: 可在 Settings > General > Privacy 中关闭 + + ### 改进 + + - 将 `Libs/*.a` 静态库迁移至 Git LFS 跟踪,减小仓库克隆大小 + - 将 `filter { }.count` 替换为 `count(where:)`,涉及 7 个文件 + - 将文档示例中的 `print()` 替换为 `Logger` + - 统一 Xcode `SWIFT_VERSION` 构建设置从 5.0 至 5.9 + + ### 错误修复 + + - 修复 macOS 13 上因 CodeEditSourceEditor 0.15.2 缺少 `asyncAndWait` 符号导致启动崩溃的问题 + - 修复 PostgreSQL `pg_enum` 查找和 SQLite `sqlite_master` 查询中通过转义单引号防止 SQL 注入的问题 + - 修复 ENUM 列可空检测使用启发式 `rawType` 检查而非实际 schema 元数据的问题 + - 修复 PostgreSQL 主键修改以从 `pg_constraint` 查询实际约束名的问题 + + + + ### 新功能 + + - **SSL/TLS 连接支持**: MySQL/MariaDB 和 PostgreSQL 的安全连接,支持可配置模式(禁用、首选、必需、验证 CA、验证身份)和自定义证书文件路径 + - **CSV 剪贴板粘贴**: 符合 RFC 4180 标准的 CSV 解析器,粘贴时自动检测 CSV 或 TSV 格式 + - **查询执行计划**: SQL 编辑器工具栏新增按钮和菜单项(⌥⌘E),用于查看查询执行计划 + - **连接切换器**: 工具栏中的快速切换弹窗,可在活动连接和已保存连接之间切换 + - **日期/时间选择器**: 用于编辑数据网格中 date、datetime、timestamp 和 time 列的专用日期选择器弹窗 + - **只读模式**: 连接级只读开关,带工具栏徽章和完整 UI 强制执行:禁用编辑、行操作和保存更改 + - **查询超时**: 在 Settings > General 中配置执行超时(默认 60 秒,0 = 无限制),按驱动分别通过 `statement_timeout` (PostgreSQL)、`max_execution_time` (MySQL)、`max_statement_time` (MariaDB) 和 `sqlite3_busy_timeout` (SQLite) 强制执行 + - **外键查找**: 外键列的可搜索下拉菜单,显示引用表的值,同时展示 ID 和描述性显示列 + - **JSON 列编辑器**: JSON/JSONB 列的弹窗编辑器,支持格式化、紧凑模式、实时验证和明确的保存/取消按钮 + - **Excel 导出**: 导出为 `.xlsx` 格式,使用轻量级纯 Swift OOXML 写入器,支持共享字符串去重、粗体表头、数字类型检测和多表导出到独立工作表 + - **视图管理**: 侧边栏上下文菜单支持创建视图(打开 SQL 编辑器并提供模板)、编辑视图定义(获取现有定义)和删除视图 + + ### 错误修复 + + - 修复 macOS 13 (Ventura) 上因缺少 Swift 运行时符号导致启动崩溃的问题 + - 修复数据网格中的重做功能(⌘⇧Z 现在正常工作) + - 修复进行新更改时重做栈未清除的问题 + - 修复数据网格 coordinator 中 `canRedo()` 始终返回 false 的问题 + - 将撤销/重做回调直接连接到数据网格以正确验证响应链 + - 修复 MariaDB 连接错误 1193 "Unknown system variable 'max_execution_time'",改用正确的 `max_statement_time` 变量 + - 查询超时错误不再阻止数据库连接的建立 + + ### 改进 + + - 将所有 `print()` 语句替换为结构化 OSLog `Logger`,涉及 25 个文件,通过 Console.app 实现更好的调试 + + + + ### 新功能 + + - **CodeEditSourceEditor 迁移**: SQL 编辑器现在由 tree-sitter 通过 CodeEditSourceEditor 驱动,改进语法高亮和性能 + - **多语句执行**: 在一次运行中执行多条 SQL 语句 + - **查看表结构**: 右键点击侧边栏中的任意表即可快速查看其结构 + - **改进的筛选面板**: 重新设计的筛选 UI,提供更好的体验 + - **SwiftUI 标签栏**: 全新的纯 SwiftUI 编辑器标签栏,替代 AppKit 实现 + - **GPL v3 许可证**: 项目现在采用 GNU General Public License v3 许可 + - **自动更新**: 通过 Sparkle 2 实现应用内更新,使用 EdDSA 签名。可在 TablePro 菜单或 Settings > General 中检查更新 + + ### 错误修复 + + - 修复 MySQL 8+ 连接因 `caching_sha2_password` 插件错误而失败的问题,通过静态编译认证插件重建 libmariadb 解决 + - 修复数据网格行上按 Delete 键错误地将表标记为已删除的问题 + - 降级所有 API 以支持 macOS 13.5 (Ventura) + + ### 维护 + + - CI 发布说明现在从精选的 CHANGELOG.md 读取,而非从 commit 自动生成 + - 移除冗余的 `prepare-libs` CI 任务,构建流水线加快约 5 分钟 + - 添加 CodeEditSourceEditor 依赖的 SPM Package.resolved + - 更新构建和测试命令,添加 `-skipPackagePluginValidation` + + + + TablePro 的首个公开发布版本:一款基于 SwiftUI 和 AppKit 构建的原生 macOS 数据库客户端。 + + ### 功能 + + - **多数据库支持**: 连接 MySQL、PostgreSQL 和 SQLite 数据库 + - **SQL 编辑器**: 功能完整的编辑器,支持语法高亮、自动补全和行号显示 + - **数据网格**: 浏览和编辑表数据,支持排序、筛选和分页 + - **SSH 隧道**: 通过 SSH 隧道安全连接数据库 + - **查询历史**: 记录和重放你的 SQL 查询 + - **表结构**: 查看和修改表 schema、索引和约束 + - **导入/导出**: 导入 SQL 文件,导出数据为 CSV、JSON 和 SQL 格式 + - **键盘快捷键**: 为高级用户提供全面的键盘导航 + - **原生标签栏**: AppKit 驱动的标签栏,支持拖拽排序 + - **Dock 菜单**: 快速访问欢迎窗口和最近的连接 + - **许可证激活**: RSA 签名的许可证验证,支持离线使用 + + ### 性能 + + - 优化 SQL 编辑器处理大文件,仅对可视区域进行语法高亮 + - 原生 AppKit 标签栏实现轻量级标签页管理 + - 高效的数据网格渲染,适用于大结果集 + - 使用 Apple 原生框架实现轻量级内存占用 + diff --git a/docs/zh/customization/appearance.mdx b/docs/zh/customization/appearance.mdx new file mode 100644 index 00000000..085a99b7 --- /dev/null +++ b/docs/zh/customization/appearance.mdx @@ -0,0 +1,334 @@ +--- +title: 外观 +description: 主题模式、强调色、连接颜色和数据库类型颜色编码 +--- + +# 外观设置 + +在 **Settings** > **Appearance** 中配置 TablePro 的外观。 + +{/* Screenshot: Appearance settings panel */} + + 外观设置 + 外观设置 + + +## 主题 + +三种主题模式: + +| 主题 | 描述 | +|-------|-------------| +| **System** | 自动跟随 macOS 外观(默认) | +| **Light** | 始终使用浅色 | +| **Dark** | 始终使用深色 | + +### 跟随系统主题 + +设为 **System** 时,TablePro 会跟随 macOS 的外观设置: + +1. 打开 **System Settings** > **Appearance** +2. 选择 Light、Dark 或 Auto +3. TablePro 自动更新 + +{/* Screenshot: Side-by-side light and dark themes */} + + 主题对比 + 主题对比 + + +### 浅色主题 + +- 白色/浅灰色背景 +- 深色文字,可读性好 +- 适合光线充足的环境 +- 明亮房间中对比度较低 + +### 深色主题 + +- 深灰色/黑色背景 +- 浅色文字,对比鲜明 +- 在低光照环境下减轻眼睛疲劳 +- 在 OLED 屏幕上更省电 + + +深色主题适合长时间工作,尤其是在光线较暗的环境中。 + + +## 强调色 + +| 选项 | 描述 | +|--------|-------------| +| **System** | 使用 macOS 系统强调色 | +| **Blue** | 经典蓝色 | +| **Purple** | 紫色 | +| **Pink** | 粉色 | +| **Red** | 红色 | +| **Orange** | 橙色 | +| **Yellow** | 黄色 | +| **Green** | 绿色 | +| **Graphite** | 灰色/中性色 | + +### 强调色的应用位置 + +- 选中项目和高亮显示 +- 按钮和交互元素 +- 进度指示器 +- 焦点轮廓 +- 活动标签页指示器 + +{/* Screenshot: Different accent colors applied */} + + 强调色 + 强调色 + + +{/* Screenshot: Accent color applied to UI */} + + 强调色应用于界面元素 + 强调色应用于界面元素 + + +### 与 macOS 保持一致 + +使用系统强调色: + +1. 将 TablePro 的强调色设置为 **System** +2. 打开 **System Settings** > **Appearance** +3. 选择你喜欢的强调色 +4. TablePro 自动更新 + +## 连接颜色 + +为连接分配颜色以便于视觉区分: + +| 颜色 | 建议用途 | +|-------|---------------| +| 无 | 默认,中性 | +| 红色 | 生产数据库 | +| 橙色 | 预发布环境 | +| 黄色 | 测试数据库 | +| 绿色 | 开发/本地环境 | +| 蓝色 | 共享数据库 | +| 紫色 | 特殊用途 | +| 粉色 | 个人项目 | + +### 设置连接颜色 + +1. 打开连接表单(编辑或新建) +2. 在 **Appearance** 部分,点击 **Color** +3. 从调色板中选择颜色 +4. 保存连接 + +{/* Screenshot: Connection color picker */} + + 连接颜色 + 连接颜色 + + +### 连接颜色的显示位置 + +连接颜色会显示在: + +- 侧边栏连接列表 +- 标签页头部 +- 连接状态栏 +- 窗口标题(已连接时) + + +建议将生产数据库设置为红色,作为执行查询时的视觉提醒。 + + +{/* Screenshot: Connection colors in sidebar and tabs */} + + 侧边栏和标签页中的连接颜色 + 侧边栏和标签页中的连接颜色 + + +## 数据库类型颜色 + +每种数据库类型都有固定的颜色用于快速识别: + +| 数据库 | 颜色 | +|----------|-------| +| MySQL | 橙色 | +| MariaDB | 青色 | +| PostgreSQL | 蓝色 | +| SQLite | 绿色 | + +这些颜色出现在: + +- 数据库类型图标 +- 连接类型指示器 +- 侧边栏图标 + +{/* Screenshot: Database type colors */} + + 数据库类型颜色 + 数据库类型颜色 + + +## 编辑器主题 + +SQL 语法高亮颜色: + +| 元素 | 颜色 | +|---------|-------| +| 关键字 | 粉色 | +| 字符串 | 绿色 | +| 数字 | 蓝色 | +| 注释 | 灰色 | +| 标识符 | 默认文字颜色 | + +颜色会自动适应浅色/深色主题。 + +## 界面元素 + +### 状态颜色 + +| 颜色 | 含义 | +|-------|---------| +| 绿色 | 成功、已连接、有效 | +| 橙色 | 警告、进行中、连接中 | +| 红色 | 错误、失败、无效 | +| 蓝色 | 信息 | +| 灰色 | 中性、已断开 | + +### 数据类型颜色 + +在数据表格中: + +| 类型 | 显示方式 | +|------|---------| +| NULL | 灰色,斜体 | +| 布尔值 True | 绿色 | +| 布尔值 False | 红色 | +| 数字 | 标准颜色 | +| 文本 | 标准颜色 | + +## 最佳实践 + +### 提升可读性 + +1. **适应环境**:低光照用深色主题,明亮环境用浅色主题 +2. **对比度**:确保对比度适合你的光照条件 +3. **字体大小**:如果文字不易阅读,可以增大字号 + +### 提高组织效率 + +1. **连接颜色**:选择一套统一的颜色方案 +2. **环境编码**:红色=生产、绿色=开发,以此类推 +3. **团队约定**:与团队成员协商统一的颜色含义 + +### 保护眼睛 + +1. **夜间用深色主题**:减少蓝光暴露 +2. **适当休息**:定期将目光从屏幕移开 +3. **Night Shift**:启用 macOS Night Shift 获得更暖的色调 + +## 无障碍 + +### 色觉辨识 + +1. 不要仅依赖颜色来传达信息 +2. 连接名称提供文字标识 +3. 图标辅助补充颜色信息 + +### 高对比度 + +1. 使用浅色或深色主题(不使用自动模式) +2. 选择高对比度的强调色(蓝色、绿色) +3. 在编辑器设置中增大字号 + +## 故障排除 + +### 主题未切换 + +1. 更改设置后重启 TablePro +2. 如果使用 System 主题,检查 macOS 外观设置 +3. 确认设置已保存 + +### 颜色显示异常 + +1. 在系统设置中检查显示器颜色配置文件 +2. 确认显示器校准正确 +3. 在支持的显示器上检查 True Tone 设置 + +### 强调色未生效 + +1. 重启 TablePro +2. 设置为具体颜色而非 System +3. 检查是否有冲突的系统扩展 + +## 相关设置 + + + + 字体和编辑器外观 + + + 所有设置分类 + + + 配置数据显示 + + + 连接颜色设置 + + diff --git a/docs/zh/customization/editor-settings.mdx b/docs/zh/customization/editor-settings.mdx new file mode 100644 index 00000000..fef1a30b --- /dev/null +++ b/docs/zh/customization/editor-settings.mdx @@ -0,0 +1,401 @@ +--- +title: 编辑器设置 +description: SQL 编辑器字体、大小、行号、自动换行、缩进和 Vim 模式配置 +--- + +# 编辑器设置 + +在 **Settings** > **Editor** 中配置 SQL 编辑器。 + +{/* Screenshot: Editor settings panel */} + + 编辑器设置 + 编辑器设置 + + +## 字体设置 + +### 字体系列 + +可用的等宽字体: + +| 字体 | 描述 | +|------|-------------| +| **System Mono** | macOS 默认等宽字体(推荐) | +| **SF Mono** | San Francisco Mono | +| **Menlo** | 经典 macOS 等宽字体 | +| **Monaco** | 传统 Mac 编程字体 | +| **Courier New** | 跨平台标准字体 | + + +**System Mono** 会自动使用系统最佳的等宽字体。 + + +### 字体可用性 + +| 字体 | 可用性 | +|------|--------------| +| System Mono | 始终可用 | +| SF Mono | macOS 10.12+ | +| Menlo | macOS 10.6+ | +| Monaco | macOS Classic | +| Courier New | 系统标准字体 | + +如果所选字体不可用,TablePro 会自动回退到 System Mono。 + +{/* Screenshot: Font family selector */} + + 字体系列选择器 + 字体系列选择器 + + +### 字体大小 + +| 设置 | 范围 | 默认值 | +|---------|-------|---------| +| 字体大小 | 11-18 pt | 13 pt | + +{/* Screenshot: Editor with different font sizes */} + + 字体大小 + 字体大小 + + +**建议**: + +| 大小 | 适用场景 | +|------|----------| +| 11-12 pt | 小屏幕,查看更多代码 | +| 13-14 pt | 常规使用(默认) | +| 15-16 pt | 更好的可读性 | +| 17-18 pt | 大屏幕,无障碍需求 | + +## 显示设置 + +### 行号 + +| 选项 | 描述 | +|--------|-------------| +| **开启** | 显示行号(默认) | +| **关闭** | 隐藏行号,获得更简洁的界面 | + +行号的用途: + +- 引用特定行 +- 定位错误信息中提到的行号 +- 在大型查询中导航 +- 与他人讨论代码 + +{/* Screenshot: Editor with and without line numbers */} + + 行号 + 行号 + + +### 当前行高亮 + +| 选项 | 描述 | +|--------|-------------| +| **开启** | 轻微高亮光标所在行(默认) | +| **关闭** | 不高亮当前行 | + +在长查询中帮助你追踪光标位置。 + +{/* Screenshot: Current line highlight */} + + 当前行高亮 + 当前行高亮 + + +### 自动换行 + +| 选项 | 描述 | +|--------|-------------| +| **关闭** | 长行水平滚动(默认) | +| **开启** | 长行自动换行到下一行 | + +**建议开启自动换行的场景**: + +- 在较窄的屏幕上工作 +- 查询语句行较长 +- 不想使用水平滚动 + +**建议关闭自动换行的场景**: + +- 偏好一致的行长度 +- 使用预格式化的查询 +- 需要清楚地看到查询结构 + +{/* Screenshot: Word wrap */} + + 自动换行对比 + 自动换行对比 + + +## 缩进设置 + +### 制表符宽度 + +| 设置 | 选项 | 默认值 | +|---------|---------|---------| +| 制表符宽度 | 1-16 个空格 | 4 | + +常见选择: + +| 宽度 | 用法 | +|-------|-------| +| 2 个空格 | 紧凑,JavaScript 风格 | +| 4 个空格 | 标准 SQL 格式(推荐) | +| 8 个空格 | 传统 Unix 风格 | + +{/* Screenshot: Tab width setting */} + + 制表符宽度设置 + 制表符宽度设置 + + +### 自动缩进 + +| 选项 | 描述 | +|--------|-------------| +| **开启** | 新行与上一行的缩进保持一致(默认) | +| **关闭** | 新行从第 1 列开始 | + +```sql +SELECT + u.id, + u.name, + | -- 光标在此处,下一行自动缩进 +``` + +{/* Screenshot: Auto-indent */} + + 编辑器中的自动缩进 + 编辑器中的自动缩进 + + +## 编辑器行为 + +### 文本输入 + +编辑器的行为与标准 macOS 文本编辑器一致: + +- 标准键盘快捷键正常使用 +- 复制/粘贴正常工作 +- 维护撤销/重做历史 +- 支持鼠标和键盘选择文本 + +### 自动补全 + +自动补全始终开启,但可以按 `Escape` 关闭。 + +详见[自动补全](/zh/features/autocomplete)。 + +## 应用设置 + +所有更改即时生效,无需重启。 + +## 推荐配置 + +### 默认(均衡) + +``` +Font Family: System Mono +Font Size: 13 pt +Line Numbers: On +Current Line: On +Tab Width: 4 +Auto Indent: On +Word Wrap: Off +``` + +### 紧凑(显示更多代码) + +``` +Font Family: SF Mono +Font Size: 11 pt +Line Numbers: On +Current Line: On +Tab Width: 2 +Auto Indent: On +Word Wrap: Off +``` + +### 舒适(易于阅读) + +``` +Font Family: Menlo +Font Size: 15 pt +Line Numbers: On +Current Line: On +Tab Width: 4 +Auto Indent: On +Word Wrap: On +``` + +### 极简(简洁界面) + +``` +Font Family: Monaco +Font Size: 13 pt +Line Numbers: Off +Current Line: Off +Tab Width: 4 +Auto Indent: On +Word Wrap: Off +``` + +### 无障碍 + +``` +Font Family: System Mono +Font Size: 18 pt +Line Numbers: On +Current Line: On +Tab Width: 4 +Auto Indent: On +Word Wrap: On +``` + +## 语法高亮 + +SQL 语法自动高亮显示: + +| 元素 | 深色主题颜色 | 浅色主题颜色 | +|---------|--------------|---------------| +| 关键字 | 粉色 | 粉色 | +| 字符串 | 绿色 | 绿色 | +| 数字 | 蓝色 | 蓝色 | +| 注释 | 灰色 | 灰色 | +| 函数 | 默认 | 默认 | +| 标识符 | 白色 | 黑色 | + +颜色会随当前主题自动调整。 + +### 高亮的关键字 + +被高亮显示的 SQL 关键字: + +- `SELECT`、`INSERT`、`UPDATE`、`DELETE`、`CREATE`、`ALTER`、`DROP` +- `FROM`、`WHERE`、`JOIN`、`ON`、`GROUP BY`、`ORDER BY`、`HAVING` +- `AND`、`OR`、`NOT`、`IN`、`LIKE`、`BETWEEN`、`IS NULL` +- `INNER`、`LEFT`、`RIGHT`、`OUTER`、`CROSS`、`UNION` +- 以及更多 SQL 标准关键字 + +## 编辑器键盘快捷键 + +| 操作 | 快捷键 | +|--------|----------| +| 执行查询 | `Cmd+Enter` | +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | +| 查找 | `Cmd+F` | +| 替换 | `Cmd+Option+F` | +| 全选 | `Cmd+A` | +| 跳转到行 | `Cmd+G` | + +查看[键盘快捷键](/zh/features/keyboard-shortcuts)获取完整列表。 + +## 故障排除 + +### 字体显示不正确 + +1. 确认字体已安装到系统中 +2. 尝试其他字体 +3. 重启 TablePro + +### 设置未保存 + +1. 检查磁盘权限 +2. 确认偏好设置文件可写: + ```bash + ls -la ~/Library/Preferences/com.TablePro.plist + ``` +3. 尝试重置偏好设置 + +### 编辑器响应缓慢 + +1. 减小字体大小(较大字体渲染更慢) +2. 对于长查询关闭自动换行 +3. 检查编辑器中是否有超大查询 + +## 相关页面 + + + + 编辑器功能和用法 + + + 自动补全功能 + + + 主题和颜色 + + + 所有键盘快捷键 + + diff --git a/docs/zh/customization/settings.mdx b/docs/zh/customization/settings.mdx new file mode 100644 index 00000000..a63ecbcd --- /dev/null +++ b/docs/zh/customization/settings.mdx @@ -0,0 +1,537 @@ +--- +title: 设置概览 +description: 所有设置分类 - 通用、外观、编辑器、数据表格、标签页、键盘、AI、历史记录、插件和许可证 +--- + +# 设置概览 + +通过 **TablePro** > **Settings** 或 `Cmd+,` 打开设置。 + +{/* Screenshot: Settings window showing all categories */} + + 设置窗口 + 设置窗口 + + +## 设置分类 + + + + 语言、启动行为、软件更新和基本偏好设置 + + + 主题、颜色和视觉选项 + + + SQL 编辑器字体、大小和行为 + + + 行高、日期格式和显示设置 + + + 标签页复用行为 + + + 自定义键盘快捷键 + + + AI 提供商配置和聊天设置 + + + 查询历史保留设置 + + + 管理数据库驱动插件 + + + 许可证激活和管理 + + + +## 通用设置 + +### 语言 + +| 选项 | 描述 | +|--------|-------------| +| **System** | 跟随 macOS 系统语言(默认) | +| **English** | 英语 | +| **Tiếng Việt** | 越南语 | + + +更改语言需要重启 TablePro。 + + +### 启动行为 + +| 选项 | 描述 | +|--------|-------------| +| **显示欢迎界面** | 显示带有最近连接的欢迎界面 | +| **恢复上次会话** | 自动重新连接到上次使用的数据库 | + +### 查询执行超时 + +设置查询在被取消前的最大运行时间: + +| 设置 | 默认值 | 范围 | 描述 | +|---------|---------|-------|-------------| +| **查询超时** | 60 秒 | 0 -- 600 | 最大等待秒数。0 表示无限制。 | + +超时在数据库层面执行: + +| 数据库 | 机制 | +|----------|-----------| +| PostgreSQL | `SET statement_timeout`(所有语句) | +| MySQL | `SET SESSION max_execution_time`(SELECT 查询) | +| MariaDB | `SET SESSION max_statement_time`(SELECT 查询) | +| SQLite | `sqlite3_busy_timeout`(锁竞争) | + + +超时在建立新连接时生效。更改超时设置需要重新连接。 + + +{/* Screenshot: Query timeout setting */} + + 查询超时设置 + 查询超时设置 + + +### 软件更新 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **自动检查更新** | 开启 | 在后台定期检查新版本 | +| **立即检查更新...** | -- | 立即检查 | + +TablePro 使用 [Sparkle](https://sparkle-project.org/) 进行更新。当有可用更新时,会弹出对话框显示发布说明和安装选项。 + +也可以从 **TablePro** 菜单 > **Check for Updates...** 访问。 + +### 隐私 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **分享匿名使用数据** | 开启 | 每 24 小时发送匿名统计数据(操作系统版本、架构、地区、数据库类型) | + +完全匿名:不会传输任何个人信息、查询内容或数据库数据。可随时关闭。 + +{/* Screenshot: General settings panel */} + + 通用设置 + 通用设置 + + +## 数据表格设置 + +### 行高 + +| 选项 | 高度 | 适用场景 | +|--------|--------|----------| +| **紧凑** | 20px | 密集数据,显示更多行 | +| **标准** | 24px | 均衡(默认) | +| **舒适** | 28px | 更好的可读性 | +| **宽松** | 32px | 无障碍需求 | + +### 日期格式 + +| 格式 | 示例 | +|--------|---------| +| ISO 8601 | 2024-12-31 23:59:59 | +| ISO Date | 2024-12-31 | +| US Long | 12/31/2024 11:59:59 PM | +| US Short | 12/31/2024 | +| EU Long | 31/12/2024 23:59:59 | +| EU Short | 31/12/2024 | + + +建议使用 ISO 8601 格式以保持一致性,特别是在跨国团队中。 + + +### NULL 显示 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **NULL 显示** | "NULL" | NULL 值显示的文本 | + +选项: +- `NULL` - 标准数据库表示法 +- `(null)` - 括号形式 +- `∅` - 空集符号 +- 自定义文本(最多 20 个字符) + +### 每页行数 + +| 范围 | 最小值 | 最大值 | 默认值 | +|-------|---------|---------|---------| +| 每页行数 | 10 | 100,000 | 1,000 | + + +较大的每页行数会占用更多内存,但可以一次显示更多数据。 + + + +**验证范围:** +- **每页行数**:10 -- 100,000 行(超出范围的值会被自动限制) +- **NULL 显示**:最多 20 个字符,不允许换行符或制表符 + + +### 交替行颜色 + +| 选项 | 描述 | +|--------|-------------| +| **开启** | 斑马纹条纹,便于扫视 | +| **关闭** | 统一背景色 | + +### 自动显示检查器 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **选中行时自动显示检查器** | 关闭 | 在表格标签页中选中行时,自动打开右侧边栏 | + +{/* Screenshot: Data Grid settings */} + + 数据表格设置 + 数据表格设置 + + +## 标签页设置 + +### 复用空闲表格标签页 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **复用空闲表格标签页** | 关闭 | 在侧边栏点击新表格时,替换当前表格标签页而非打开新标签页 | + +满足以下所有条件时,标签页被视为"空闲": + +- 是表格标签页(非查询或创建表) +- 未被固定 +- 没有未保存的更改 +- 你没有与之交互(没有排序、筛选、选中行等操作) + +关闭时(默认),每次点击表格都会打开一个新标签页。 + + +启用此选项可获得单标签页浏览体验,类似 TablePlus 的默认行为。 + + +{/* Screenshot: Tab settings */} + + 标签页设置 + 标签页设置 + + +### 预览标签页 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **启用预览标签页** | 开启 | 单击表格打开临时标签页,下次点击时会被替换 | + +启用后,在侧边栏单击表格会打开预览标签页。预览标签页在你点击另一个表格时会被替换。双击表格或与预览标签页交互(排序、筛选、编辑)会使其变为永久标签页。 + +预览标签页在窗口副标题中显示"Preview",且不会在应用重启时保留。 + +## 键盘设置 + +自定义菜单操作的键盘快捷键。详见[键盘快捷键](/zh/features/keyboard-shortcuts#customizing-shortcuts)。 + +### 重新绑定快捷键 + +1. 打开 **Settings** > **Keyboard** +2. 点击任意操作旁的快捷键字段 +3. 按下新的按键组合 +4. 立即生效 + +### 冲突检测 + +分配已在使用的快捷键时,会弹出对话框提供 **Cancel** 或 **Reassign** 选项。系统保留快捷键(`Cmd+Q`、`Cmd+H`、`Cmd+M`、`Cmd+,`)不可重新分配。 + +### 恢复默认 + +点击 **Reset to Defaults** 恢复所有快捷键。 + +{/* Screenshot: Keyboard settings */} + + 键盘设置 + 键盘设置 + + +## 历史记录设置 + +### 最大条目数 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **最大条目数** | 10,000 | 保留的最大查询数量 | + +设为 `0` 表示无限制。 + +### 最大天数 + +| 设置 | 默认值 | 描述 | +|---------|---------|-------------| +| **最大天数** | 90 | 删除超过此天数的查询记录 | + +设为 `0` 表示永久保留历史记录。 + +### 自动清理 + +| 选项 | 描述 | +|--------|-------------| +| **开启** | 自动清除旧条目(默认) | +| **关闭** | 仅手动清理 | + + +关闭自动清理且不限制条目数量时,历史数据库可能会随时间变得非常大。 + + +### 清除历史记录 + +1. 打开 Settings > History +2. 点击 **Clear All History** +3. 确认操作 + +{/* Screenshot: History settings */} + + 历史记录设置 + 历史记录设置 + + +## 插件设置 + +在 Settings 的 **Plugins** 标签页中管理数据库驱动插件。 + +### 已安装插件 + +TablePro 内置 8 个数据库驱动插件: + +| 插件 | 数据库类型 | 默认端口 | +|--------|---------------|--------------| +| MySQL | MySQL, MariaDB | 3306 | +| PostgreSQL | PostgreSQL, Redshift | 5432 | +| SQLite | SQLite | -- | +| ClickHouse | ClickHouse | 8123 | +| SQL Server | SQL Server | 1433 | +| MongoDB | MongoDB | 27017 | +| Redis | Redis | 6379 | +| Oracle | Oracle | 1521 | + +每个插件都有开关按钮来启用或禁用。禁用的插件会在连接对话框中隐藏其数据库类型,并阻止连接到该类型的数据库。 + +### 插件详情 + +点击插件查看详情:版本、Bundle ID、支持的功能、数据库类型和默认端口。 + +### 安装第三方插件 + +1. 点击 **Install from File...** +2. 选择包含 `.tableplugin` 包的 `.zip` 压缩文件 +3. TablePro 验证代码签名并安装插件 + + +只安装来自你信任的来源的插件。TablePro 会检查侧载插件的代码签名,但无法保证其行为。 + + +### 卸载插件 + +用户安装的插件在插件详情视图中显示 **Uninstall** 按钮。内置插件不能卸载,只能禁用。 + +## 许可证设置 + +在 Settings 的 **License** 标签页中管理你的许可证。 + +### 激活许可证 + +1. 打开 **Settings**(`Cmd+,`)并选择 **License** 标签页 +2. 输入许可证密钥 +3. 点击 **Activate** + +激活后,标签页会显示你的注册邮箱和许可证密钥。 + +### 停用许可证 + +1. 打开 **Settings** > **License** +2. 点击 **Deactivate...** +3. 确认操作 + + +停用许可证会释放激活名额,以便在其他设备上使用。 + + +### 离线使用 + +TablePro 使用加密签名在本地验证许可证。激活后的日常使用不需要联网。应用每 7 天会与服务器重新验证一次。 + +{/* Screenshot: License settings */} + + 许可证设置 + 许可证设置 + + +## 设置存储 + +设置存储在: + +``` +~/Library/Preferences/com.TablePro.plist +``` + +### 重置设置 + +将所有设置恢复为默认值: + +```bash +# 删除偏好设置文件 +rm ~/Library/Preferences/com.TablePro.plist + +# 删除缓存设置 +rm -rf ~/Library/Caches/com.TablePro +``` + +然后重启 TablePro。 + + +重置偏好设置不会影响已保存的连接或查询历史。 + + +## 按功能分类的设置 + +### 连接相关 + +| 设置 | 位置 | 描述 | +|---------|----------|-------------| +| 语言 | 通用 | 应用显示语言 | +| 启动行为 | 通用 | 启动时的操作 | +| 查询超时 | 通用 | 查询最大执行时间 | +| 自动检查更新 | 通用 | 自动检查更新 | +| 分享统计数据 | 通用 | 分享匿名使用数据 | +| 自动重连 | 连接 | 断开时自动重连 | +| 安全模式 | 连接 | 按连接配置查询执行控制 | + +### 编辑器相关 + +| 设置 | 位置 | 描述 | +|---------|----------|-------------| +| 字体系列 | 编辑器 | 等宽字体选择 | +| 字体大小 | 编辑器 | 文字大小(11--18 pt,限制在范围内) | +| 行号 | 编辑器 | 显示/隐藏行号 | +| 自动换行 | 编辑器 | 长行换行 | +| 制表符宽度 | 编辑器 | 每个制表符的空格数(1--16) | +| Vim 模式 | 编辑器 | 在 SQL 编辑器中启用 Vim 键绑定(Normal/Insert/Visual 模式) | + +详见[编辑器设置](/zh/customization/editor-settings)。 + +### 显示相关 + +| 设置 | 位置 | 描述 | +|---------|----------|-------------| +| 主题 | 外观 | 浅色/深色/跟随系统 | +| 强调色 | 外观 | 界面强调色 | +| 行高 | 数据表格 | 表格行高 | +| 日期格式 | 数据表格 | 日期显示格式 | + +详见[外观](/zh/customization/appearance)。 + +### 键盘相关 + +| 设置 | 位置 | 描述 | +|---------|----------|-------------| +| 快捷键绑定 | 键盘 | 自定义菜单键盘快捷键 | +| 恢复默认 | 键盘 | 将所有快捷键恢复为原始值 | + +### 筛选相关 + +| 设置 | 位置 | 描述 | +|---------|----------|-------------| +| 默认列 | 筛选 | 新筛选器预选的列(Raw SQL、主键、任意列) | +| 默认运算符 | 筛选 | 新筛选器预选的运算符 | +| 面板状态 | 筛选 | 打开时筛选面板的行为(隐藏、始终显示、恢复上次状态) | + +详见[筛选](/zh/features/filtering)。 + +## 键盘快捷键 + +| 操作 | 快捷键 | +|--------|----------| +| 打开设置 | `Cmd+,` | + +## 相关页面 + + + + 主题和颜色设置 + + + SQL 编辑器配置 + + + 历史记录功能详情 + + + 数据表格功能 + + diff --git a/docs/zh/databases/clickhouse.mdx b/docs/zh/databases/clickhouse.mdx new file mode 100644 index 00000000..2cf7289f --- /dev/null +++ b/docs/zh/databases/clickhouse.mdx @@ -0,0 +1,358 @@ +--- +title: ClickHouse +description: 使用 TablePro 连接 ClickHouse 数据库 +--- + +# ClickHouse 连接 + +TablePro 通过 HTTP 接口连接 ClickHouse。ClickHouse 是一个面向列存储的 OLAP 数据库,专为大数据集的实时分析而设计。TablePro 通过 HTTP(默认端口 8123)连接,而非原生 TCP 协议。 + +## 安装插件 + +ClickHouse 驱动以可下载插件的形式提供。当你在连接表单中选择 ClickHouse 时,TablePro 会提示你自动安装。你也可以手动安装: + +1. 打开 **Settings** > **Plugins** > **Browse** +2. 找到 **ClickHouse Driver** 并点击 **Install** +3. 插件会立即下载和加载,无需重启 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **ClickHouse** + + + 填写 host、port、username、password 和数据库名称 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP 地址 | `localhost` | +| **Port** | ClickHouse HTTP 端口 | `8123` | + +### 可选字段 + +| 字段 | 描述 | +|-------|-------------| +| **Username** | ClickHouse 用户名 | `default` | +| **Password** | 用户密码(本地安装默认为空) | +| **Database** | 要连接的数据库 | `default` | + + +ClickHouse 在全新安装时自带一个无密码的 `default` 用户。对于生产服务器,请务必设置密码或配置访问控制。 + + +## HTTP 接口 + +TablePro 通过 HTTP API 连接 ClickHouse,而非原生 TCP 协议(端口 9000)。HTTP 接口默认在 8123 端口启用,支持所有 SQL 操作。 + +如果你的 ClickHouse 服务器使用 HTTPS,请在连接表单中启用 SSL/TLS。默认的 HTTPS 端口是 8443。 + + +部分 ClickHouse 云服务商只暴露 HTTP(S) 接口。由于 TablePro 原生使用 HTTP,因此可以开箱即用。 + + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local ClickHouse +Host: localhost +Port: 8123 +Username: default +Password: (留空) +Database: default +``` + +### Docker ClickHouse 容器 + +启动一个 ClickHouse 容器用于本地测试: + +```bash +docker run -d \ + --name clickhouse \ + -p 8123:8123 \ + -p 9000:9000 \ + -e CLICKHOUSE_USER=default \ + -e CLICKHOUSE_PASSWORD=secret \ + clickhouse/clickhouse-server:latest +``` + +然后用以下信息连接: + +``` +Name: Docker ClickHouse +Host: localhost +Port: 8123 +Username: default +Password: secret +Database: default +``` + +### ClickHouse Cloud + +``` +Name: ClickHouse Cloud +Host: abc123.us-east-1.aws.clickhouse.cloud +Port: 8443 +Username: default +Password: (你的云密码) +Database: default +``` + + +ClickHouse Cloud 要求 HTTPS(端口 8443)。请在连接表单中启用 SSL/TLS。 + + +### 远程服务器 + +``` +Name: Production ClickHouse +Host: clickhouse.example.com +Port: 8123 +Username: app_user +Password: (安全密码) +Database: analytics +``` + + +对于生产环境的 ClickHouse 实例,如果 HTTP 端口未加密,建议使用 [SSH tunneling](/zh/databases/ssh-tunneling)。 + + +## SSL/TLS 连接 + +TablePro 支持 ClickHouse 连接的 SSL/TLS 加密。在连接表单的 **SSL/TLS** 部分配置。 + +| SSL 模式 | 描述 | +|----------|-------------| +| **Disabled** | 不使用 SSL 加密(HTTP,端口 8123) | +| **Required** | 要求 SSL 加密(HTTPS,通常使用端口 8443) | + + +ClickHouse Cloud 和大多数托管 ClickHouse 服务要求 HTTPS。将端口设为 8443 并启用 SSL。 + + +## SSH Tunnel 支持 + +你可以通过 SSH tunnel 连接 ClickHouse 以安全访问远程服务器。详细设置方法请参阅 [SSH Tunneling](/zh/databases/ssh-tunneling)。 + +## 功能 + +### 数据库浏览 + +连接后,侧栏列出服务器上的所有数据库。展开数据库可以看到其表和视图。使用工具栏中的数据库切换器切换数据库。 + +### 表浏览 + +每个表显示以下内容: + +- **Structure**:列及其 ClickHouse 数据类型、默认表达式和注释 +- **Indexes**:数据跳跃索引(minmax、set、bloom_filter 等) +- **DDL**:完整的 CREATE TABLE 语句,包括引擎和设置 +- **Parts**:来自 `system.parts` 的分区和 part 详情(行数、磁盘大小、活跃状态) + +### 引擎信息 + +ClickHouse 表使用存储引擎来决定数据的存储和查询方式。TablePro 在表结构视图中显示引擎类型及其参数。常见引擎: + +| 引擎 | 用途 | +|--------|----------| +| **MergeTree** | 生产分析表的主要引擎 | +| **ReplacingMergeTree** | 按排序键去重 | +| **SummingMergeTree** | 数值列的预聚合 | +| **AggregatingMergeTree** | 使用 AggregateFunction 列的增量聚合 | +| **Log / TinyLog** | 小表、开发和测试 | +| **Memory** | 临时数据的内存表 | +| **Distributed** | 跨集群分片查询 | + +### 排序键和分区键 + +ClickHouse 表按其排序键(表定义中的 ORDER BY 子句)排序。TablePro 在表结构视图中显示排序键、分区键和主键。这些对查询性能至关重要,因为 ClickHouse 按排序顺序读取数据。 + +### 数据跳跃索引 + +ClickHouse 支持在查询时跳过 granule 的二级索引。TablePro 在 Indexes 标签页中显示: + +```sql +-- 示例:URL 列上的 bloom filter 索引 +ALTER TABLE hits ADD INDEX url_idx url TYPE bloom_filter GRANULARITY 4; +``` + +### 查询进度追踪 + +查询执行期间,工具栏显示实时进度:已读取的行数和处理的字节数。完成后会显示总执行时间、已读取行数和字节数的汇总。这些数据从 `system.processes` 轮询获取。 + +### EXPLAIN 模式 + +ClickHouse 支持多种 EXPLAIN 模式。在查询编辑器中点击 Explain 下拉菜单选择: + +| 模式 | 描述 | +|---------|-------------| +| **Plan** | 逻辑查询计划(默认) | +| **Pipeline** | 带线程/端口信息的物理执行管道 | +| **AST** | 已解析查询的抽象语法树 | +| **Syntax** | 语法优化后的查询 | +| **Estimate** | 预计读取的行数、mark 数和 part 数 | + +### 服务端查询取消 + +当你取消正在运行的查询时,TablePro 会向 ClickHouse 服务器发送 `KILL QUERY` 命令。这会在服务端停止查询,而不仅仅是断开 HTTP 连接。 + +### 查询编辑器 + +在编辑器中编写和执行 ClickHouse SQL 查询: + +```sql +-- 聚合查询 +SELECT + toDate(event_time) AS date, + count() AS events, + uniqExact(user_id) AS unique_users +FROM analytics.events +WHERE event_time >= now() - INTERVAL 7 DAY +GROUP BY date +ORDER BY date; + +-- 系统表 +SELECT name, engine, total_rows, total_bytes +FROM system.tables +WHERE database = 'analytics'; + +-- 表分区 +SELECT partition, sum(rows) AS rows, formatReadableSize(sum(bytes_on_disk)) AS size +FROM system.parts +WHERE table = 'events' AND active +GROUP BY partition +ORDER BY partition; +``` + +### 数据编辑 + +TablePro 支持在 ClickHouse 表中编辑单元格值、插入行和删除行。编辑操作以标准的 INSERT、ALTER TABLE UPDATE 和 ALTER TABLE DELETE 语句提交。 + + +ClickHouse 的 mutation(UPDATE 和 DELETE)是异步的。它们在后台执行,对于大表可能需要一些时间才能完成。详见「限制」部分。 + + +### 导出与导入 + +将查询结果或表数据导出为 CSV、JSON 等格式。从 CSV 文件导入数据到 ClickHouse 表中。 + +## 系统数据库 + +ClickHouse 包含内置的系统数据库: + +| 数据库 | 描述 | +|----------|-------------| +| **system** | 服务器指标、查询日志、part 信息、集群状态 | +| **information_schema** | SQL 标准元数据视图(表、列、schema) | +| **INFORMATION_SCHEMA** | `information_schema` 的别名(大小写敏感变体) | + +`system` 数据库在监控方面特别有用: + +```sql +-- 最近的查询 +SELECT query, read_rows, elapsed, memory_usage +FROM system.query_log +WHERE type = 'QueryFinish' +ORDER BY event_time DESC +LIMIT 20; + +-- 按表统计磁盘使用量 +SELECT database, table, formatReadableSize(sum(bytes_on_disk)) AS size +FROM system.parts +WHERE active +GROUP BY database, table +ORDER BY sum(bytes_on_disk) DESC; +``` + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或超时 + +**原因及解决方案**: + +1. **ClickHouse 未运行或 HTTP 接口被禁用** + ```bash + # 检查 ClickHouse 是否在 8123 端口监听 + curl http://localhost:8123/ping + # 预期响应:"Ok." + ``` + +2. **端口错误** + - HTTP 接口:8123(默认) + - HTTPS 接口:8443 + - 原生 TCP:9000(TablePro 不使用) + +3. **配置中 HTTP 接口被禁用** + - 检查 `/etc/clickhouse-server/config.xml` 中的 `` + +### 认证失败 + +**症状**:"Authentication failed" 或 HTTP 403 + +**解决方案**: + +1. 验证 username 和 password +2. 检查用户是否存在: + ```sql + SELECT name, auth_type FROM system.users; + ``` +3. 验证用户是否有目标数据库的访问权限: + ```sql + SHOW GRANTS FOR app_user; + ``` + +### 连接超时 + +**症状**:连接挂起或超时 + +**解决方案**: + +1. 验证 host 和 port 是否正确 +2. 检查网络连通性和防火墙规则 +3. 对于云托管的 ClickHouse,确保你的 IP 在允许列表中 + +## 已知限制 + +- **无外键。** ClickHouse 不支持外键约束。引用完整性需要在应用层管理。 +- **无事务。** ClickHouse 没有多语句事务支持。每条语句独立执行。 +- **异步 mutation。** UPDATE 和 DELETE 操作通过 `ALTER TABLE UPDATE` 和 `ALTER TABLE DELETE` 作为后台 mutation 运行。它们不是即时的:对于大表,mutation 可能需要数秒到数分钟。检查 mutation 进度: + ```sql + SELECT * FROM system.mutations WHERE is_done = 0; + ``` +- **无自增。** ClickHouse 不支持自增列。 +- **主键不可变。** 表创建后不能更改主键和排序键。 +- **优化写入。** ClickHouse 为批量插入设计,不适合单行写入。逐行插入可以工作但效率不高。 + +## 后续步骤 + + + + 安全连接远程 ClickHouse 服务器 + + + 掌握查询编辑器功能 + + + 导入和导出 ClickHouse 数据 + + + 在数据网格中浏览和编辑数据 + + diff --git a/docs/zh/databases/connection-urls.mdx b/docs/zh/databases/connection-urls.mdx new file mode 100644 index 00000000..230e0db8 --- /dev/null +++ b/docs/zh/databases/connection-urls.mdx @@ -0,0 +1,219 @@ +--- +title: 连接 URL 参考 +description: 所有支持的数据库 URL scheme、格式和查询参数,适用于导入和直接连接 +--- + +# 连接 URL 参考 + +TablePro 解析标准的数据库连接 URL,用于导入连接、从浏览器或终端直接打开,以及配置 SSH tunnel。本页涵盖所有支持的 scheme、格式和查询参数。 + +## URL Scheme + +| Scheme | 数据库 | +|--------|----------| +| `postgresql://` | PostgreSQL | +| `postgres://` | PostgreSQL(别名) | +| `mysql://` | MySQL | +| `mariadb://` | MariaDB | +| `sqlite://` | SQLite | +| `mongodb://` | MongoDB | +| `mongodb+srv://` | MongoDB(SRV) | +| `redis://` | Redis | +| `rediss://` | Redis(TLS 加密) | +| `redshift://` | Amazon Redshift | +| `mssql://` | Microsoft SQL Server | +| `sqlserver://` | Microsoft SQL Server(别名) | +| `oracle://` | Oracle Database | +| `jdbc:oracle:thin:@//` | Oracle Database(JDBC thin) | + +在任意 scheme 后追加 `+ssh`(SQLite 除外)即可使用 SSH tunnel: + +``` +postgresql+ssh:// +mysql+ssh:// +mariadb+ssh:// +``` + +## 标准格式 + +``` +scheme://[username[:password]@]host[:port][/database][?param=value&...] +``` + +**示例:** + +``` +postgresql://alice:secret@db.example.com:5432/myapp +mysql://root@localhost/shop +mongodb://user:pass@mongo.host:27017/analytics?authSource=admin +redis://:password@cache.host:6379/1 +sqlite:///Users/alice/data/local.db +``` + + +密码中包含特殊字符(`@`、`#`、`%`、`:`)时必须进行 percent-encoding。例如 `p@ss#word` 应写为 `p%40ss%23word`。 + + +## SSH Tunnel 格式 + +SSH tunnel URL 将 SSH 和数据库凭据编码在同一个字符串中: + +``` +scheme+ssh://[ssh_user@]ssh_host[:ssh_port]/[db_user[:db_pass]@]db_host[:db_port][/database][?params] +``` + +**示例:** + +``` +postgresql+ssh://deploy@bastion.host:22/dbuser:dbpass@internal-pg:5432/mydb +mysql+ssh://ec2-user@jump.host/root:secret@10.0.0.5/shop +mariadb+ssh://admin@ssh.host/maria_user@db.internal/store?usePrivateKey=true +``` + +如果省略 `db_host`,默认为 `127.0.0.1`。 + +## 查询参数 + +### 连接标识 + +| 参数 | 描述 | 示例 | +|-----------|-------------|---------| +| `name` | 覆盖侧栏中显示的连接名称 | `?name=Production+DB` | + +### SSL / TLS + +| 参数 | 值 | 描述 | +|-----------|--------|-------------| +| `sslmode` | `disable`、`prefer`、`require`、`verify-ca`、`verify-full` | SSL 模式(标准 PostgreSQL 命名) | +| `tlsmode` | `0`--`4` | SSL 模式(整数形式):0=disable、1=prefer、2=require、3=verify-ca、4=verify-full | + +**示例:** + +``` +postgresql://user:pass@host/db?sslmode=require +postgresql://user:pass@host/db?tlsmode=2 +``` + +### 导航 + +这些参数在连接后立即打开指定的表、视图或 schema。 + +| 参数 | 描述 | 示例 | +|-----------|-------------|---------| +| `table` | 打开指定的表 | `?table=users` | +| `view` | 打开指定的视图 | `?view=active_orders` | +| `schema` | 在打开前切换到此 schema(仅 PostgreSQL/Redshift) | `?schema=reporting` | + +**示例:** + +``` +postgresql://user:pass@host/mydb?schema=reporting&table=monthly_sales +``` + +### 过滤 + +自动对打开的表应用过滤条件。 + +| 参数 | 描述 | 示例 | +|-----------|-------------|---------| +| `column` | 要过滤的列名 | `?column=status` | +| `operation` | 过滤操作符(如 `=`、`!=`、`LIKE`) | `?operation=LIKE` | +| `value` | 过滤值 | `?value=active` | +| `condition` | 原始 SQL WHERE 条件(覆盖 column/operation/value) | `?condition=status%3D'active'+AND+role%3D'admin'` | + +`raw` 和 `query` 是 `condition` 的别名。 + +**示例:** + +``` +postgresql://user:pass@host/mydb?table=orders&column=status&operation==&value=pending +postgresql://user:pass@host/mydb?table=orders&condition=total%3E1000 +``` + +### 外观 + +| 参数 | 描述 | 示例 | +|-----------|-------------|---------| +| `statusColor` | 为连接分配颜色(十六进制值,匹配最接近的调色板颜色) | `?statusColor=FF3B30` | +| `env` | 按名称分配已有标签 | `?env=production` | + +**示例:** + +``` +postgresql://user:pass@host/db?statusColor=FF3B30&env=production +``` + +### MongoDB + +| 参数 | 描述 | +|-----------|-------------| +| `authSource` | 认证数据库(默认为 `admin`) | + +**示例:** + +``` +mongodb://user:pass@host:27017/mydb?authSource=admin +``` + +### Redis + +路径部分设置数据库索引(0--15)。`rediss://` scheme 自动启用 TLS。 + +``` +redis://:password@host:6379/2 # 数据库索引 2 +rediss://:password@host:6380 # TLS,默认索引 0 +``` + +### SSH Tunnel + +| 参数 | 描述 | +|-----------|-------------| +| `usePrivateKey` | 设为 `true` 使用密钥认证而非密码 | + +**示例:** + +``` +postgresql+ssh://ubuntu@bastion/dbuser@10.0.0.5/mydb?usePrivateKey=true +``` + +## 直接打开 URL 的工作原理 + +从浏览器或终端打开数据库 URL 时,TablePro 会自动处理: + +1. **匹配已保存连接**:如果 host、port、database 和 username 都匹配已有的保存连接,TablePro 使用该连接(包括已保存的密码) +2. **未匹配**:TablePro 创建一个临时会话。URL 中的密码在会话期间存储在 Keychain 中,但连接不会保存到列表中 + +从终端打开 URL: + +```bash +open "postgresql://user:pass@localhost:5432/mydb" +open "mysql://root@localhost/shop?table=products" +open "postgresql+ssh://ubuntu@bastion/user:pass@10.0.0.5/mydb?usePrivateKey=true" +``` + + +如需永久保存连接,请使用 New Connection 表单中的 **Import from URL**。它会填充所有字段供你检查并点击 **Create** 保存。 + + +## 完整示例 + +一个通过 SSH 连接、打开特定 schema 和表、预设过滤条件并设置颜色标签的 URL: + +``` +postgresql+ssh://deploy@bastion.example.com:22/dbuser:dbpass@10.0.1.5:5432/analytics?schema=public&table=events&column=type&value=purchase&statusColor=FF9500&env=staging +``` + +分解如下: + +| 部分 | 值 | +|------|-------| +| SSH user | `deploy` | +| SSH host | `bastion.example.com:22` | +| DB user / pass | `dbuser` / `dbpass` | +| DB host / port | `10.0.1.5:5432` | +| Database | `analytics` | +| Schema | `public` | +| Table | `events` | +| Filter | `type = purchase` | +| Color | 橙色(`FF9500`) | +| Tag | `staging` | diff --git a/docs/zh/databases/duckdb.mdx b/docs/zh/databases/duckdb.mdx new file mode 100644 index 00000000..9c7697bf --- /dev/null +++ b/docs/zh/databases/duckdb.mdx @@ -0,0 +1,101 @@ +--- +title: DuckDB +description: 使用 TablePro 连接 DuckDB 数据库 +--- + +# DuckDB + +DuckDB 是一个嵌入式分析数据库,针对 OLAP 工作负载进行了优化。TablePro 支持连接 DuckDB 数据库文件,用于浏览表、执行查询和管理 schema。 + +## 连接 DuckDB 数据库 + + + + 打开 TablePro 并点击 **New Connection** 或按 Cmd+N。 + + + 从数据库类型列表中选择 **DuckDB**。 + + + 点击 **Browse** 选择一个已有的 `.duckdb` 文件,或输入路径创建新数据库。 + + + 点击 **Connect** 打开数据库。 + + + +## 从 Finder 打开 DuckDB 文件 + +在 Finder 中双击任意 `.duckdb` 文件即可直接在 TablePro 中打开。 + +## 直接查询文件 + +DuckDB 可以用 SQL 直接查询 CSV、Parquet 和 JSON 文件: + +```sql +-- 查询 CSV 文件 +SELECT * FROM 'data.csv'; + +-- 查询 Parquet 文件 +SELECT * FROM read_parquet('analytics.parquet'); + +-- 查询 JSON 文件 +SELECT * FROM read_json('config.json'); +``` + +## Schema 支持 + +DuckDB 在单个数据库中支持多个 schema。默认 schema 是 `main`。使用工具栏中的 schema 切换器在不同 schema 之间导航。 + +```sql +-- 创建新的 schema +CREATE SCHEMA analytics; + +-- 在特定 schema 中创建表 +CREATE TABLE analytics.events ( + id INTEGER PRIMARY KEY, + event_name VARCHAR, + created_at TIMESTAMP +); +``` + +## DuckDB 扩展 + +DuckDB 拥有丰富的扩展生态系统。使用 SQL 安装和加载扩展: + +```sql +-- 安装扩展 +INSTALL httpfs; + +-- 加载扩展 +LOAD httpfs; + +-- 查询远程 Parquet 文件 +SELECT * FROM read_parquet('https://example.com/data.parquet'); +``` + +## 数据类型 + +DuckDB 支持广泛的数据类型: + +| 类别 | 类型 | +|----------|-------| +| 数值 | `INTEGER`、`BIGINT`、`HUGEINT`、`DOUBLE`、`FLOAT`、`DECIMAL` | +| 字符串 | `VARCHAR`、`TEXT`、`CHAR` | +| 日期/时间 | `DATE`、`TIME`、`TIMESTAMP`、`INTERVAL` | +| 复合类型 | `LIST`、`MAP`、`STRUCT`、`UNION`、`ENUM` | +| 其他 | `BOOLEAN`、`BLOB`、`UUID`、`JSON`、`BIT` | + +## 限制 + +- DuckDB 是嵌入式数据库,没有网络服务器可供连接。 +- 同一时间只有一个进程可以写入 DuckDB 文件。 + + + + 学习键盘快捷键以加速操作 + + + 编写和执行 SQL 查询 + + diff --git a/docs/zh/databases/mongodb.mdx b/docs/zh/databases/mongodb.mdx new file mode 100644 index 00000000..2ddaccff --- /dev/null +++ b/docs/zh/databases/mongodb.mdx @@ -0,0 +1,404 @@ +--- +title: MongoDB +description: 连接 MongoDB 5.0+,支持 MQL shell 查询、集合浏览和 BSON 类型显示 +--- + +# MongoDB 连接 + +TablePro 支持 MongoDB 5.0 及更高版本。集合在侧栏中以表的形式显示。文档的字段作为列展示,嵌套对象渲染为格式化的 JSON。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **MongoDB** + + + 填写 host、port、认证数据库、username 和 password + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP | `localhost` | +| **Port** | MongoDB 服务器端口 | `27017` | +| **Database** | 要连接的数据库名称 | - | + +### 可选字段 + +| 字段 | 描述 | +|-------|-------------| +| **Username** | 用于认证的 MongoDB 用户名 | +| **Password** | 用户密码 | +| **Auth Database** | 认证数据库(默认为 `admin`) | + + +对于没有启用认证的本地开发环境,可以留空 username 和 password 字段。 + + +### 高级设置 + +在 **Advanced** 标签页中配置 read preference 和 write concern。这些设置仅适用于 MongoDB 连接。 + +| 字段 | 描述 | 选项 | +|-------|-------------|---------| +| **Read Preference** | 控制哪些 replica set 成员接收读操作 | Default、Primary、Primary Preferred、Secondary、Secondary Preferred、Nearest | +| **Write Concern** | 控制写操作的确认级别 | Default、Majority、1、2、3 | + + +默认设置适用于大多数场景。使用 **Secondary Preferred** 或 **Nearest** 可以将读负载分散到 replica 成员之间。使用 **Majority** write concern 可以获得更强的持久性保证。 + + +{/* Screenshot: MongoDB connection form */} + + MongoDB 连接表单 + MongoDB 连接表单 + + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local MongoDB +Host: localhost +Port: 27017 +Username: (留空) +Password: (留空) +Database: myapp +``` + +### Docker MongoDB 容器 + +``` +Name: Docker MongoDB +Host: localhost +Port: 27017(或你映射的端口) +Username: root +Password: (来自 MONGO_INITDB_ROOT_PASSWORD 的密码) +Database: admin +``` + +### MongoDB Atlas + +``` +Name: Atlas Cluster +Host: cluster0.abc123.mongodb.net +Port: 27017 +Username: atlas_user +Password: (你的 Atlas 密码) +Database: myapp +``` + + +MongoDB Atlas 要求 SSL/TLS。请在连接表单的 SSL/TLS 部分启用。 + + +### 远程服务器 + +``` +Name: Production DB +Host: db.example.com +Port: 27017 +Username: app_user +Password: (安全密码) +Database: production +``` + + +对于生产数据库,建议使用 [SSH tunneling](/zh/databases/ssh-tunneling) 进行安全连接。 + + +## SSL/TLS 连接 + +在连接表单的 **SSL/TLS** 部分配置 SSL。 + +| SSL 模式 | 描述 | +|----------|-------------| +| **Disabled** | 不使用 SSL 加密 | +| **Required** | 要求 SSL 加密 | +| **Verify CA** | 要求 SSL 并验证服务器证书是否由 CA 签发 | + +对于 **Verify CA** 模式,需要提供 CA 证书文件路径。也可以提供可选的客户端证书和密钥文件以实现 mutual TLS。 + + +MongoDB Atlas 始终要求 SSL/TLS。连接 Atlas 集群时使用 **Required** 或 **Verify CA**。 + + + +如果不想配置 SSL 证书,[SSH tunneling](/zh/databases/ssh-tunneling) 可以通过 SSH tunnel 加密所有流量。 + + +{/* Screenshot: MongoDB SSL/TLS configuration */} + + MongoDB SSL/TLS 配置 + MongoDB SSL/TLS 配置 + + +## SSH Tunnel 支持 + +通过 SSH tunnel 连接 MongoDB 以安全访问远程服务器。设置方法请参阅 [SSH Tunneling](/zh/databases/ssh-tunneling)。 + +## 功能 + +### 集合浏览 + +连接后,侧栏显示所选数据库中的所有集合: + +1. 点击侧栏中的连接名称 +2. 展开数据库查看其集合 +3. 点击集合查看其文档 + +{/* Screenshot: Sidebar showing MongoDB collections */} + + 集合浏览器 + 集合浏览器 + + +### 文档查看 + +文档在数据网格中以字段作为列的方式显示: + +- **顶层字段** 显示为独立的列 +- **嵌套对象** 渲染为格式化的 JSON 字符串 +- **数组** 显示为 JSON 数组 +- **ObjectId** 值显示为其字符串表示 +- **BSON 类型**(Date、Decimal128、Binary 等)以适当的格式渲染 + + +Schema 通过采样集合中的文档来推断。列反映了所有采样文档中找到的字段的并集。 + + +### 集合复制 + +复制现有集合,包括所有文档和索引: + +1. 打开 **Create Table** 对话框 +2. 点击工具栏中的 **Duplicate** +3. 从列表中选择源集合 +4. TablePro 使用 `aggregate` 配合 `$out` 复制所有文档,并重建非主索引 + +复制的集合命名为 `originalName_copy`(如果名称已存在则添加数字后缀)。 + +### MongoDB Shell 查询 + +在编辑器中使用 MongoDB Shell(MQL)语法执行查询: + +```javascript +// 带过滤的文档查找 +db.users.find({ age: { $gte: 18 }, active: true }) + +// 带投影和排序的查找 +db.orders.find( + { status: "completed" }, + { customerId: 1, total: 1, date: 1 } +).sort({ date: -1 }).limit(20) + +// 聚合管道 +db.sales.aggregate([ + { $match: { date: { $gte: ISODate("2025-01-01") } } }, + { $group: { _id: "$product", totalSales: { $sum: "$amount" } } }, + { $sort: { totalSales: -1 } }, + { $limit: 10 } +]) + +// 文档计数 +db.users.countDocuments({ role: "admin" }) + +// 去重值 +db.products.distinct("category") +``` + +### CRUD 操作 + +#### 插入文档 + +```javascript +// 插入单个文档 +db.users.insertOne({ + name: "John Doe", + email: "john@example.com", + age: 30, + tags: ["developer", "admin"] +}) + +// 插入多个文档 +db.users.insertMany([ + { name: "Alice", email: "alice@example.com" }, + { name: "Bob", email: "bob@example.com" } +]) +``` + +#### 更新文档 + +```javascript +// 更新单个文档 +db.users.updateOne( + { email: "john@example.com" }, + { $set: { age: 31, updatedAt: new Date() } } +) + +// 更新多个文档 +db.users.updateMany( + { active: false }, + { $set: { status: "inactive" } } +) +``` + +#### 删除文档 + +```javascript +// 删除单个文档 +db.users.deleteOne({ email: "john@example.com" }) + +// 删除多个文档 +db.users.deleteMany({ active: false, lastLogin: { $lt: ISODate("2024-01-01") } }) +``` + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或 "couldn't connect to server" + +**原因及解决方案**: + +1. **MongoDB 服务器未运行** + ```bash + # 检查 MongoDB 是否运行 + mongosh --eval "db.runCommand({ ping: 1 })" + + # 启动 MongoDB(macOS Homebrew) + brew services start mongodb-community + ``` + +2. **端口错误** + - 检查 MongoDB 配置文件(`mongod.conf`)中的端口 + - 检查你的配置 + +3. **MongoDB 未监听预期地址** + - 检查 `mongod.conf` 中的 `bindIp` + - 对于远程连接,添加客户端 IP 或使用 `0.0.0.0` + +### 认证失败 + +**症状**:"Authentication failed" 或 "command find requires authentication" + +**解决方案**: + +1. 验证 username、password 和认证数据库 +2. 检查用户角色: + ```javascript + db.getUsers() + ``` +3. 创建或更新用户凭据: + ```javascript + db.createUser({ + user: "appuser", + pwd: "password", + roles: [{ role: "readWrite", db: "myapp" }] + }) + ``` + +### 连接超时 + +**症状**:连接挂起或超时 + +**解决方案**: + +1. 验证 host 和 port 是否正确 +2. 检查网络连通性和防火墙规则 +3. 对于 MongoDB Atlas,确保你的 IP 已在 Network Access 设置中加入白名单 + +## 已知限制 + +- **事务**:多文档事务需要 replica set 或分片集群。独立实例不支持事务。 +- **Schema 推断**:由于 MongoDB 是无 schema 的,列结构通过采样文档推断。文档结构差异很大的集合可能无法显示所有字段。 +- **固定大小集合**:对 capped collection 的某些操作(更新、删除)可能受限。 +- **GridFS**:GridFS 文件存储不能通过集合浏览器直接浏览。 +- **Change Streams**:当前版本不支持实时 change stream。 + +## 性能建议 + +### 大型集合 + +对于有数百万文档的集合: + +1. 在查询中始终使用过滤条件或 `limit()` +2. 在数据网格设置中启用分页 +3. 为常见查询模式创建适当的索引 + +### 索引管理 + +监控和创建索引以提升性能: + +```javascript +// 列出现有索引 +db.users.getIndexes() + +// 创建索引 +db.users.createIndex({ email: 1 }, { unique: true }) + +// 创建复合索引 +db.orders.createIndex({ customerId: 1, date: -1 }) +``` + +### 查询分析 + +使用 `explain()` 了解查询性能: + +```javascript +db.users.find({ age: { $gte: 18 } }).explain("executionStats") +``` + +## 后续步骤 + + + + 安全连接远程 MongoDB 服务器 + + + 掌握查询编辑器功能 + + + 导入和导出 MongoDB 数据 + + + 在数据网格中浏览和编辑文档 + + diff --git a/docs/zh/databases/mssql.mdx b/docs/zh/databases/mssql.mdx new file mode 100644 index 00000000..882d5e50 --- /dev/null +++ b/docs/zh/databases/mssql.mdx @@ -0,0 +1,290 @@ +--- +title: Microsoft SQL Server +description: 通过 FreeTDS 连接 SQL Server 2017+ 和 Azure SQL Database,支持 T-SQL 查询 +--- + +# Microsoft SQL Server 连接 + +TablePro 通过 FreeTDS 连接 SQL Server 2017 及更高版本。涵盖 Windows、Linux、Docker 和 Azure SQL Database 上的实例。 + + +连接 SQL Server 之前需要构建 FreeTDS。运行一次 `scripts/build-freetds.sh` 编译所需的库。 + + +## 快速设置 + + + + 如果尚未构建,从仓库根目录运行 `scripts/build-freetds.sh` + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **SQL Server** + + + 填写 host、port、username、password 和数据库名称 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP 地址 | `localhost` | +| **Port** | SQL Server 端口 | `1433` | +| **Username** | SQL Server 登录名 | `sa` | +| **Password** | 登录密码 | - | +| **Database** | 要连接的数据库名称 | - | + + +TablePro 使用 SQL Server Authentication(用户名和密码)。不支持 Windows Authentication。 + + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local SQL Server +Host: localhost +Port: 1433 +Username: sa +Password: (你的密码) +Database: master +``` + +### Docker SQL Server 容器 + +启动一个 SQL Server 2022 容器用于本地测试: + +```bash +docker run \ + -e "ACCEPT_EULA=Y" \ + -e "SA_PASSWORD=YourStrong@Passw0rd" \ + -p 1433:1433 \ + --name sql-server \ + -d mcr.microsoft.com/mssql/server:2022-latest +``` + +然后用以下信息连接: + +``` +Name: Docker SQL Server +Host: localhost +Port: 1433 +Username: sa +Password: YourStrong@Passw0rd +Database: master +``` + + +`SA_PASSWORD` 必须满足 SQL Server 的复杂性要求:至少 8 个字符,包含大写、小写、数字和符号。 + + +### 远程服务器 + +``` +Name: Production SQL Server +Host: sql.example.com +Port: 1433 +Username: app_user +Password: (安全密码) +Database: myapp_production +``` + +### Azure SQL Database + +``` +Name: Azure SQL +Host: myserver.database.windows.net +Port: 1433 +Username: admin@myserver +Password: (你的密码) +Database: mydb +``` + + +Azure SQL Database 可能要求用户名包含服务器后缀(如 `user@servername`),具体取决于你的认证配置。 + + +## 功能 + +### Schema 选择 + +SQL Server 在数据库内将对象组织到 schema 中。默认 schema 是 `dbo`。TablePro 显示你的登录有权访问的所有 schema,并列出每个 schema 中的表。 + +使用数据库切换器(**Cmd+K**)切换 schema,它会显示当前数据库可用的 schema。 + +### 表浏览 + +每个表显示以下内容: + +- **Structure**:列及其 SQL Server 数据类型、可空性和默认值 +- **Indexes**:聚集索引和非聚集索引 +- **Foreign Keys**:与其他表的关系 +- **DDL**:包含约束的表定义 + +### 查询编辑器 + +在 SQL 编辑器中编写和执行 T-SQL。分页使用 SQL Server 的标准 offset 语法: + +```sql +-- 分页结果 +SELECT * +FROM dbo.orders +ORDER BY order_id +OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY; + +-- 行数估算(快速,使用统计信息) +SELECT SUM(p.rows) AS row_count +FROM sys.partitions p +JOIN sys.tables t ON p.object_id = t.object_id +WHERE p.index_id IN (0, 1) + AND t.name = 'orders'; + +-- 查看视图定义 +SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.my_view')); + +-- 列出当前数据库中的所有表 +SELECT TABLE_SCHEMA, TABLE_NAME +FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE = 'BASE TABLE' +ORDER BY TABLE_SCHEMA, TABLE_NAME; +``` + +### Schema 编辑 + +通过 T-SQL ALTER TABLE 修改表结构。SQL Server 使用方括号表示标识符: + +```sql +-- 添加列 +ALTER TABLE [dbo].[users] ADD [last_login] DATETIME2 NULL; + +-- 重命名列(需要 sp_rename) +EXEC sp_rename 'dbo.users.old_name', 'new_name', 'COLUMN'; + +-- 删除列 +ALTER TABLE [dbo].[users] DROP COLUMN [legacy_field]; + +-- 添加索引 +CREATE INDEX [IX_users_email] ON [dbo].[users] ([email]); +``` + +### 外键 + +TablePro 在表结构视图中显示外键关系。手动查看外键: + +```sql +SELECT + fk.name AS fk_name, + OBJECT_NAME(fk.parent_object_id) AS parent_table, + COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS parent_column, + OBJECT_NAME(fk.referenced_object_id) AS referenced_table, + COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column +FROM sys.foreign_keys fk +JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id +ORDER BY parent_table, fk_name; +``` + +## 认证 + +TablePro 仅使用 SQL Server Authentication。在连接表单中提供 SQL Server 登录名和密码。 + +**不支持 Windows Authentication**(集成安全/Kerberos)。 + +创建 SQL Server 登录: + +```sql +-- 创建登录 +CREATE LOGIN app_user WITH PASSWORD = 'StrongPassword1!'; + +-- 为该登录创建数据库用户 +USE mydb; +CREATE USER app_user FOR LOGIN app_user; + +-- 授予权限 +ALTER ROLE db_datareader ADD MEMBER app_user; +ALTER ROLE db_datawriter ADD MEMBER app_user; +``` + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Unable to connect" 或连接超时 + +**原因及解决方案**: + +1. **SQL Server 未运行或未接受 TCP 连接** + + SQL Server Browser 和 TCP/IP 协议必须启用: + - 打开 SQL Server Configuration Manager + - 在「SQL Server Network Configuration」下启用 TCP/IP + - 确保 SQL Server 服务正在运行 + +2. **1433 端口被防火墙阻止** + - 对于 Windows Firewall,添加 TCP 端口 1433 的入站规则 + - 对于云 VM,检查安全组/防火墙规则 + +3. **Docker 容器未启动** + ```bash + docker start sql-server + docker logs sql-server + ``` + +### 登录失败 + +**症状**:"Login failed for user" 错误 + +**解决方案**: + +1. 验证用户名和密码 +2. 确认 SQL Server Authentication 已启用(不是仅 Windows 模式): + ```sql + -- 检查服务器认证模式(1 = 仅 Windows,2 = 混合模式) + SELECT SERVERPROPERTY('IsIntegratedSecurityOnly'); + ``` +3. 在 SQL Server Management Studio 的 Server Properties > Security 中启用混合模式认证,然后重启 SQL Server 服务 + +### 未找到 FreeTDS + +**症状**:"FreeTDS library not found" 或启动时的链接错误 + +**解决方案**:从仓库根目录运行构建脚本: + +```bash +scripts/build-freetds.sh +``` + +这会编译 FreeTDS 并将静态库放置在 Xcode 项目期望的位置。 + +## 已知限制 + +- **不支持 Windows Authentication。** 仅 SQL Server Authentication(用户名 + 密码)可用。 +- **不支持命名实例**(如 `HOSTNAME\INSTANCENAME`)。请通过 IP 地址和明确的端口连接。 +- **`NTEXT`、`TEXT`、`IMAGE` 列**(自 SQL Server 2005 起已弃用)编辑支持有限。在新的 schema 中请使用 `NVARCHAR(MAX)`、`VARCHAR(MAX)` 和 `VARBINARY(MAX)`。 + +## 后续步骤 + + + + 安全连接远程 SQL Server 实例 + + + 掌握 SQL 编辑器功能 + + + 编辑行并通过 SQL 预览保存更改 + + + 查看和修改表结构 + + diff --git a/docs/zh/databases/mysql.mdx b/docs/zh/databases/mysql.mdx new file mode 100644 index 00000000..98f5b80e --- /dev/null +++ b/docs/zh/databases/mysql.mdx @@ -0,0 +1,351 @@ +--- +title: MySQL & MariaDB +description: 通过相同的 MariaDB C connector 驱动连接 MySQL 5.7+/8.0+ 和 MariaDB 10.x+ +--- + +# MySQL & MariaDB 连接 + +TablePro 支持 MySQL 5.7+、MySQL 8.0+ 和 MariaDB 10.x+。两种数据库共享兼容的协议,使用相同的连接界面。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从类型选择器中选择 **MySQL** 或 **MariaDB** + + + 填写 host、port、username、password,以及可选的默认数据库 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP | `localhost` | +| **Port** | MySQL 服务器端口 | `3306` | +| **Username** | MySQL 用户名 | `root` | +| **Password** | 用户密码 | - | + +### 可选字段 + +| 字段 | 描述 | +|-------|-------------| +| **Database** | 连接后使用的默认数据库 | + + +留空数据库字段会显示该用户有权访问的所有数据库。 + + + +你也可以通过在浏览器或终端中打开 `mysql://` 或 `mariadb://` URL 来连接。详见 [连接 URL 参考](/zh/databases/connection-urls)。 + + +{/* Screenshot: MySQL connection form */} + + MySQL 连接表单 + MySQL 连接表单 + + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local MySQL +Host: localhost +Port: 3306 +Username: root +Password: (你的密码) +Database: (留空) +``` + +### Docker MySQL 容器 + +``` +Name: Docker MySQL +Host: localhost +Port: 3306(或你映射的端口) +Username: root +Password: (来自 MYSQL_ROOT_PASSWORD 的密码) +Database: (留空) +``` + +### MAMP Pro + +``` +Name: MAMP MySQL +Host: localhost +Port: 8889(MAMP 默认端口) +Username: root +Password: root +Database: (留空) +``` + +### 远程服务器 + +``` +Name: Production DB +Host: db.example.com +Port: 3306 +Username: app_user +Password: (安全密码) +Database: production +``` + + +对于生产数据库,建议使用 [SSH tunneling](/zh/databases/ssh-tunneling) 进行安全连接。 + + +## MySQL 与 MariaDB 的区别 + +TablePro 对两者使用相同的驱动。以下是一些差异: + +| 特性 | MySQL 8.0 | MariaDB 10.x | +|---------|-----------|--------------| +| 默认认证方式 | `caching_sha2_password` | `mysql_native_password` | +| JSON 支持 | 原生 | 兼容 | +| Window functions | 支持 | 支持 | +| CTEs | 支持 | 支持 | + + +如果遇到 MySQL 8.0 的认证问题,请参阅 [认证问题排查](#mysql-80-认证) 部分。 + + +## 功能 + +### 浏览数据库 + +连接后,侧栏显示该用户可访问的所有数据库: + +1. 点击侧栏中的连接名称 +2. 展开数据库查看其表 +3. 点击表查看内容 + +{/* Screenshot: Sidebar showing expanded MySQL database with tables */} + + 数据库浏览器 + 数据库浏览器 + + +### 表信息 + +每个表显示以下内容: + +- **Structure**:列定义、类型和约束 +- **Indexes**:所有索引,包括主键 +- **Foreign Keys**:与其他表的关系 +- **DDL**:CREATE TABLE 语句 + +### 查询执行 + +完整支持 MySQL 语法: + +```sql +-- JSON 查询 +SELECT id, JSON_EXTRACT(data, '$.name') as name +FROM users +WHERE JSON_CONTAINS(roles, '"admin"'); + +-- Window functions +SELECT + department, + employee, + salary, + RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank +FROM employees; + +-- CTEs +WITH RECURSIVE category_tree AS ( + SELECT id, name, parent_id, 0 as level + FROM categories WHERE parent_id IS NULL + UNION ALL + SELECT c.id, c.name, c.parent_id, ct.level + 1 + FROM categories c + JOIN category_tree ct ON c.parent_id = ct.id +) +SELECT * FROM category_tree; +``` + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或 "Can't connect to MySQL server" + +**原因及解决方案**: + +1. **MySQL 服务器未运行** + ```bash + # 检查 MySQL 是否运行 + mysqladmin ping -h localhost -u root -p + + # 启动 MySQL(macOS Homebrew) + brew services start mysql + ``` + +2. **端口错误** + - 在 MySQL 中验证端口:`SHOW VARIABLES LIKE 'port';` + - 检查配置文件 + +3. **MySQL 未监听 TCP** + - 检查 `my.cnf` 中是否设置了 `skip-networking` + - 确保 `bind-address` 包含你的客户端 IP + +### 访问被拒绝 + +**症状**:"Access denied for user 'xxx'@'localhost'" + +**解决方案**: + +1. 验证用户名和密码 +2. 检查用户权限: + ```sql + SHOW GRANTS FOR 'username'@'localhost'; + ``` +3. 授予必要权限: + ```sql + GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'localhost'; + FLUSH PRIVILEGES; + ``` + +### MySQL 8.0 认证 + +MySQL 8.0 默认使用 `caching_sha2_password`,可能导致连接问题。 + +**方案一**:为特定用户使用 native password +```sql +ALTER USER 'username'@'localhost' +IDENTIFIED WITH mysql_native_password BY 'password'; +``` + +**方案二**:更改默认认证方式 +```ini +# 在 my.cnf 中 +[mysqld] +default_authentication_plugin=mysql_native_password +``` + +### SSL/TLS 连接 + +在连接表单的 **SSL/TLS** 部分配置 SSL。 + +| SSL 模式 | MySQL 行为 | +|----------|----------------| +| **Disabled** | 明确禁用 SSL | +| **Preferred** | 如果服务器支持则使用 SSL,否则回退到非加密连接 | +| **Required** | 强制 SSL 加密(`MYSQL_OPT_SSL_ENFORCE`) | +| **Verify CA** | 强制 SSL 并验证服务器证书是否由 CA 签发 | +| **Verify Identity** | 强制 SSL,验证 CA 和服务器主机名 | + +对于 **Verify CA** 和 **Verify Identity** 模式,需要提供 CA 证书文件路径。可选提供客户端证书和密钥文件以实现 mutual TLS。 + + +大多数云端 MySQL 服务商(AWS RDS、Google Cloud SQL、Azure)都要求 SSL。使用 **Verify CA** 配合服务商提供的 CA 证书以获得最佳安全性。 + + + +如果不需要 SSL 但想加密连接,[SSH tunneling](/zh/databases/ssh-tunneling) 可以通过 SSH tunnel 加密所有流量。 + + +{/* Screenshot: MySQL SSL/TLS configuration */} + + MySQL SSL/TLS 配置 + MySQL SSL/TLS 配置 + + +## 性能建议 + +### 大型结果集 + +对于有数百万行的表: + +1. 在查询中使用 `LIMIT` +2. 在数据网格设置中启用分页 +3. 为常见查询创建适当的索引 + +### 复杂查询 + +1. 使用 `EXPLAIN` 分析查询计划: + ```sql + EXPLAIN SELECT * FROM users WHERE email LIKE '%@example.com'; + ``` + +2. 在结果面板中监控查询执行时间 + +## 启动命令 + +设置每次连接时自动应用的会话变量。在连接表单的 **Advanced** 标签页中配置。 + +常用的 MySQL 启动命令: + +```sql +SET time_zone = '+00:00'; +SET NAMES utf8mb4; +SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE'; +SET group_concat_max_len = 1000000; +``` + +例如,设置 `time_zone` 可以确保所有 `DATETIME` 和 `TIMESTAMP` 查询返回 UTC 结果,不受服务器配置时区的影响。当应用服务器和数据库服务器位于不同时区时特别有用。 + +详见 [启动命令](/zh/databases/overview#启动命令)。 + +## 字符集 + +TablePro 默认使用 UTF-8(utf8mb4)连接 MySQL,可以正确处理国际字符、emoji 和特殊符号。 + +如果遇到编码问题,请检查表/列的字符集: + +```sql +SHOW CREATE TABLE table_name; +``` + +## 后续步骤 + + + + 安全连接远程 MySQL 服务器 + + + 掌握 SQL 编辑器功能 + + + 导入和导出 MySQL 数据 + + + 查看和修改表结构 + + diff --git a/docs/zh/databases/oracle.mdx b/docs/zh/databases/oracle.mdx new file mode 100644 index 00000000..55b9f709 --- /dev/null +++ b/docs/zh/databases/oracle.mdx @@ -0,0 +1,303 @@ +--- +title: Oracle Database +description: 使用 TablePro 连接 Oracle Database +--- + +# Oracle Database 连接 + +TablePro 通过 Oracle Call Interface(OCI)支持 Oracle Database 12c 及更高版本。涵盖本地部署、Docker 和 Oracle Cloud 上的 Oracle Database 实例。 + + +连接 Oracle Database 之前必须安装 Oracle Instant Client。从 [Oracle 官网](https://www.oracle.com/database/technologies/instant-client.html) 下载并确保库文件可被访问。 + + +## 安装插件 + +Oracle 驱动以可下载插件的形式提供。当你在连接表单中选择 Oracle 时,TablePro 会提示你自动安装。你也可以手动安装: + +1. 打开 **Settings** > **Plugins** > **Browse** +2. 找到 **Oracle Driver** 并点击 **Install** +3. 插件会立即下载和加载,无需重启 + +## 快速设置 + + + + 下载并安装适用于 macOS 的 Oracle Instant Client Basic 包 + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **Oracle** + + + 填写 host、port、username、password 和 service name + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP 地址 | `localhost` | +| **Port** | Oracle listener 端口 | `1521` | +| **Username** | Oracle 用户名 | - | +| **Password** | 用户密码 | - | +| **Service Name** | Oracle service name(如 `ORCL`、`XEPDB1`) | - | + + +TablePro 使用 Oracle service name 连接,而非 SID。如果你有 SID,请查看 `tnsnames.ora` 获取对应的 service name,或者直接用 SID 作为 service name(在大多数配置下可行)。 + + +## 配置示例 + +### 本地开发(Oracle XE) + +``` +Name: Local Oracle XE +Host: localhost +Port: 1521 +Username: system +Password: (你的密码) +Service Name: XEPDB1 +``` + +### Docker Oracle 容器 + +启动一个 Oracle XE 21c 容器用于本地测试: + +```bash +docker run \ + -e ORACLE_PASSWORD=YourStrong@Passw0rd \ + -p 1521:1521 \ + --name oracle-xe \ + -d gvenzl/oracle-xe:21-slim +``` + +然后用以下信息连接: + +``` +Name: Docker Oracle XE +Host: localhost +Port: 1521 +Username: system +Password: YourStrong@Passw0rd +Service Name: XEPDB1 +``` + + +`gvenzl/oracle-xe` Docker 镜像是社区维护的轻量级 Oracle XE 镜像,非常适合本地开发和测试。 + + +### 远程服务器 + +``` +Name: Production Oracle +Host: oracle.example.com +Port: 1521 +Username: app_user +Password: (安全密码) +Service Name: PRODDB +``` + +### Oracle Cloud(Autonomous Database) + +``` +Name: Oracle Cloud ADB +Host: adb.region.oraclecloud.com +Port: 1522 +Username: ADMIN +Password: (你的密码) +Service Name: mydb_tp +``` + + +Oracle Autonomous Database 默认使用 1522 端口并要求 TLS。从 Oracle Cloud Console 下载 wallet 用于 mTLS 连接。 + + +## 功能 + +### Schema 选择 + +Oracle 将对象组织到 schema 中,每个 schema 对应一个数据库用户。TablePro 列出所有可访问的 schema 及其对象。 + +使用数据库切换器(**Cmd+K**)切换 schema,它会显示当前连接可用的 schema。 + +### 表浏览 + +每个表显示以下内容: + +- **Structure**:列及其 Oracle 数据类型、可空性和默认值 +- **Indexes**:B-tree 和 bitmap 索引 +- **Foreign Keys**:与其他表的关系 +- **DDL**:通过 DBMS_METADATA 生成的表定义 + +### 查询编辑器 + +在编辑器中编写和执行 SQL 及 PL/SQL。分页使用 Oracle 12c 的行限制语法: + +```sql +-- 分页结果 +SELECT * +FROM hr.employees +ORDER BY employee_id +OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY; + +-- 近似行数(快速,使用统计信息) +SELECT num_rows +FROM all_tables +WHERE owner = 'HR' AND table_name = 'EMPLOYEES'; + +-- 查看视图定义 +SELECT text +FROM all_views +WHERE owner = 'HR' AND view_name = 'EMP_DETAILS'; + +-- 列出当前 schema 中的所有表 +SELECT table_name +FROM user_tables +ORDER BY table_name; +``` + +### Schema 编辑 + +通过 ALTER TABLE 语句修改表结构。Oracle 使用双引号表示大小写敏感的标识符: + +```sql +-- 添加列 +ALTER TABLE "HR"."EMPLOYEES" ADD ("LAST_LOGIN" TIMESTAMP); + +-- 重命名列 +ALTER TABLE "HR"."EMPLOYEES" RENAME COLUMN "OLD_NAME" TO "NEW_NAME"; + +-- 修改列 +ALTER TABLE "HR"."EMPLOYEES" MODIFY ("SALARY" NUMBER(12,2)); + +-- 删除列 +ALTER TABLE "HR"."EMPLOYEES" DROP COLUMN "LEGACY_FIELD"; + +-- 添加索引 +CREATE INDEX "IX_EMP_EMAIL" ON "HR"."EMPLOYEES" ("EMAIL"); +``` + +### 外键 + +TablePro 在表结构视图中显示外键关系。手动查看外键: + +```sql +SELECT + c.constraint_name, + cc.column_name, + r.table_name AS referenced_table, + rc.column_name AS referenced_column +FROM all_constraints c +JOIN all_cons_columns cc + ON c.constraint_name = cc.constraint_name AND c.owner = cc.owner +JOIN all_constraints r + ON c.r_constraint_name = r.constraint_name AND c.r_owner = r.owner +JOIN all_cons_columns rc + ON r.constraint_name = rc.constraint_name AND r.owner = rc.owner +WHERE c.constraint_type = 'R' + AND c.owner = 'HR' +ORDER BY c.constraint_name; +``` + +## 认证 + +TablePro 使用 Oracle 数据库认证(username 和 password)。不支持 OS 认证和基于 wallet 的认证。 + +创建 Oracle 用户: + +```sql +-- 创建用户(schema) +CREATE USER app_user IDENTIFIED BY "StrongPassword1!"; + +-- 授予基本权限 +GRANT CREATE SESSION TO app_user; +GRANT SELECT ANY TABLE TO app_user; +GRANT INSERT ANY TABLE TO app_user; +GRANT UPDATE ANY TABLE TO app_user; +GRANT DELETE ANY TABLE TO app_user; +``` + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Unable to connect" 或超时 + +**原因及解决方案**: + +1. **Oracle listener 未运行** + + 检查并启动 listener: + ```bash + lsnrctl status + lsnrctl start + ``` + +2. **1521 端口被防火墙阻止** + - 检查 TCP 端口 1521 的防火墙规则 + - 对于云 VM,验证安全组设置 + +3. **Docker 容器未启动** + ```bash + docker start oracle-xe + docker logs oracle-xe + ``` + +### Service Name 无效 + +**症状**:"ORA-12514: TNS:listener does not currently know of service requested" + +**解决方案**: + +1. 验证 service name: + ```sql + SELECT value FROM v$parameter WHERE name = 'service_names'; + ``` +2. 检查 listener 上已注册的服务: + ```bash + lsnrctl services + ``` + +### 未找到 Oracle Instant Client + +**症状**:"Oracle Instant Client not found" 或库加载错误 + +**解决方案**:安装 Oracle Instant Client: + +1. 从 [Oracle Instant Client](https://www.oracle.com/database/technologies/instant-client.html) 下载 Basic 包 +2. 解压到某个目录(如 `/usr/local/oracle/instantclient`) +3. 设置 `DYLD_LIBRARY_PATH` 或将库文件复制到系统路径 + +## 已知限制 + +- **不支持 OS 认证。** 仅 username/password 认证可用。 +- **不支持基于 wallet 的认证**(Oracle Cloud 的 mTLS)。 +- **LONG 和 LONG RAW 列**(已弃用)编辑支持有限。在新的 schema 中请使用 CLOB 和 BLOB。 +- **PL/SQL 执行** 仅限于单个匿名块。包/过程的创建应使用查询编辑器。 + +## 后续步骤 + + + + 安全连接远程 Oracle 实例 + + + 掌握 SQL 编辑器功能 + + + 编辑行并通过 SQL 预览保存更改 + + + 查看和修改表结构 + + diff --git a/docs/zh/databases/overview.mdx b/docs/zh/databases/overview.mdx new file mode 100644 index 00000000..a60e5e61 --- /dev/null +++ b/docs/zh/databases/overview.mdx @@ -0,0 +1,606 @@ +--- +title: 连接管理 +description: 在 TablePro 中创建、组织和管理 10 种数据库引擎的连接 +--- + +# 连接管理 + +TablePro 通过统一界面连接十种数据库系统。你可以创建连接、用颜色、标签和分组来组织它们,并在不离开当前工作区的情况下自由切换。 + +## 支持的数据库 + +TablePro 原生支持十种数据库系统: + + + + 完整支持 MySQL 5.7+ 和 MySQL 8.0+。默认端口:3306 + + + 兼容 MariaDB 10.x 及更高版本。默认端口:3306 + + + PostgreSQL 12+,功能全面支持。默认端口:5432 + + + 通过 PostgreSQL wire protocol 连接 Redshift 数据仓库。默认端口:5439 + + + 基于文件的数据库,无需服务器 + + + MongoDB 4.4+,支持 MQL shell 查询。默认端口:27017 + + + Redis 6.0+,支持键值浏览和 CLI。默认端口:6379 + + + SQL Server 2017+,通过 FreeTDS 连接。默认端口:1433 + + + Oracle 12c+,通过 Oracle Call Interface 连接。默认端口:1521 + + + ClickHouse OLAP 数据库,通过 HTTP API 连接。默认端口:8123 + + + +## 创建连接 + +### 从欢迎界面 + +首次启动或没有活动连接时会显示欢迎界面。 + +1. 点击 **New Connection** +2. 填写连接信息 +3. 点击 **Test Connection** 验证 +4. 点击 **Create** 保存并连接 + +{/* Screenshot: Welcome screen with New Connection button highlighted */} + + 欢迎界面 + 欢迎界面 + + +### 从菜单栏 + +随时创建新连接: + +- **File** > **New Connection** (`Cmd+N`) + +### 从连接 URL + +托管平台、部署工具和文档通常会提供 connection string。你可以直接粘贴到连接表单中: + +1. 打开 **New Connection** 表单 +2. 在 General 标签页中点击 **Import from URL** +3. 将连接 URL 粘贴到对话框中,点击 **Import** +4. 所有字段(类型、host、port、database、username、password)会自动填充 +5. 检查自动填充的值,然后点击 **Create** + +参阅 [连接 URL 参考](/zh/databases/connection-urls) 了解所有支持的 scheme 和格式。 + + +如果密码中包含特殊字符(如 `@`、`#` 或 `%`),需要使用 percent-encoding。例如 `p@ssword` 应写为 `p%40ssword`。 + + +### 直接通过 URL 连接 + +从浏览器或终端打开数据库 URL,TablePro 会立即启动并连接,无需填写表单或已保存的连接。 + +**从浏览器:** 将 URL 粘贴到地址栏并按回车。 + +**从终端:** + +```bash +open "postgresql://user:pass@host:5432/dbname" +open "mysql://root:secret@localhost:3306/myapp" +open "redis://:password@localhost:6379" +``` + +TablePro 在 macOS 上注册了 `postgresql`、`postgres`、`mysql`、`mariadb`、`sqlite`、`mongodb`、`mongodb+srv`、`redis`、`rediss`、`redshift`、`mssql`、`sqlserver`、`oracle` 和 `clickhouse` 作为 URL scheme,因此系统会直接将这些 URL 路由到应用。 + +**打开 URL 后的行为:** + +- 如果已保存的连接匹配 host、port、database 和 username,TablePro 会复用该连接 +- 否则会创建一个临时会话,不会保存到连接列表中 +- URL 中的密码会在会话期间存储在 Keychain 中 + +你还可以通过 query parameter 指定特定的表、schema 或应用过滤条件。 + +参阅 [连接 URL 参考](/zh/databases/connection-urls) 了解所有支持的查询参数。 + + +这与 **Import from URL** 不同——后者会填充连接表单供你检查并保存。直接打开 URL 会跳过表单,立即连接。 + + +### 连接表单字段 + +#### General 部分 + +| 字段 | 描述 | +|-------|-------------| +| **Name** | 用于标识此连接的名称 | +| **Type** | 数据库类型:MySQL、MariaDB、PostgreSQL、SQLite、MongoDB、Redis、Redshift、SQL Server 或 Oracle | + +#### Appearance 部分 + +| 字段 | 描述 | +|-------|-------------| +| **Color** | 为连接标记颜色,便于快速识别 | +| **Tag** | 使用自定义标签组织连接 | +| **Group** | 将连接分配到分组(文件夹)中 | +| **Read-Only** | 开启后禁止对此连接执行所有写操作 | + + +用颜色区分环境:红色代表生产环境,绿色代表开发环境。为生产数据库启用 **Read-Only** 模式,防止误写。 + + +#### Connection 部分 + +| 字段 | 描述 | +|-------|-------------| +| **Host** | 服务器地址(默认:`localhost`) | +| **Port** | 服务器端口(根据数据库类型自动填充) | +| **Database** | 默认连接的数据库(MySQL/MariaDB 为可选) | + +对于 SQLite,此部分显示文件浏览器: + +| 字段 | 描述 | +|-------|-------------| +| **File Path** | SQLite 数据库文件的路径 | + +#### Authentication 部分 + +适用于 MySQL、MariaDB 和 PostgreSQL: + +| 字段 | 描述 | +|-------|-------------| +| **Username** | 数据库用户名(MySQL 默认为 `root`) | +| **Password** | 数据库密码(安全存储在 Keychain 中) | + + +SQLite 数据库不需要身份验证。 + + +{/* Screenshot: Connection form */} + + 连接表单字段 + 连接表单字段 + + +#### SSL/TLS 部分 + +适用于 MySQL、MariaDB 和 PostgreSQL 连接,配置 SSL/TLS 加密: + +| 字段 | 描述 | +|-------|-------------| +| **SSL Mode** | 加密模式(见下表) | +| **CA Certificate** | CA 证书文件路径(用于 Verify CA/Verify Identity 模式) | +| **Client Certificate** | 客户端证书文件路径(可选) | +| **Client Key** | 客户端私钥文件路径(可选) | + +**可用的 SSL 模式:** + +| 模式 | 描述 | +|------|-------------| +| **Disabled** | 不使用 SSL 加密(默认) | +| **Preferred** | 如果可用则使用 SSL,否则回退到非加密连接 | +| **Required** | 要求 SSL 加密,但不验证证书 | +| **Verify CA** | 要求 SSL 并验证服务器证书是否由 CA 签发 | +| **Verify Identity** | 要求 SSL,验证 CA,并验证服务器主机名是否匹配证书 | + + +对于生产数据库,建议使用 **Verify CA** 或 **Verify Identity** 以获得最高安全性。对于开发服务器,**Required** 可以在无需证书文件的情况下提供加密。 + + + +SSL/TLS 不适用于 SQLite 连接(基于文件,不涉及网络)。 + + +{/* Screenshot: SSL/TLS settings */} + + SSL/TLS 连接设置 + SSL/TLS 连接设置 + + +## 连接颜色 + +为连接分配颜色以便快速识别: + +| 颜色 | 建议用途 | +|-------|---------------| +| None | 默认,中性连接 | +| Red | 生产数据库 | +| Orange | 预发布环境 | +| Yellow | 测试数据库 | +| Green | 开发/本地 | +| Blue | 共享数据库 | +| Purple | 特殊用途 | +| Pink | 个人项目 | + +{/* Screenshot: Connection form showing color picker */} + + 颜色选择器 + 颜色选择器 + + +### 环境颜色指示器 + +当连接设置了颜色后,窗口工具栏会呈现该颜色的淡淡色调。这让你一眼就能看出当前所在的环境,类似于 Safari 根据网站颜色为工具栏着色的效果。 + +- **红色调工具栏** = 生产数据库 +- **绿色调工具栏** = 开发/本地 +- 无色调 = 未分配颜色(默认) + +色调足够淡,不会影响可读性,但一眼就能注意到。 + +## 连接标签 + +标签将连接组织成逻辑分组: + +1. 在连接表单中,点击 **Tag** 字段 +2. 选择已有标签或创建新标签 +3. 标签会显示在侧栏中,方便筛选 + +常见标签示例: +- "工作" +- "个人" +- "客户项目" +- "归档" + +{/* Screenshot: Connection tags */} + + 连接标签 + 连接标签 + + +## 连接分组 + +分组将连接组织为欢迎界面上可折叠的文件夹: + +1. 在连接列表中右键点击选择 **New Group**,或点击搜索栏旁边的文件夹图标 +2. 为分组命名并选择颜色 +3. 将连接拖入分组,或在连接表单的 **Appearance** 部分指定分组 + +### 管理分组 + +| 操作 | 方法 | +|--------|-----| +| **创建** | 点击文件夹图标或右键 > New Group | +| **重命名** | 右键点击分组标题 > Rename | +| **更改颜色** | 右键点击分组标题 > Change Color | +| **删除** | 右键点击分组标题 > Delete Group(连接会移至未分组) | + +点击箭头可折叠/展开分组。折叠状态会在会话之间保持。 + + +将分组与颜色结合使用,获得清晰的视觉概览:将所有生产连接放入红色标题的「Production」分组,开发连接放入绿色的「Development」分组。 + + +## 快速切换连接 + +从工具栏直接切换活动或已保存的连接,无需返回欢迎界面: + +1. 点击工具栏中的**连接名称**按钮 +2. 弹出面板显示活动会话和已保存连接 +3. 点击任意连接即可切换 +4. 点击 **Manage Connections...** 打开完整的连接管理器 + + +连接切换器是在开发过程中跳转不同数据库的最快方式。再次点击连接按钮可关闭弹出面板。 + + +## 切换数据库 + +在同一连接中切换数据库: + +1. 点击工具栏中的数据库名称(位于连接名称旁) +2. 从下拉列表中选择其他数据库 +3. 侧栏会更新显示新数据库的表 + +这比为同一服务器的每个数据库创建单独的连接要快得多。 + +{/* Screenshot: Database switcher */} + + 工具栏中的数据库切换器 + 工具栏中的数据库切换器 + + +## 从 Dock 菜单快速连接 + +无需经过欢迎界面,直接从 macOS Dock 打开已保存的连接。 + +右键点击 Dock 中的 TablePro 图标打开 Dock 菜单: + +| 菜单项 | 描述 | +|-----------|-------------| +| **Show Welcome Window** | 打开欢迎界面 | +| **Open Connection** | 子菜单,列出所有已保存连接及数据库类型图标 | + +### 使用方法 + +1. 右键点击 Dock 中的 TablePro 图标 +2. 将鼠标悬停在 **Open Connection** 上 +3. 点击连接名称 +4. TablePro 打开并自动连接 + +如果连接失败(如服务器不可达),TablePro 会回退到欢迎界面,方便你检查或修改连接设置。 + + +Dock 菜单中的每个连接都显示对应的数据库类型图标(MySQL、MariaDB、PostgreSQL 或 SQLite),方便一眼识别。 + + +## 创建数据库 + +创建新数据库: + +1. 在侧栏中右键点击连接 +2. 选择 **Create Database** +3. 输入数据库名称 +4. 选择字符集和排序规则(MySQL/MariaDB) +5. 点击 **Create** + + +创建数据库需要服务器上的相应权限。 + + +## 测试连接 + +保存连接前先测试: + +1. 填写所有必要的连接信息 +2. 点击 **Test Connection** +3. 等待结果: + - **绿色勾号**:连接成功 + - **红色叉号**:连接失败(查看错误信息) + +{/* Screenshot: Successful connection test */} + + 连接测试 + 连接测试 + + +### 常见测试失败 + +| 错误 | 可能原因 | 解决方案 | +|-------|----------------|----------| +| "Connection refused" | 服务器未运行 | 启动数据库服务器 | +| "Authentication failed" | 凭据错误 | 检查用户名/密码 | +| "Host not found" | 服务器地址无效 | 检查主机名/IP | +| "Connection timed out" | 网络/防火墙问题 | 检查网络连通性 | + +## 连接健康监控 + +TablePro 监控活动连接,并在中断时自动恢复。 + +### 自动健康检查 + +对于 MySQL、MariaDB 和 PostgreSQL 连接,TablePro 每 **30 秒** 执行一次 ping(`SELECT 1`)来验证连接是否存活。SQLite 是基于文件的,不需要健康监控。 + +### 自动重连 + +当健康检查检测到连接丢失时,TablePro 会以指数退避的方式自动重连: + +1. **第 1 次** -- 等待 2 秒后重连 +2. **第 2 次** -- 等待 4 秒后重连 +3. **第 3 次** -- 等待 8 秒后重连 + +如果三次尝试都失败,连接进入错误状态。工具栏会出现 **Reconnect** 按钮。 + +SSH tunnel 有独立的健康监控。如果 tunnel 进程终止,会自动重新建立。 + +### 手动重连 + +如果自动重连失败,点击工具栏中的 **Reconnect** 按钮手动重新连接。对于 SSH 连接,这也会重新创建 SSH tunnel。 + + +工具栏状态指示器显示连接状态:绿色表示已连接,橙色表示正在重连,红色表示错误/已断开。 + + + +SQLite 是基于文件的连接,不需要健康监控或自动重连。 + + +{/* Screenshot: Connection health status */} + + 连接健康状态 + 连接健康状态 + + +## 启动命令 + +启动命令是每次建立连接时自动执行的 SQL 语句。可用于设置会话变量、配置时区、更改编码或设置其他会话级选项。 + +在连接表单的 **Advanced** 标签页中配置启动命令。每行输入一条 SQL 语句。 + +### 常见示例 + +```sql +SET time_zone = '+00:00'; +SET NAMES utf8mb4; +SET sql_mode = 'STRICT_TRANS_TABLES'; +SET search_path TO myschema, public; +SET statement_timeout = '30s'; +``` + +启动命令按从上到下的顺序执行。如果某条命令失败,连接仍会继续,但该命令会被跳过。 + + +启动命令适合在团队成员之间统一会话设置。例如,设置特定时区可以确保所有日期时间查询返回相同时区的结果,而不受服务器默认设置的影响。 + + + +启动命令在每次连接时都会执行,包括自动重连。命令语法需要匹配数据库类型:MySQL 连接使用 MySQL 语法,PostgreSQL 连接使用 PostgreSQL 语法,以此类推。 + + +## 编辑连接 + +修改已有连接: + +1. 在侧栏中右键点击连接 +2. 选择 **Edit Connection** +3. 进行更改 +4. 点击 **Save** + + +更改会在下次连接时生效。如果当前已连接,需要断开后重新连接。 + + +## 删除连接 + +删除连接: + +1. 在侧栏中右键点击连接 +2. 选择 **Delete Connection** +3. 确认删除 + + +删除连接只会移除已保存的设置和凭据,不会影响实际的数据库。 + + +## 连接存储 + +### 存储位置 + +| 数据 | 位置 | 存储类型 | +|------|----------|--------------| +| 连接设置 | `~/Library/Preferences/com.TablePro.plist` | UserDefaults | +| 所有应用设置 | `~/Library/Preferences/com.TablePro.plist` | UserDefaults | +| 密码 | macOS Keychain | 加密存储 | +| SSH 密钥 | 按路径引用 | 不会复制 | + +### 备份与恢复 + +备份连接和设置: + +```bash +# 备份连接和所有设置 +cp ~/Library/Preferences/com.TablePro.plist ~/Desktop/tablepro-backup.plist +``` + +恢复: + +```bash +# 先关闭 TablePro,然后恢复 +cp ~/Desktop/tablepro-backup.plist ~/Library/Preferences/com.TablePro.plist +``` + + +备份文件不包含密码(存储在 Keychain 中)和 SSH 私钥。恢复后需要重新输入密码。 + + +## 默认端口 + +选择数据库类型时,TablePro 会自动填充端口: + +| 数据库 | 默认端口 | +|----------|-------------| +| MySQL | 3306 | +| MariaDB | 3306 | +| PostgreSQL | 5432 | +| Amazon Redshift | 5439 | +| SQLite | 不适用(基于文件) | +| MongoDB | 27017 | +| Redis | 6379 | +| Microsoft SQL Server | 1433 | +| Oracle Database | 1521 | +| ClickHouse | 8123 | + +## 相关指南 + + + + MySQL 和 MariaDB 详细连接指南 + + + PostgreSQL 连接选项 + + + 使用 SQLite 数据库 + + + MongoDB 连接和 MQL 查询 + + + Redis 键值浏览和 CLI + + + 通过 FreeTDS 连接 SQL Server + + + 通过 OCI 连接 Oracle Database + + + 连接 Redshift 数据仓库 + + + 连接 ClickHouse OLAP 数据库 + + + 通过 SSH 安全连接 + + diff --git a/docs/zh/databases/postgresql.mdx b/docs/zh/databases/postgresql.mdx new file mode 100644 index 00000000..8e69bf0b --- /dev/null +++ b/docs/zh/databases/postgresql.mdx @@ -0,0 +1,448 @@ +--- +title: PostgreSQL +description: 通过 libpq 驱动连接 PostgreSQL 12+,支持 schema 浏览、JSONB 显示等功能 +--- + +# PostgreSQL 连接 + +TablePro 通过 libpq C connector 支持 PostgreSQL 12 及更高版本。Schema 浏览、丰富的类型显示(JSONB、数组、UUID、inet)以及所有标准 PostgreSQL 查询功能均可开箱即用。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **PostgreSQL** + + + 填写 host、port、username、password 和数据库名称 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP | `localhost` | +| **Port** | PostgreSQL 服务器端口 | `5432` | +| **Username** | PostgreSQL 用户名 | `postgres` | +| **Password** | 用户密码 | - | +| **Database** | 要连接的数据库名称 | - | + + +与 MySQL 不同,PostgreSQL 需要指定数据库名称才能连接。 + + + +你也可以通过在浏览器或终端中打开 `postgresql://` URL 来连接。详见 [连接 URL 参考](/zh/databases/connection-urls)。 + + +{/* Screenshot: PostgreSQL connection form */} + + PostgreSQL 连接表单 + PostgreSQL 连接表单 + + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local PostgreSQL +Host: localhost +Port: 5432 +Username: postgres +Password: (你的密码) +Database: postgres +``` + +### Docker PostgreSQL 容器 + +``` +Name: Docker Postgres +Host: localhost +Port: 5432(或你映射的端口) +Username: postgres +Password: (来自 POSTGRES_PASSWORD 的密码) +Database: postgres +``` + +### Homebrew PostgreSQL + +``` +Name: Homebrew Postgres +Host: localhost +Port: 5432 +Username: (你的 macOS 用户名) +Password: (本地 trust 认证可留空) +Database: postgres +``` + + +Homebrew 安装的 PostgreSQL 通常对本地连接使用 "trust" 认证,意味着不需要密码。 + + +### 远程服务器 + +``` +Name: Production DB +Host: db.example.com +Port: 5432 +Username: app_user +Password: (安全密码) +Database: myapp_production +``` + +### 云数据库 + +#### Amazon RDS + +``` +Name: AWS RDS Postgres +Host: mydb.abc123.us-east-1.rds.amazonaws.com +Port: 5432 +Username: postgres +Password: (你的 RDS 密码) +Database: postgres +``` + +#### Heroku Postgres + +``` +Name: Heroku Postgres +Host: ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com +Port: 5432 +Username: (来自 DATABASE_URL) +Password: (来自 DATABASE_URL) +Database: (来自 DATABASE_URL) +``` + + +解析 Heroku 的 `DATABASE_URL` 以提取 host、port、username、password 和数据库名称。 + + +## 功能 + +### Schema 支持 + +PostgreSQL 将表组织到 schema 中。TablePro 显示: + +1. 当前用户可访问的所有 schema +2. 每个 schema 中的表 +3. search path 顺序 + +{/* Screenshot: Sidebar showing PostgreSQL schemas and tables */} + + Schema 浏览器 + Schema 浏览器 + + +### 切换数据库 + +使用数据库切换器(**Cmd+K**)在 PostgreSQL 数据库和 schema 之间切换: + +1. 按 **Cmd+K** 打开切换器。它会列出 PostgreSQL 连接的数据库 +2. 选择目标数据库(例如 `app`、`analytics` 或 `postgres`) +3. 侧栏、查询和工具栏会在重新连接后更新 + + +系统数据库(`postgres`、`template0`、`template1`)会标记为系统条目。 + + + +切换数据库会将 PostgreSQL 会话重新连接到所选数据库。 + + +### 表信息 + +每个表显示以下内容: + +- **Structure**:包含 PostgreSQL 特有类型的列信息 +- **Indexes**:包括部分索引和表达式索引 +- **Constraints**:主键、外键、检查约束 +- **DDL**:CREATE TABLE 语句 + +### 查询执行 + +完整支持 PostgreSQL 语法: + +```sql +-- JSONB 查询 +SELECT data->>'name' as name, data->'address'->>'city' as city +FROM customers +WHERE data @> '{"active": true}'::jsonb; + +-- 数组操作 +SELECT name, tags +FROM products +WHERE 'electronics' = ANY(tags); + +-- Window functions +SELECT + department, + employee, + salary, + salary - LAG(salary) OVER (PARTITION BY department ORDER BY hire_date) as salary_change +FROM employees; + +-- CTEs with RETURNING +WITH inserted AS ( + INSERT INTO orders (customer_id, total) + VALUES (1, 99.99) + RETURNING * +) +SELECT * FROM inserted; + +-- 全文搜索 +SELECT title, ts_rank(search_vector, query) as rank +FROM articles, to_tsquery('english', 'database & performance') query +WHERE search_vector @@ query +ORDER BY rank DESC; +``` + +### PostgreSQL 特有类型 + +TablePro 正确渲染 PostgreSQL 丰富的类型系统: + +| 类型 | 显示方式 | +|------|---------| +| `jsonb` | 格式化的 JSON | +| `array` | 数组表示法 | +| `uuid` | UUID 字符串 | +| `inet` | IP 地址 | +| `timestamp with time zone` | 本地化时间戳 | +| `interval` | 可读的时间间隔 | +| `bytea` | 二进制数据指示器 | + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或 "could not connect to server" + +**原因及解决方案**: + +1. **PostgreSQL 服务器未运行** + ```bash + # 检查 PostgreSQL 是否运行 + pg_isready -h localhost -p 5432 + + # 启动 PostgreSQL(macOS Homebrew) + brew services start postgresql@16 + ``` + +2. **PostgreSQL 未接受连接** + - 检查 `postgresql.conf` 中的 `listen_addresses` + - 对于远程连接,设置 `listen_addresses = '*'` + +3. **防火墙阻止连接** + - 检查 macOS 防火墙设置 + - 验证 5432 端口是否可访问 + +### 认证失败 + +**症状**:"password authentication failed" 或 "Peer authentication failed" + +**理解 pg_hba.conf**: + +PostgreSQL 使用 `pg_hba.conf` 控制认证。常见配置: + +``` +# TYPE DATABASE USER ADDRESS METHOD +local all all trust +host all all 127.0.0.1/32 md5 +host all all ::1/128 md5 +``` + +**解决方案**: + +1. **密码认证**:确保设置了 `md5` 或 `scram-sha-256` +2. **本地开发**:使用 `trust`(不需要密码) +3. **忘记密码时重置**: + ```sql + ALTER USER postgres WITH PASSWORD 'newpassword'; + ``` + +### 数据库不存在 + +**症状**:"database 'xyz' does not exist" + +**解决方案**:先连接到已有的数据库(通常是 `postgres`),然后创建你的数据库: + +```sql +CREATE DATABASE myapp; +``` + +### 权限不足 + +**症状**:"permission denied for table" 或 "permission denied for schema" + +**解决方案**: + +1. 检查当前权限: + ```sql + SELECT * FROM information_schema.role_table_grants + WHERE grantee = 'username'; + ``` + +2. 授予必要权限: + ```sql + GRANT ALL ON DATABASE mydb TO username; + GRANT ALL ON SCHEMA public TO username; + GRANT ALL ON ALL TABLES IN SCHEMA public TO username; + ``` + +### SSL/TLS 连接 + +在连接表单的 **SSL/TLS** 部分配置 SSL。 + +| SSL 模式 | PostgreSQL `sslmode` | 描述 | +|----------|---------------------|-------------| +| **Disabled** | `disable` | 不使用 SSL 加密 | +| **Preferred** | `prefer` | 如果可用则使用 SSL,否则回退到非加密连接 | +| **Required** | `require` | 要求 SSL,但不验证证书 | +| **Verify CA** | `verify-ca` | 要求 SSL 并验证服务器证书是否由 CA 签发 | +| **Verify Identity** | `verify-full` | 要求 SSL,验证 CA 和服务器主机名 | + +对于 **Verify CA** 和 **Verify Identity** 模式,需要提供 CA 证书(根证书)路径。也可以提供可选的客户端证书和密钥文件以实现 mutual TLS。 + + +AWS RDS、Heroku 和 Supabase 等云服务商通常要求 SSL。根据你的安全需求使用 **Required** 或 **Verify CA**。 + + + +如果不想配置 SSL 证书,[SSH tunneling](/zh/databases/ssh-tunneling) 可以通过 SSH tunnel 加密所有流量。 + + +{/* Screenshot: PostgreSQL SSL/TLS configuration */} + + PostgreSQL SSL/TLS 配置 + PostgreSQL SSL/TLS 配置 + + +## 启动命令 + +设置每次连接时自动应用的会话变量。在连接表单的 **Advanced** 标签页中配置。 + +常用的 PostgreSQL 启动命令: + +```sql +SET timezone = 'UTC'; +SET search_path TO myschema, public; +SET statement_timeout = '30s'; +SET work_mem = '256MB'; +SET client_encoding = 'UTF8'; +``` + +设置 `search_path` 在表位于非默认 schema 时很有用。无需每次都写全限定名(`myschema.users`),设置一次 search path 后就可以直接用表名查询。 + +设置 `timezone` 可以确保所有 `timestamptz` 查询返回相同时区的结果,不受服务器或客户端操作系统时区的影响。 + +详见 [启动命令](/zh/databases/overview#启动命令)。 + +## PostgreSQL 扩展 + +TablePro 可以使用常见扩展的数据库: + +| 扩展 | 支持情况 | +|-----------|---------| +| `postgis` | 显示 geometry/geography 类型 | +| `pg_trgm` | 完整查询支持 | +| `uuid-ossp` | UUID 显示 | +| `hstore` | 键值显示 | +| `ltree` | 树路径显示 | + +查看已安装的扩展: + +```sql +SELECT * FROM pg_extension; +``` + +## 性能建议 + +### 查询分析 + +使用 `EXPLAIN ANALYZE` 了解查询性能: + +```sql +EXPLAIN ANALYZE +SELECT * FROM users WHERE email LIKE '%@example.com'; +``` + +### 连接限制 + +PostgreSQL 有默认的连接数限制。监控连接数: + +```sql +SELECT count(*) FROM pg_stat_activity; +``` + +### 大表 + +对于有数百万行的表: + +1. 在探索性查询中始终使用 `LIMIT` +2. 创建适当的索引 +3. 在数据网格中使用分页 + +## 从 MySQL 迁移 + +如果你从 MySQL 转到 PostgreSQL: + +| MySQL | PostgreSQL | +|-------|------------| +| `SHOW DATABASES` | `\l` 或查询 `pg_database` | +| `SHOW TABLES` | `\dt` 或查询 `information_schema.tables` | +| `DESCRIBE table` | `\d table` 或查询 `information_schema.columns` | +| `AUTO_INCREMENT` | `SERIAL` 或 `GENERATED AS IDENTITY` | +| `LIMIT x, y` | `LIMIT y OFFSET x` | +| 反引号引用 | 双引号引用标识符 | + +## 后续步骤 + + + + 安全连接远程 PostgreSQL 服务器 + + + 掌握 SQL 编辑器功能 + + + 导入和导出 PostgreSQL 数据 + + + 查看和修改表结构 + + diff --git a/docs/zh/databases/redis.mdx b/docs/zh/databases/redis.mdx new file mode 100644 index 00000000..23c909cb --- /dev/null +++ b/docs/zh/databases/redis.mdx @@ -0,0 +1,309 @@ +--- +title: Redis +description: 按命名空间浏览键、管理 TTL,以及直接在编辑器中执行 Redis 命令 +--- + +# Redis 连接 + +TablePro 支持 Redis 6.0 及更高版本。键按冒号分隔的命名空间在侧栏中分组。值在数据网格中以类型感知的格式显示(字符串、哈希、列表、集合、有序集合、JSON)。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **Redis** + + + 填写 host、port、password(如需要)和数据库索引 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | 服务器主机名或 IP | `localhost` | +| **Port** | Redis 服务器端口 | `6379` | + +### 可选字段 + +| 字段 | 描述 | +|-------|-------------| +| **Password** | Redis 服务器密码(AUTH) | +| **Database** | 数据库索引(0-15,默认 `0`) | + + +对于没有启用认证的本地开发环境,可以留空 password 字段。Redis 默认使用数据库索引 `0`。 + + +## 连接 URL 格式 + +使用 Redis URL 导入连接。 + +`rediss://` scheme(注意双 `s`)表示 TLS 加密连接。 + +参阅 [连接 URL 参考](/zh/databases/connection-urls#redis) 了解完整的 Redis URL 格式。 + +## 配置示例 + +### 本地开发服务器 + +``` +Name: Local Redis +Host: localhost +Port: 6379 +Password: (留空) +Database: 0 +``` + +### Docker Redis 容器 + +``` +Name: Docker Redis +Host: localhost +Port: 6379(或你映射的端口) +Password: (来自 REDIS_PASSWORD 环境变量的密码) +Database: 0 +``` + +### Redis Cloud / 托管服务 + +``` +Name: Redis Cloud +Host: redis-12345.c1.us-east-1-2.ec2.cloud.redislabs.com +Port: 12345 +Password: (你的 Redis Cloud 密码) +Database: 0 +``` + + +托管 Redis 服务通常要求 SSL/TLS。请在连接表单的 SSL/TLS 部分启用。 + + +### 远程服务器 + +``` +Name: Production Cache +Host: redis.example.com +Port: 6379 +Password: (安全密码) +Database: 0 +``` + + +对于生产环境的 Redis 实例,建议使用 [SSH tunneling](/zh/databases/ssh-tunneling) 进行安全连接。 + + +## SSL/TLS 连接 + +在连接表单的 **SSL/TLS** 部分配置 SSL。 + +| SSL 模式 | 描述 | +|----------|-------------| +| **Disabled** | 不使用 SSL 加密 | +| **Required** | 要求 SSL 加密 | +| **Verify CA** | 要求 SSL 并验证服务器证书是否由 CA 签发 | + +对于 **Verify CA** 模式,需要提供 CA 证书文件路径。也可以提供可选的客户端证书和密钥文件以实现 mutual TLS。 + + +导入需要 TLS 的连接时使用 `rediss://` URL scheme。 + + + +如果不想配置 SSL 证书,[SSH tunneling](/zh/databases/ssh-tunneling) 可以通过 SSH tunnel 加密所有流量。 + + +## SSH Tunnel 支持 + +通过 SSH tunnel 连接 Redis 以安全访问远程服务器。设置方法请参阅 [SSH Tunneling](/zh/databases/ssh-tunneling)。 + +## 功能 + +### 命名空间浏览 + +连接后,侧栏按冒号分隔的前缀对键进行分组。名为 `user:1`、`user:2` 和 `session:abc` 的键分别出现在 `user` 和 `session` 命名空间下: + +1. 点击侧栏中的连接名称 +2. 展开命名空间查看其键 +3. 点击键查看其值 + +没有冒号分隔符的键归入根命名空间。 + +### 键值查看 + +值在数据网格中以类型感知的格式显示: + +- **String** 值显示为纯文本 +- **Hash** 字段以键值对的行形式显示 +- **List** 元素显示其索引 +- **Set** 成员显示为独立行 +- **Sorted Set** 成员显示其分数 +- **JSON** 值带有语法高亮 + +### TTL 管理 + +查看和管理键的生存时间(TTL): + +- TTL 显示在数据网格中每个键的旁边 +- 没有过期时间的键显示 `-1` +- 不存在的键显示 `-2` +- 可以直接在界面中设置或更新 TTL 值 + +### Redis CLI + +在编辑器标签页中直接执行 Redis 命令: + +```redis +-- 键操作 +GET mykey +SET mykey "hello" EX 60 +DEL mykey key2 key3 +KEYS user:* + +-- 哈希操作 +HGETALL myhash +HSET myhash field1 "value1" +HDEL myhash field1 + +-- 列表操作 +LRANGE mylist 0 -1 +LPUSH mylist "item1" "item2" +LLEN mylist + +-- 集合操作 +SMEMBERS myset +SADD myset "member1" "member2" +SCARD myset + +-- 有序集合操作 +ZRANGE myzset 0 -1 WITHSCORES +ZADD myzset 1 "one" 2 "two" +ZCARD myzset + +-- 扫描键 +SCAN 0 MATCH user:* COUNT 100 + +-- 服务器信息 +PING +INFO +DBSIZE +``` + +### 支持的命令 + +TablePro 支持全套 Redis 命令: + +| 类别 | 命令 | +|----------|----------| +| **String** | GET、SET、MGET、MSET、INCR、DECR、APPEND | +| **Hash** | HGET、HSET、HGETALL、HDEL、HKEYS、HVALS、HLEN | +| **List** | LPUSH、RPUSH、LPOP、RPOP、LRANGE、LLEN、LINDEX | +| **Set** | SADD、SREM、SMEMBERS、SISMEMBER、SCARD、SUNION | +| **Sorted Set** | ZADD、ZREM、ZRANGE、ZRANGEBYSCORE、ZCARD、ZSCORE | +| **Key** | DEL、EXISTS、EXPIRE、TTL、TYPE、RENAME、KEYS、SCAN | +| **Server** | PING、INFO、DBSIZE、FLUSHDB、SELECT | + +未在上方列出的命令仍会发送到服务器,其响应会显示在结果面板中。 + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或超时 + +**原因及解决方案**: + +1. **Redis 服务器未运行** + ```bash + # 检查 Redis 是否运行 + redis-cli ping + + # 启动 Redis(macOS Homebrew) + brew services start redis + ``` + +2. **端口错误** + - 检查 Redis 配置文件(`redis.conf`)中的端口 + - 检查你的配置 + +3. **Redis 未监听预期地址** + - 检查 `redis.conf` 中的 `bind` 指令 + - 对于远程连接,添加客户端 IP 或使用 `0.0.0.0` + +### 认证失败 + +**症状**:"NOAUTH Authentication required" 或 "ERR invalid password" + +**解决方案**: + +1. 验证密码是否匹配 `redis.conf` 中的 `requirepass` +2. 对于 Redis 6.0+ 的 ACL: + ```redis + ACL LIST + ACL SETUSER myuser on >password ~* +@all + ``` + +### 连接超时 + +**症状**:连接挂起或超时 + +**解决方案**: + +1. 验证 host 和 port 是否正确 +2. 检查网络连通性和防火墙规则 +3. 对于云托管的 Redis,确保你的 IP 已加入白名单 + +## 已知限制 + +- **集群模式**:不支持自动分片的 Redis Cluster。请直接连接单个节点。 +- **Pub/Sub**:当前版本不支持实时 Pub/Sub 订阅。 +- **Streams**:Redis Streams(XADD、XREAD 等)在数据网格中不支持,但命令可在 CLI 中使用。 +- **模块**:RedisJSON、RediSearch 等模块命令可通过 CLI 使用,但可能缺少专门的 UI 支持。 +- **大键**:包含数百万元素的键(大列表、集合或哈希)会进行分页以防止内存问题。 + +## 性能建议 + +### 大型数据库 + +对于有数百万个键的 Redis 实例: + +1. 使用命名空间浏览按前缀过滤键 +2. 在 CLI 中使用 `SCAN` 而不是 `KEYS` 进行模式匹配 +3. 浏览大型集合时会自动应用分页 + +### 内存监控 + +检查 Redis 实例的内存使用情况: + +```redis +INFO memory +MEMORY USAGE mykey +DBSIZE +``` + +## 后续步骤 + + + + 安全连接远程 Redis 服务器 + + + 掌握查询编辑器功能 + + + 导入和导出 Redis 数据 + + + 在数据网格中浏览和编辑键值数据 + + diff --git a/docs/zh/databases/redshift.mdx b/docs/zh/databases/redshift.mdx new file mode 100644 index 00000000..8588ca2c --- /dev/null +++ b/docs/zh/databases/redshift.mdx @@ -0,0 +1,246 @@ +--- +title: Amazon Redshift +description: 通过 PostgreSQL wire protocol 连接 Redshift 集群和 Serverless,显示 DISTKEY/SORTKEY 元数据 +--- + +# Amazon Redshift 连接 + +TablePro 连接 Amazon Redshift——AWS 基于 PostgreSQL 8.0.2 的列式数据仓库。连接使用与 PostgreSQL 相同的 libpq 驱动,并通过 Redshift 特有的元数据查询获取分布方式、排序键和表大小信息。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **Amazon Redshift** + + + 填写集群端点、port、username、password 和数据库名称 + + + 点击 **Test Connection**,然后点击 **Create** + + + +## 连接设置 + +### 必填字段 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **Name** | 连接标识名称 | - | +| **Host** | Redshift 集群端点 | - | +| **Port** | Redshift 服务器端口 | `5439` | +| **Username** | Redshift 用户名 | - | +| **Password** | 用户密码 | - | +| **Database** | 要连接的数据库名称 | `dev` | + + +Redshift 需要指定数据库名称。每个集群创建时的默认数据库是 `dev`。 + + +## 配置示例 + +### Redshift 集群 + +``` +Name: Production Warehouse +Host: my-cluster.abc123xyz.us-east-1.redshift.amazonaws.com +Port: 5439 +Username: awsuser +Password: (你的密码) +Database: dev +``` + +### Redshift Serverless + +``` +Name: Serverless Warehouse +Host: my-workgroup.123456789012.us-west-2.redshift-serverless.amazonaws.com +Port: 5439 +Username: admin +Password: (你的密码) +Database: dev +``` + + +在 AWS 控制台的 Amazon Redshift > Clusters > 你的集群 > Properties 中找到集群端点。端点中包含端口,但在 TablePro 中需要分别输入 host 和 port。 + + +## 功能 + +### Schema 支持 + +Redshift 像 PostgreSQL 一样将表组织到 schema 中。TablePro 显示: + +1. 当前用户可访问的所有 schema +2. 每个 schema 中的表 +3. search path 顺序 + +### Schema 切换 + +使用数据库切换器(**Cmd+K**)在 Redshift schema 之间切换: + +1. 按 **Cmd+K** 打开切换器 +2. 选择目标 schema +3. 侧栏、查询和工具栏会更新以反映所选 schema + + +默认 schema 是 `public`。系统 schema 如 `pg_catalog` 和 `information_schema` 会从列表中过滤掉。 + + +### 表浏览和数据查看 + +浏览表、视图和后期绑定视图。数据网格会对大型仓库表进行分页。通过 `svv_table_info` 获取的 Redshift 特有元数据——分布方式、排序键和表大小——可在表信息面板中查看。 + +### 查询执行 + +使用 Redshift SQL 语法执行查询。编辑器高亮显示 Redshift 特有的函数和关键字。 + +```sql +-- Window functions +SELECT + category, + product, + revenue, + RANK() OVER (PARTITION BY category ORDER BY revenue DESC) as rank +FROM sales; + +-- 从 S3 加载数据 +COPY sales FROM 's3://mybucket/data/sales/' +IAM_ROLE 'arn:aws:iam::123456789012:role/MyRedshiftRole' +FORMAT AS PARQUET; + +-- 导出到 S3 +UNLOAD ('SELECT * FROM sales WHERE year = 2024') +TO 's3://mybucket/export/sales_2024_' +IAM_ROLE 'arn:aws:iam::123456789012:role/MyRedshiftRole' +FORMAT AS CSV; + +-- 分析压缩 +ANALYZE COMPRESSION sales; +``` + +### 数据导出 + +以多种格式导出查询结果或表数据: + +- CSV +- JSON +- SQL(INSERT 语句) +- XLSX + +### 数据导入 + +从 CSV、JSON、SQL 和 XLSX 文件导入数据到 Redshift 表中。 + +### DDL 生成 + +查看任意表的 DDL(CREATE TABLE 语句),包括 Redshift 特有的子句:DISTKEY、SORTKEY、DISTSTYLE 和 ENCODE 指令。 + +### 外键导航 + +Redshift 支持外键定义,但仅用于信息参考(引擎不会强制执行)。TablePro 显示这些关系,并允许在相关表之间导航。 + +## SSL/TLS + +Redshift 连接支持 SSL/TLS 加密,配置与 PostgreSQL 相同: + +| SSL 模式 | 描述 | +|----------|-------------| +| **Disabled** | 不使用 SSL 加密 | +| **Preferred** | 如果可用则使用 SSL,否则回退到非加密连接 | +| **Required** | 要求 SSL,但不验证证书 | +| **Verify CA** | 要求 SSL 并验证服务器证书是否由 CA 签发 | +| **Verify Identity** | 要求 SSL,验证 CA 和服务器主机名 | + + +AWS Redshift 端点默认支持 SSL。生产连接建议使用 **Required** 或 **Verify CA**。 + + +## SSH Tunnel 支持 + +如果你的集群在私有 VPC 中,可以通过 SSH tunnel 连接 Redshift。在连接表单的 SSH 标签页中配置。TablePro 会将 Redshift 连接通过 tunnel 路由。 + +## 限制 + +Redshift 是列式数据仓库,不是通用的 RDBMS。一些 PostgreSQL 功能缺失或工作方式不同: + +| 特性 | Redshift 行为 | +|---------|------------------| +| **索引** | 没有传统的 B-tree 索引。使用 DISTKEY 和 SORTKEY 控制数据分布和排序。这些列显示在 Structure 标签页中。 | +| **ALTER TABLE** | 支持有限。不能重命名列。类型变更仅限于扩展 VARCHAR 或更改数值精度。 | +| **枚举类型** | 不支持。没有用于自定义枚举的 CREATE TYPE。 | +| **序列** | 不支持。使用 IDENTITY 列代替。 | +| **外键** | 仅供参考。在 DDL 中定义但引擎不强制执行。 | +| **触发器** | 不支持。 | +| **存储过程** | 支持,但使用受限的 PL/pgSQL 子集。 | + +### DISTKEY 和 SORTKEY + +Redshift 使用分布键在节点间分布数据,使用排序键在每个节点内排序数据,而非传统索引。TablePro 在每个表的 Structure 标签页中显示 DISTKEY 和 SORTKEY 标记,展示你的数据是如何物理组织的。 + +## 故障排除 + +### 连接被拒绝 + +**症状**:"Connection refused" 或超时 + +**常见原因**: + +1. **安全组未配置**:你的 IP 必须在 Redshift 集群 VPC 安全组的入站规则中允许(端口 5439)。 +2. **集群未公开访问**:如果集群属性中 `Publicly Accessible` 为 No,你需要 SSH tunnel 或 VPN。 +3. **集群已暂停**:Redshift 集群可以暂停以节省成本。在 AWS 控制台中恢复集群。 + +### 认证失败 + +**症状**:"password authentication failed" + +**解决方案**: + +1. 在 AWS 控制台中验证主用户名和密码 +2. 对于基于 IAM 的认证,确保凭据是最新的 +3. 检查用户是否被授予访问指定数据库的权限 + +### 查询性能 + +Redshift 针对大数据集的分析查询进行了优化。如果查询较慢: + +1. 检查表的分布方式:`SELECT * FROM svv_table_info WHERE "table" = 'your_table'` +2. 运行 `ANALYZE` 更新表统计信息 +3. 使用 `EXPLAIN` 查看查询计划 +4. 确保 SORTKEY 列匹配你常用的 WHERE 和 JOIN 条件 + +## 与 PostgreSQL 的区别 + +如果你从 PostgreSQL 转到 Redshift: + +| PostgreSQL | Redshift | +|------------|----------| +| 默认端口 5432 | 默认端口 5439 | +| B-tree、GIN、GiST 索引 | 仅 DISTKEY + SORTKEY | +| `CREATE INDEX` | 不支持 | +| 完整约束执行 | 外键仅供参考 | +| `SERIAL` / `GENERATED AS IDENTITY` | `IDENTITY(seed, step)` | +| 丰富的类型系统(JSONB、数组等) | 类型有限(无数组,JSON 通过 SUPER 类型有限支持) | +| `pg_stat_activity` | `stv_recents`、`svl_qlog` | +| 行式存储 | 列式存储 | + +## 后续步骤 + + + + 连接私有 VPC 中的 Redshift 集群 + + + 编写和执行 Redshift 查询 + + + 导入和导出 Redshift 数据 + + + 查看 DISTKEY、SORTKEY 和列定义 + + diff --git a/docs/zh/databases/sqlite.mdx b/docs/zh/databases/sqlite.mdx new file mode 100644 index 00000000..55d3f108 --- /dev/null +++ b/docs/zh/databases/sqlite.mdx @@ -0,0 +1,387 @@ +--- +title: SQLite +description: 直接打开和查询 .sqlite、.db 和 .sqlite3 文件,无需服务器 +--- + +# SQLite 数据库 + +SQLite 是一个自包含的、基于文件的数据库引擎。无需服务器,整个数据库存储在 Mac 上的一个文件中。 + +## 快速设置 + + + + 在欢迎界面点击 **New Connection**,或选择 **File** > **New Connection** + + + 从数据库类型选择器中选择 **SQLite** + + + 点击 **Browse** 选择你的 `.sqlite`、`.db` 或 `.sqlite3` 文件 + + + 为连接命名并点击 **Create** + + + +## 连接设置 + +SQLite 连接很简单,因为不涉及服务器: + +| 字段 | 描述 | +|-------|-------------| +| **Name** | 此连接的名称 | +| **File Path** | SQLite 数据库文件的完整路径 | + +{/* Screenshot: SQLite connection form with file browser */} + + SQLite 连接 + SQLite 连接 + + + +SQLite 数据库不需要用户名、密码或网络设置。 + + +## 常见 SQLite 文件位置 + +### 应用数据库 + +许多 macOS 应用使用 SQLite: + +| 应用 | 数据库位置 | +|-------------|-------------------| +| Safari | `~/Library/Safari/History.db` | +| Photos | `~/Pictures/Photos Library.photoslibrary/database/Photos.sqlite` | +| Messages | `~/Library/Messages/chat.db` | +| Notes | `~/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite` | + + +系统数据库在其父应用运行时可能被锁定。打开数据库前请先退出对应应用。 + + +### 开发数据库 + +常见的开发数据库位置: + +``` +# Ruby on Rails +./db/development.sqlite3 + +# Django +./db.sqlite3 + +# iOS 模拟器 +~/Library/Developer/CoreSimulator/Devices/*/data/Containers/Data/Application/*/Documents/*.sqlite + +# Core Data +*.sqlite(在应用容器中) +``` + +### 创建新数据库 + +创建新的 SQLite 数据库: + +1. 创建新连接 +2. 输入一个尚不存在的文件路径 +3. TablePro 会在连接时创建该文件 + +或者通过命令行: + +```bash +sqlite3 ~/Documents/newdatabase.sqlite "SELECT 1;" +``` + +## 功能 + +### 数据库浏览器 + +侧栏显示 SQLite 数据库中的所有表和视图: + +{/* Screenshot: Sidebar with SQLite tables expanded */} + + SQLite 浏览器 + SQLite 浏览器 + + +### 表信息 + +每个表显示以下内容: + +- **Structure**:列名、类型和约束 +- **Indexes**:所有索引,包括 UNIQUE 约束 +- **DDL**:CREATE TABLE 语句 + +### SQLite 系统表 + +TablePro 可以显示 SQLite 的内部表: + +| 表 | 用途 | +|-------|---------| +| `sqlite_master` | schema 信息 | +| `sqlite_sequence` | AUTOINCREMENT 追踪 | + +### 查询执行 + +完整支持 SQLite 语法: + +```sql +-- JSON 函数(SQLite 3.38+) +SELECT json_extract(data, '$.name') as name +FROM users +WHERE json_extract(data, '$.active') = true; + +-- Window functions +SELECT + category, + product, + price, + rank() OVER (PARTITION BY category ORDER BY price DESC) as rank +FROM products; + +-- CTEs +WITH RECURSIVE + cnt(x) AS ( + SELECT 1 + UNION ALL + SELECT x+1 FROM cnt WHERE x < 10 + ) +SELECT x FROM cnt; + +-- 全文搜索(如果启用了 FTS) +SELECT * FROM documents WHERE documents MATCH 'sqlite AND database'; + +-- UPSERT(INSERT OR REPLACE) +INSERT INTO settings (key, value) +VALUES ('theme', 'dark') +ON CONFLICT(key) DO UPDATE SET value = excluded.value; +``` + +## SQLite 数据类型 + +SQLite 使用动态类型系统和类型亲和性: + +| 亲和性 | 描述 | 示例 | +|----------|-------------|----------| +| TEXT | 字符串数据 | `VARCHAR`、`TEXT`、`CLOB` | +| INTEGER | 有符号整数 | `INT`、`INTEGER`、`BIGINT` | +| REAL | 浮点数 | `REAL`、`DOUBLE`、`FLOAT` | +| NUMERIC | 数值或文本 | `DECIMAL`、`BOOLEAN`、`DATE` | +| BLOB | 二进制数据 | `BLOB`、原始字节 | + + +SQLite 接受在任何列中存储任何数据类型(INTEGER PRIMARY KEY 除外)。类型只是一个提示,不是约束。 + + +## 处理大文件 + +### 文件大小 + +SQLite 数据库可以很大。TablePro 可以处理: + +- 数 GB 大小的数据库 +- 有数百万行的表 +- BLOB 数据(图片、文件) + +### 性能建议 + +1. **使用分页**:在设置中为大表启用分页 +2. **添加索引**:为经常查询的列创建索引 +3. **使用 LIMIT**:探索时始终限制结果集 +4. **定期 VACUUM**:使用 `VACUUM` 回收空间 + +```sql +-- 检查数据库大小 +SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size(); + +-- 分析表以优化查询 +ANALYZE; + +-- 回收未使用的空间 +VACUUM; +``` + +## 故障排除 + +### 数据库被锁定 + +**症状**:"database is locked" 或 "database table is locked" + +**原因**: +- 另一个应用打开了该数据库 +- 前一个查询仍在运行 +- WAL 模式冲突 + +**解决方案**: + +1. 关闭使用该数据库的其他应用 +2. 等待运行中的查询完成 +3. 检查 WAL 文件: + ```bash + ls -la /path/to/database.sqlite* + # 你可能会看到:database.sqlite-wal、database.sqlite-shm + ``` + +### 无法打开数据库 + +**症状**:"unable to open database file" + +**原因及解决方案**: + +1. **文件不存在**:验证路径是否正确 +2. **权限不足**:检查文件权限 + ```bash + ls -la /path/to/database.sqlite + chmod 644 /path/to/database.sqlite + ``` +3. **路径包含特殊字符**:使用不含空格的绝对路径 + +### 数据库损坏 + +**症状**:"database disk image is malformed" + +**恢复选项**: + +1. **检查完整性**: + ```sql + PRAGMA integrity_check; + ``` + +2. **尝试恢复**: + ```bash + sqlite3 corrupt.sqlite ".recover" | sqlite3 recovered.sqlite + ``` + +3. **从备份恢复**(如果有的话) + +### Schema 变更不可见 + +**症状**:创建的表或列没有显示 + +**解决方案**:刷新连接: +1. 右键点击连接 +2. 选择 **Refresh** + +或者断开后重新连接。 + +## SQLite Pragmas + +TablePro 支持 SQLite PRAGMA 命令进行配置: + +```sql +-- 检查 SQLite 版本 +SELECT sqlite_version(); + +-- 显示表信息 +PRAGMA table_info(users); + +-- 检查外键是否启用 +PRAGMA foreign_keys; + +-- 启用外键约束 +PRAGMA foreign_keys = ON; + +-- 检查日志模式 +PRAGMA journal_mode; + +-- 使用 WAL 模式提高并发性 +PRAGMA journal_mode = WAL; +``` + +{/* Screenshot: SQLite PRAGMA results */} + + SQLite PRAGMA 结果 + SQLite PRAGMA 结果 + + +## 备份与恢复 + +### 手动备份 + +SQLite 数据库就是文件。备份方法: + +```bash +# 简单复制(确保数据库没有正在写入) +cp database.sqlite database-backup.sqlite + +# SQLite 备份命令(更安全,可处理锁) +sqlite3 database.sqlite ".backup backup.sqlite" +``` + +### 导出为 SQL + +将数据库导出为 SQL 语句: + +```bash +sqlite3 database.sqlite .dump > backup.sql +``` + +### 从 SQL 恢复 + +```bash +sqlite3 newdatabase.sqlite < backup.sql +``` + +## 与服务器数据库的区别 + +| 特性 | SQLite | MySQL/PostgreSQL | +|---------|--------|------------------| +| 需要服务器 | 否 | 是 | +| 多连接 | 有限 | 无限制 | +| 用户认证 | 否 | 是 | +| 网络访问 | 基于文件 | TCP/IP | +| 并发写入 | 有限 | 完整支持 | +| 存储过程 | 否 | 是 | +| 数据类型 | 动态 | 静态 | + +## 常见用途 + +SQLite 适用于: + +- **本地开发**:快速原型开发 +- **嵌入式应用**:移动应用、桌面应用 +- **单用户应用**:个人数据库 +- **数据分析**:快速数据探索 +- **测试**:使用隔离数据库的单元测试 +- **原型验证**:迁移到服务器数据库之前的验证 + +## 后续步骤 + + + + 编写和执行 SQL 查询 + + + 查看和编辑数据 + + + 导入和导出 SQLite 数据 + + + 查看和修改表结构 + + diff --git a/docs/zh/databases/ssh-tunneling.mdx b/docs/zh/databases/ssh-tunneling.mdx new file mode 100644 index 00000000..9d188832 --- /dev/null +++ b/docs/zh/databases/ssh-tunneling.mdx @@ -0,0 +1,564 @@ +--- +title: SSH Tunneling +description: 通过加密的 SSH 隧道路由数据库连接,访问私有网络中的服务器 +--- + +# SSH Tunneling + +SSH tunneling 将你的数据库连接通过加密隧道路由,以访问无法从 Mac 直接连接的服务器。TablePro 管理 tunnel 的生命周期,包括保活和自动重连。 + +## SSH Tunneling 的工作原理 + +```mermaid +flowchart LR + subgraph mac ["你的 Mac"] + TablePro["TablePro
localhost:60000"] + end + + subgraph ssh ["SSH 服务器"] + Jump["SSH 跳板
服务器"] + end + + subgraph db ["数据库服务器"] + Database["MySQL
PostgreSQL
db:3306"] + end + + TablePro -->|"加密
隧道"| Jump -->|"内部
网络"| Database +``` + +1. TablePro 向你的跳板服务器发起 SSH 连接 +2. 本地端口(如 60000)通过隧道转发 +3. Mac 和 SSH 服务器之间的所有流量都是加密的 +4. SSH 服务器代替你连接数据库 + +## 何时使用 SSH Tunneling + +- 数据库服务器位于私有网络中 +- 数据库服务器只接受本地连接 +- 需要加密数据库连接 +- 需要通过堡垒机/跳板机访问数据库 + +## 设置 SSH Tunneling + + + + 打开数据库的连接表单 + + + 将 **SSH Tunnel** 开关切换为 ON + + + 输入 SSH 服务器信息和认证方式 + + + 点击 **Test Connection** 验证隧道是否正常工作 + + + +{/* Screenshot: Connection form with SSH section expanded */} + + SSH tunnel 设置 + SSH tunnel 设置 + + +## SSH 配置选项 + +### SSH 服务器设置 + +| 字段 | 描述 | 默认值 | +|-------|-------------|---------| +| **SSH Host** | SSH 服务器主机名或 IP | - | +| **SSH Port** | SSH 服务器端口 | `22` | +| **SSH User** | SSH 用户名 | - | + +### 认证方式 + +TablePro 支持三种 SSH 认证方式: + + + + 简单的密码认证: + + | 字段 | 描述 | + |-------|-------------| + | **SSH Pass** | 你的 SSH 密码 | + + + 密码认证不如密钥认证安全。生产服务器请使用 SSH 密钥。 + + + + 基于密钥的认证(更安全): + + | 字段 | 描述 | + |-------|-------------| + | **Key File** | 私钥路径(如 `~/.ssh/id_rsa`) | + | **Passphrase** | 密钥口令(如果已加密) | + + + 点击 **Browse** 选择私钥文件。TablePro 默认在 `~/.ssh/` 中查找。 + + + + 将签名委托给 SSH agent 进程(1Password、Secretive、macOS `ssh-agent`)。密钥保留在 agent 中,TablePro 不会读取。 + + | 字段 | 描述 | + |-------|-------------| + | **Agent Socket** | 下拉菜单,可选 `SSH_AUTH_SOCK`、`1Password` 或 `Custom Path` | + + - **SSH_AUTH_SOCK**:使用系统的 `SSH_AUTH_SOCK` 环境变量。 + - **1Password**:使用 1Password 的默认 socket 路径 `~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock`。 + - **Custom Path**:显示文本框,可输入其他 agent socket 路径。 + + + 1Password 文档中也提到 `~/.1password/agent.sock` 作为更简短的别名,但该快捷方式仅在你自己创建后才有效。TablePro 的 **1Password** 选项使用 `~/Library/Group Containers/...` 中的默认路径。 + + + + +{/* Screenshot: SSH authentication methods */} + + SSH 认证方式 + SSH 认证方式 + + +### 使用 SSH Config + +如果你在 `~/.ssh/config` 中有配置项,TablePro 会自动读取: + +1. TablePro 在启动时读取你的 SSH 配置 +2. 从 **SSH Host** 下拉菜单中选择主机 +3. 设置会从配置中自动填充 + +SSH 配置示例: + +``` +# ~/.ssh/config +Host production-jump + HostName jump.example.com + User deploy + Port 22 + IdentityFile ~/.ssh/production_key +``` + +这会在 SSH Host 下拉菜单中显示为「production-jump」。 + +{/* Screenshot: SSH config hosts */} + + SSH 配置主机 + SSH 配置主机 + + +## 数据库连接设置 + +使用 SSH tunneling 时,数据库 host 是相对于 SSH 服务器的: + +| 字段 | 值 | 描述 | +|-------|-------|-------------| +| **Host** | `localhost` 或 `127.0.0.1` | 数据库在 SSH 服务器本机上 | +| **Host** | `db.internal` | 数据库在内部网络中 | +| **Port** | `3306`、`5432` 等 | 数据库端口(不变) | + + +数据库 host 应该是 SSH 服务器用来访问数据库的地址,而不是你的 Mac 使用的地址。 + + +### 常见场景 + +#### 数据库在 SSH 服务器上 + +数据库与 SSH 服务器运行在同一台机器上: + +``` +SSH Host: jump.example.com +SSH User: deploy + +Database Host: localhost +Database Port: 3306 +``` + +#### 数据库在内部网络中 + +数据库在另一台服务器上,只能从 SSH 服务器访问: + +``` +SSH Host: jump.example.com +SSH User: deploy + +Database Host: db.internal.example.com +Database Port: 5432 +``` + +#### 通过堡垒机访问 AWS RDS + +通过 EC2 堡垒机连接 RDS: + +``` +SSH Host: bastion.example.com +SSH User: ec2-user +Key File: ~/.ssh/aws-key.pem + +Database Host: mydb.abc123.us-east-1.rds.amazonaws.com +Database Port: 5432 +``` + +## 多跳 SSH(ProxyJump) + +当数据库服务器位于多个堡垒机之后时,TablePro 可以使用 OpenSSH 的 `-J`(ProxyJump)标志链接 SSH 跳转。单个 `ssh` 进程处理所有中间跳转。 + +```mermaid +flowchart LR + subgraph mac ["你的 Mac"] + TablePro["TablePro"] + end + + subgraph hop1 ["堡垒机 1"] + B1["跳板主机 1"] + end + + subgraph hop2 ["堡垒机 2"] + B2["跳板主机 2"] + end + + subgraph db ["数据库服务器"] + Database["MySQL
PostgreSQL"] + end + + TablePro -->|"跳转 1"| B1 -->|"跳转 2"| B2 -->|"最终跳转"| Database +``` + +### 设置多跳 + +1. 打开连接表单并切换到 **SSH Tunnel** 标签页 +2. 启用 SSH 并配置**最终 SSH 服务器**(能访问数据库的那台) +3. 展开认证设置下方的 **Jump Hosts** 部分 +4. 点击 **Add Jump Host** 并按顺序填写每个中间堡垒机 +5. 主机按顺序连接:第一个跳板主机从你的 Mac 访问,每个后续主机通过前一个访问 + +### Jump Host 设置 + +每个 jump host 有以下配置: + +| 字段 | 描述 | +|-------|-------------| +| **Host** | 跳板主机的主机名或 IP | +| **Port** | SSH 端口(默认 `22`) | +| **Username** | 此跳转的 SSH 用户名 | +| **Auth Method** | **Private Key** 或 **SSH Agent**(jump host 不支持密码认证) | +| **Key File** | 私钥路径(使用 Private Key 认证时) | + +### 示例:两个堡垒机 + +``` +Jump Host 1: admin@bastion1.example.com:22 (SSH Agent) +Jump Host 2: tunnel@bastion2.internal:2222 (Private Key) + +SSH Server: deploy@final-ssh.internal:22 +Database Host: db.internal:5432 +``` + +这等效于: +```bash +ssh -J admin@bastion1.example.com:22,tunnel@bastion2.internal:2222 deploy@final-ssh.internal +``` + +### SSH Config 集成 + +TablePro 读取 `~/.ssh/config` 中的 `ProxyJump` 指令。当你选择设置了 `ProxyJump` 的配置主机时,jump host 会自动填充。 + +``` +# ~/.ssh/config +Host production-db + HostName final-ssh.internal + User deploy + ProxyJump admin@bastion1.example.com,tunnel@bastion2.internal:2222 +``` + + +Jump host 仅支持 **Private Key** 和 **SSH Agent** 认证。不支持中间跳转的密码认证,因为 OpenSSH 的 `-J` 标志不支持 jump host 的交互式密码提示。 + + +## SSH 密钥设置 + +### 生成 SSH 密钥 + +如果你没有 SSH 密钥: + +```bash +# 生成新的密钥对 +ssh-keygen -t ed25519 -C "your_email@example.com" + +# 或使用 RSA 以获得更广泛的兼容性 +ssh-keygen -t rsa -b 4096 -C "your_email@example.com" +``` + +### 密钥位置 + +macOS 上的默认密钥位置: + +| 密钥类型 | 私钥 | 公钥 | +|----------|-------------|------------| +| Ed25519 | `~/.ssh/id_ed25519` | `~/.ssh/id_ed25519.pub` | +| RSA | `~/.ssh/id_rsa` | `~/.ssh/id_rsa.pub` | +| ECDSA | `~/.ssh/id_ecdsa` | `~/.ssh/id_ecdsa.pub` | + +### 将密钥添加到服务器 + +将公钥复制到 SSH 服务器: + +```bash +# 使用 ssh-copy-id +ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server + +# 或手动操作 +cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" +``` + +### 密钥权限 + +SSH 密钥必须有正确的权限: + +```bash +# 修复权限 +chmod 700 ~/.ssh +chmod 600 ~/.ssh/id_* +chmod 644 ~/.ssh/id_*.pub +chmod 644 ~/.ssh/config +``` + +## 从 URL 导入 + +通过 URL 导入 SSH tunnel 连接,无需逐个填写字段。TablePro 支持 `+ssh` URL scheme,将 SSH 和数据库凭据编码在同一个字符串中。 + +完整的 URL 规范请参阅 [连接 URL 参考](/zh/databases/connection-urls#ssh-tunnel-格式)。 + +**格式:** + +``` +scheme+ssh://ssh_user@ssh_host:ssh_port/db_user:db_password@db_host/db_name?name=MyConnection&usePrivateKey=true +``` + +**支持的 scheme:** `mysql+ssh`、`postgresql+ssh`、`postgres+ssh`、`mariadb+ssh` + +**示例:** + +``` +mysql+ssh://root@123.123.123.123:1234/database_user:database_password@127.0.0.1/database_name?name=FlashPanel&usePrivateKey=true +``` + +这会填充: +- **SSH Host**:`123.123.123.123`,**SSH Port**:`1234`,**SSH User**:`root` +- **Database Host**:`127.0.0.1`,**Database User**:`database_user`,**Database**:`database_name` +- **Connection Name**:`FlashPanel`,**Auth Method**:Private Key + +**查询参数:** + +| 参数 | 描述 | +|-----------|-------------| +| `name` | 设置连接名称 | +| `usePrivateKey` | 设为 `true` 选择 Private Key 认证 | +| `useSSHAgent` | 设为 `true` 选择 SSH Agent 认证 | +| `agentSocket` | 可选的 SSH agent socket 路径覆盖(例如 `~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock`) | + +导入方法:打开 **New Connection**,点击 **Import from URL**,然后粘贴 URL。 + + +此格式与 TablePlus SSH 连接 URL 兼容,因此迁移时可以直接粘贴 URL。 + + +## 故障排除 + +### 连接被拒绝 + +**症状**:测试 SSH tunnel 时 "Connection refused" + +**原因及解决方案**: + +1. **SSH 服务器未运行** + ```bash + # 直接测试 SSH 连接 + ssh -v user@server + ``` + +2. **端口错误** + - 验证 SSH 端口(某些服务器使用非标准端口) + - 向服务器管理员确认 + +3. **防火墙阻止连接** + - 确保端口 22(或自定义端口)已开放 + - 检查本地和服务器的防火墙 + +### 认证失败 + +**症状**:"SSH authentication failed" 或 "Permission denied" + +**密码认证**: +1. 验证用户名和密码 +2. 检查服务器是否启用了密码认证 +3. 尝试通过终端连接:`ssh user@server` + +**密钥认证**: +1. 验证密钥文件路径正确 +2. 检查密钥权限(`chmod 600`) +3. 确保公钥在服务器的 `authorized_keys` 中 +4. 验证口令(如果密钥已加密) +5. 尝试通过终端连接: + ```bash + ssh -i ~/.ssh/your_key user@server + ``` + +### 私钥错误 + +**"Private key file not found"**: +- 验证路径是否存在 +- 使用 Browse 按钮选择文件 + +**"Private key file is not readable"**: +```bash +chmod 600 ~/.ssh/your_key +``` + +**"Wrong passphrase"**: +- 重新输入口令 +- 手动测试密钥:`ssh-keygen -y -f ~/.ssh/your_key` + +### Tunnel 已建立但数据库连接失败 + +如果 SSH tunnel 连接成功但数据库连接失败: + +1. **验证数据库 host 正确**(相对于 SSH 服务器) + ```bash + # 从 SSH 服务器测试数据库连接 + ssh user@server "mysql -h localhost -u dbuser -p" + ``` + +2. **检查数据库端口** + - 确保端口与数据库服务器的实际端口匹配 + +3. **验证数据库凭据** + - 用户名/密码可能与 SSH 凭据不同 + +### Tunnel 定期断开 + +TablePro 使用保活设置维护隧道: + +- `ServerAliveInterval=60`:每 60 秒发送保活信号 +- `ServerAliveCountMax=3`:3 次未响应后断开 + +如果隧道仍然断开: +1. 检查网络稳定性 +2. 验证服务器的 `ClientAliveInterval` 设置 +3. 检查防火墙的空闲超时设置 + +{/* Screenshot: SSH tunnel active */} + + 活跃的 SSH tunnel 状态 + 活跃的 SSH tunnel 状态 + + +## 安全注意事项 + +### 最佳实践 + +1. **使用密钥认证** 而非密码 +2. **使用 Ed25519 或 4096 位以上的 RSA 密钥** +3. **用口令保护私钥** +4. **限制 SSH 访问** 到特定的用户/IP +5. **使用专用跳板机** 而非直接访问数据库 + +### 加密范围 + +| 数据 | 是否加密 | +|------|-----------| +| SSH 连接 | 是 | +| 数据库凭据 | 是(通过隧道) | +| 查询数据 | 是(通过隧道) | +| 本地存储的密码 | 是(macOS Keychain) | + +### 应避免的做法 + +- 不要共享私钥 +- 不要在生产服务器上使用密码认证 +- 不要以明文存储 SSH 密码 +- 不要将数据库端口直接暴露到互联网 + +## SSH Agent 认证 + +使用 SSH Agent 认证时,你的私钥不会离开 agent 进程。1Password、Secretive 或内置的 macOS `ssh-agent` 持有密钥,代表 TablePro 进行签名。 + +### 设置 + +1. 选择 **SSH Agent** 作为认证方式 +2. 从下拉菜单中选择 **Agent Socket** 选项 +3. 选择 **SSH_AUTH_SOCK** 使用系统默认值 +4. 选择 **1Password** 使用 `~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock` +5. 选择 **Custom Path** 手动输入其他 socket 路径 + +### 验证 Agent + +确认 agent 已加载密钥: + +```bash +# 列出 agent 中的密钥 +ssh-add -l + +# 如果为空,添加密钥 +ssh-add ~/.ssh/id_ed25519 +``` + +### Agent Socket 选项 + +| 选项 | 行为 | +|--------|----------| +| `SSH_AUTH_SOCK` | 使用当前的 `SSH_AUTH_SOCK` 环境变量 | +| `1Password` | 使用 `~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock` | +| `Custom Path` | 允许输入其他 socket 路径,例如 Secretive 偏好设置中显示的路径 | + +## 后续步骤 + + + + MySQL 特有的设置和功能 + + + PostgreSQL 特有的设置和功能 + + + 管理所有连接 + + + 加速你的工作流程 + + diff --git a/docs/zh/development/architecture.mdx b/docs/zh/development/architecture.mdx new file mode 100644 index 00000000..29806c54 --- /dev/null +++ b/docs/zh/development/architecture.mdx @@ -0,0 +1,412 @@ +--- +title: 架构 +description: MVVM 结构、数据库驱动协议、基于 Actor 的 SSH 隧道和自动补全引擎内部机制 +--- + +# 架构 + +TablePro 使用以下技术构建: + +- **SwiftUI** 用于 UI +- **AppKit** 用于底层 macOS 集成 +- **Swift Concurrency**(async/await、actors)用于并发操作 +- **原生 C 库**用于数据库连接 + +```mermaid +block-beta + columns 3 + + block:ui["User Interface"]:3 + Views["Views
(SwiftUI)"] + ViewModels["ViewModels
(Observable)"] + Theme["Theme
(Colors)"] + end + + block:logic["Business Logic"]:3 + Drivers["Database
Drivers"] + Autocomplete["Autocomplete
Engine"] + SSH["SSH
Tunnel"] + end + + block:data["Data Layer"]:3 + Models["Models
(Structs)"] + Storage["Storage
(JSON)"] + Keychain["Keychain
(Passwords)"] + end + + block:native["Native Libraries"]:3 + libmariadb["libmariadb
(MySQL)"] + libpq["libpq
(PostgreSQL)"] + SQLite["SQLite
(Built-in)"] + end +``` + +## 依赖 + +SPM 依赖: + +| 包 | 版本 | 用途 | +|---------|---------|---------| +| **CodeEditSourceEditor** | 0.15.2+ | 基于 Tree-sitter 的代码编辑器,用于 SQL 编辑器 | +| **Sparkle** | 2.x | 支持 EdDSA 签名的自动更新框架 | + + +CodeEditSourceEditor 捆绑了一个 SwiftLint 插件,CLI 构建时需要 `-skipPackagePluginValidation` 参数。详见[构建](/zh/development/building)。 + + +## 目录结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## 设计模式 + +### MVVM 架构 + +```mermaid +flowchart LR + Model["Model
(Struct)"] <--> ViewModel["ViewModel
(Observable)"] <--> View["View
(SwiftUI)"] +``` + +**Models**:纯数据结构(structs、enums) +```swift +struct DatabaseConnection: Codable, Identifiable { + let id: UUID + var name: String + var host: String + var port: Int + var type: DatabaseType +} +``` + +**ViewModels**:可观察的状态容器 +```swift +@MainActor +class DatabaseManager: ObservableObject { + @Published var sessions: [DatabaseSession] = [] + @Published var activeSessionId: UUID? + + func connect(to connection: DatabaseConnection) async throws { + // 业务逻辑 + } +} +``` + +**Views**:声明式 SwiftUI +```swift +struct ConnectionFormView: View { + @StateObject private var dbManager = DatabaseManager.shared + + var body: some View { + Form { + // UI 元素 + } + } +} +``` + +### 面向协议设计 + +所有数据库驱动遵循统一协议: + +```swift +protocol DatabaseDriver: AnyObject { + var connection: DatabaseConnection { get } + var status: ConnectionStatus { get } + + func connect() async throws + func disconnect() + func execute(query: String) async throws -> QueryResult + func fetchTables() async throws -> [TableInfo] + // ... +} +``` + +数据库驱动以 `.tableplugin` bundle 形式实现,在运行时加载。每个插件实现共享 `TableProPluginKit` 框架中的 `DriverPlugin` 和 `PluginDatabaseDriver`。`PluginDriverAdapter` 将 `PluginDatabaseDriver` 桥接到核心 `DatabaseDriver` 协议。 + +### Actor 隔离 + +并发操作使用 Swift actors: + +```swift +actor SSHTunnelManager { + static let shared = SSHTunnelManager() + + private var tunnels: [UUID: SSHTunnel] = [:] + + func createTunnel( + connectionId: UUID, + sshHost: String, + // ... + ) async throws -> Int { + // 线程安全的隧道管理 + } +} +``` + +### 插件系统 + +驱动创建使用基于插件的工厂模式。`PluginManager` 在运行时发现并加载 `.tableplugin` bundle。`DatabaseDriverFactory` 通过 `DatabaseType.pluginTypeId` 查找插件,并使用 `PluginDriverAdapter` 将其包装为核心 `DatabaseDriver` 协议。无需 switch 语句或硬编码的驱动列表。 + +## 核心组件 + +### DatabaseManager + +所有数据库操作的中央管理器: + +- 管理活跃会话 +- 协调连接/断开操作 +- 处理 SSH 隧道生命周期 +- 向 UI 发布状态变更 + +```swift +@MainActor +class DatabaseManager: ObservableObject { + static let shared = DatabaseManager() + + @Published var sessions: [DatabaseSession] = [] + @Published var activeSessionId: UUID? + + func connectToSession(_ connection: DatabaseConnection) async throws + func disconnectSession(_ id: UUID) async + func executeQuery(_ query: String) async throws -> QueryResult +} +``` + +### 数据库驱动插件 + +每个驱动是 `Plugins/` 下的 `.tableplugin` bundle: + +| 插件 | 数据库类型 | C 桥接 | +|--------|---------------|----------| +| MySQLDriverPlugin | MySQL, MariaDB | CMariaDB (libmariadb) | +| PostgreSQLDriverPlugin | PostgreSQL, Redshift | CLibPQ (libpq) | +| SQLiteDriverPlugin | SQLite | Foundation sqlite3 | +| ClickHouseDriverPlugin | ClickHouse | URLSession HTTP | +| MSSQLDriverPlugin | SQL Server | CFreeTDS | +| MongoDBDriverPlugin | MongoDB | CLibMongoc | +| RedisDriverPlugin | Redis | CRedis | +| OracleDriverPlugin | Oracle | OracleNIO (SPM) | + +### 自动补全引擎 + +```mermaid +flowchart TB + Engine["CompletionEngine
(Entry)"] + Engine --> Context["SQLContext
Analyzer"] + Engine --> Schema["SQLSchema
Provider"] + Schema --> Tables["Tables"] + Schema --> Columns["Columns"] + Context --> Keywords["SQLKeywords"] +``` + +- **CompletionEngine**:主入口 +- **SQLContextAnalyzer**:解析查询上下文 +- **SQLSchemaProvider**:提供 schema 信息 +- **SQLKeywords**:SQL 关键字定义 + +### SSH 隧道管理器 + +基于 Actor 的 SSH 隧道管理: + +```swift +actor SSHTunnelManager { + private var tunnels: [UUID: SSHTunnel] = [:] + + func createTunnel(...) async throws -> Int + func closeTunnel(connectionId: UUID) async throws + func hasTunnel(connectionId: UUID) -> Bool +} +``` + +特性: +- 通过系统 `ssh` 命令进行端口转发 +- 密码和密钥认证 +- 健康监测 +- 自动清理 + +## 数据流 + +### 连接流程 + +```mermaid +flowchart TB + User["用户点击连接"] + User --> Form["ConnectionFormView
(UI 验证)"] + Form --> Manager["DatabaseManager
.connectToSession"] + Manager --> SSH["SSHTunnelManager"] + Manager --> Factory["DatabaseDriverFactory"] + Factory --> Plugin["PluginManager
(加载 .tableplugin)"] + Plugin --> Adapter["PluginDriverAdapter"] + SSH --> Connected["连接已建立"] + Adapter --> Connected + + subgraph optional ["如果启用了 SSH"] + SSH + end +``` + +### 查询执行流程 + +```mermaid +flowchart TB + User["用户执行查询
(Cmd+Enter)"] + User --> Editor["EditorTextView
(获取查询)"] + Editor --> Manager["DatabaseManager
.executeQuery"] + Manager --> Driver["DatabaseDriver
.execute(query)"] + Driver --> Result["QueryResult
(行 + 列)"] + Result --> Grid["DataGridView
(显示结果)"] +``` + +## 状态管理 + +### Published 属性 + +UI 状态使用 `@Published`: + +```swift +@MainActor +class DatabaseManager: ObservableObject { + @Published var sessions: [DatabaseSession] = [] + @Published var activeSessionId: UUID? + @Published var isConnecting = false +} +``` + +### App Storage + +设置通过 `@AppStorage` 持久化: + +```swift +@AppStorage("appearance.theme") var theme: AppTheme = .system +@AppStorage("editor.fontSize") var fontSize: Int = 13 +``` + +### Environment + +通过 SwiftUI environment 共享状态: + +```swift +@main +struct TableProApp: App { + @StateObject private var dbManager = DatabaseManager.shared + + var body: some Scene { + WindowGroup { + ContentView() + .environmentObject(dbManager) + } + } +} +``` + +## 错误处理 + +### 驱动错误 + +每个驱动定义特定的错误类型: + +```swift +enum MySQLError: Error, LocalizedError { + case connectionFailed(String) + case queryFailed(String) + case authenticationFailed + + var errorDescription: String? { + switch self { + case .connectionFailed(let msg): return "Connection failed: \(msg)" + case .queryFailed(let msg): return "Query failed: \(msg)" + case .authenticationFailed: return "Authentication failed" + } + } +} +``` + +### 错误传播 + +错误通过 async/await 传播: + +```swift +func executeQuery(_ query: String) async throws -> QueryResult { + guard let driver = activeDriver else { + throw DatabaseError.notConnected + } + return try await driver.execute(query: query) +} +``` + +## 测试 + +### 单元测试 + +测试位于 `TableProTests/`: + +```swift +final class MySQLDriverTests: XCTestCase { + func testConnectionString() throws { + let connection = DatabaseConnection(...) + let driver = MySQLDriver(connection: connection) + XCTAssertEqual(driver.connectionString, "expected") + } +} +``` + +### 集成测试 + +```swift +func testExecuteQuery() async throws { + let driver = MySQLDriver(connection: testConnection) + try await driver.connect() + defer { driver.disconnect() } + + let result = try await driver.execute(query: "SELECT 1") + XCTAssertEqual(result.rowCount, 1) +} +``` + +## 下一步 + + + + 编码规范和风格指南 + + + 构建和发布流程 + + + 开发环境搭建 + + + 源代码仓库 + + diff --git a/docs/zh/development/building.mdx b/docs/zh/development/building.mdx new file mode 100644 index 00000000..1187e15f --- /dev/null +++ b/docs/zh/development/building.mdx @@ -0,0 +1,356 @@ +--- +title: 构建 +description: Debug 构建、arm64/x86_64 发布构建、DMG 打包、代码签名和 CI/CD 工作流 +--- + +# 构建 TablePro + +## 开发构建 + +### 使用 Xcode + +1. 打开 `TablePro.xcodeproj` +2. 选择 **TablePro** scheme +3. 选择 **My Mac** 作为目标设备 +4. `Cmd+R` 构建并运行,或 `Cmd+B` 仅构建 + +### 使用命令行 + +```bash +# 为当前架构构建(Debug) +xcodebuild -project TablePro.xcodeproj \ + -scheme TablePro \ + -configuration Debug \ + build \ + -skipPackagePluginValidation + +# 构建并运行 +xcodebuild -project TablePro.xcodeproj \ + -scheme TablePro \ + -configuration Debug \ + build \ + -skipPackagePluginValidation && open build/Debug/TablePro.app +``` + +### 清理构建 + +遇到构建问题时: + +```bash +# 通过 xcodebuild 清理 +xcodebuild -project TablePro.xcodeproj -scheme TablePro clean + +# 或清理 Derived Data +rm -rf ~/Library/Developer/Xcode/DerivedData + +# 或在 Xcode 中:Cmd+Shift+K +``` + +## 发布构建 + +### 使用构建脚本 + +```bash +# Apple Silicon(M1/M2/M3/M4/M5) +scripts/build-release.sh arm64 + +# Intel +scripts/build-release.sh x86_64 + +# 双架构 +scripts/build-release.sh both +``` + +### 构建脚本详情 + +`build-release.sh` 执行以下步骤: + +1. **准备库文件**:从 universal 库中提取对应架构的部分 +2. **构建应用**:使用 Release 配置运行 xcodebuild +3. **复制输出**:将应用放置到 `build/Release/` +4. **恢复图标**:确保包含完整的应用图标 +5. **验证架构**:确认二进制文件与目标架构匹配 + +### 输出位置 + +``` +build/Release/TablePro-arm64.app # Apple Silicon +build/Release/TablePro-x86_64.app # Intel +``` + +### 手动发布构建 + +```bash +# 设置架构 +ARCH=arm64 # or x86_64 + +# 构建 +xcodebuild \ + -project TablePro.xcodeproj \ + -scheme TablePro \ + -configuration Release \ + -arch $ARCH \ + ONLY_ACTIVE_ARCH=YES \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + clean build +``` + +## 原生库 + +TablePro 使用原生 C 库进行数据库连接。 + +### 库文件 + +位于 `Libs/` 目录下: + +| 文件 | 用途 | +|------|---------| +| `libmariadb_universal.a` | Universal(arm64 + x86_64)MariaDB 库 | +| `libmariadb.a` | 特定架构的库(构建时创建) | + +### 库设置 + +构建前必须存在 universal 库: + +```bash +# 检查 universal 库是否存在 +ls -la Libs/libmariadb_universal.a + +# 如果缺失,从特定架构的库创建 +lipo -create \ + Libs/libmariadb_arm64.a \ + Libs/libmariadb_x86_64.a \ + -output Libs/libmariadb_universal.a +``` + +构建脚本会自动提取正确架构的切片。 + +## 创建 DMG + +### 使用 DMG 脚本 + +```bash +# 先构建发布版本 +scripts/build-release.sh arm64 + +# 然后创建 DMG +scripts/create-dmg.sh arm64 +``` + +### DMG 内容 + +- TablePro.app +- Applications 文件夹快捷方式 +- 背景图片(如已配置) +- 许可证文件(如包含) + +### 输出 + +``` +build/Release/TablePro-arm64.dmg +build/Release/TablePro-x86_64.dmg +``` + +## 代码签名 + +### 开发构建 + +默认不签名,本地测试足够使用。 + +### 发布分发 + +签名(需要 Apple Developer 账号): + +```bash +# 签名应用 +codesign --force --deep --sign "Developer ID Application: Your Name (TEAM_ID)" \ + build/Release/TablePro-arm64.app + +# 验证签名 +codesign --verify --verbose build/Release/TablePro-arm64.app +``` + +### 公证 + +用于 App Store 之外的分发: + +```bash +# 创建用于公证的 ZIP +ditto -c -k --keepParent build/Release/TablePro-arm64.app TablePro.zip + +# 提交公证 +xcrun notarytool submit TablePro.zip \ + --apple-id "your@email.com" \ + --team-id "TEAM_ID" \ + --password "app-specific-password" \ + --wait + +# 装订票据 +xcrun stapler staple build/Release/TablePro-arm64.app +``` + +## 构建配置 + +### 构建设置 + +| 设置 | Debug | Release | +|---------|-------|---------| +| 优化 | 无 (-O0) | 速度优化 (-O) | +| 调试信息 | 完整 | 已剥离 | +| 断言 | 启用 | 禁用 | +| 代码签名 | 无 | Developer ID(可选) | + +### 架构设置 + +| 设置 | 值 | +|---------|-------| +| ARCHS | Standard (arm64, x86_64) | +| ONLY_ACTIVE_ARCH | Yes (Debug), No (Release) | +| VALID_ARCHS | arm64 x86_64 | + +## 故障排除 + +### 构建失败 + +**缺少库错误**: +``` +ld: library not found for -lmariadb +``` + +修复: +1. 检查 `Libs/` 目录是否存在 +2. 运行 `scripts/build-release.sh` 准备库文件 +3. 验证目标架构的 `libmariadb.a` 是否存在 + +**代码签名错误**: +``` +Code signing is required for product type 'Application' +``` + +修复:构建脚本会禁用代码签名。手动构建时添加: +``` +CODE_SIGN_IDENTITY="" +CODE_SIGNING_REQUIRED=NO +``` + +**架构不匹配**: +``` +building for macOS-arm64 but attempting to link with file built for macOS-x86_64 +``` + +修复: +1. 清理构建文件夹 +2. 确保库文件与目标架构匹配 +3. 使用构建脚本,它会处理库的架构问题 + +### Xcode 问题 + +**找不到 Scheme**: +1. 打开 Xcode +2. Product > Scheme > Manage Schemes +3. 确认 TablePro scheme 已启用 + +**Derived Data 问题**: +```bash +rm -rf ~/Library/Developer/Xcode/DerivedData +``` + +**索引问题**: +```bash +rm -rf ~/Library/Developer/Xcode/DerivedData/*/Index +``` + +## CI/CD + +### GitHub Actions + +CI 工作流示例: + +```yaml +name: Build + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode_15.0.app + + - name: Build + run: | + xcodebuild -project TablePro.xcodeproj \ + -scheme TablePro \ + -configuration Debug \ + build \ + -skipPackagePluginValidation + + - name: Test + run: | + xcodebuild -project TablePro.xcodeproj \ + -scheme TablePro \ + test \ + -skipPackagePluginValidation +``` + +### 发布工作流 + +```yaml +release: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Release (arm64) + run: scripts/build-release.sh arm64 + + - name: Build Release (x86_64) + run: scripts/build-release.sh x86_64 + + - name: Create DMGs + run: | + scripts/create-dmg.sh arm64 + scripts/create-dmg.sh x86_64 + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: release-dmgs + path: build/Release/*.dmg +``` + +## 构建大小 + +典型大小(v0.1.1): + +| 构建类型 | 大小 | +|-------|------| +| Debug 应用 | ~15 MB | +| Release 应用 | ~10 MB | +| DMG (arm64) | ~3.5 MB | +| DMG (x86_64) | ~3.5 MB | + +## 下一步 + + + + 开发环境搭建 + + + 代码库架构 + + + 编码规范 + + + 源代码仓库 + + diff --git a/docs/zh/development/code-style.mdx b/docs/zh/development/code-style.mdx new file mode 100644 index 00000000..4b3b6f29 --- /dev/null +++ b/docs/zh/development/code-style.mdx @@ -0,0 +1,520 @@ +--- +title: 代码风格 +description: Swift 编码规范、SwiftLint/SwiftFormat 规则、命名、访问控制和文件组织 +--- + +# 代码风格指南 + +这些规范使 TablePro 的代码库保持一致且易读。 + +## 工具 + +| 工具 | 用途 | 配置文件 | +|------|---------|-------------| +| **SwiftLint** | 代码检查和静态分析 | `.swiftlint.yml` | +| **SwiftFormat** | 代码格式化 | `.swiftformat` | + +### 运行工具 + +```bash +# 检查代码问题 +swiftlint lint + +# 自动修复代码问题 +swiftlint --fix + +# 格式化代码 +swiftformat . + +# 仅检查格式不应用更改 +swiftformat --lint . +``` + + +提交前运行这些工具。SwiftLint 也会在 Xcode 构建时自动运行。 + + +## 架构原则 + +### 关注点分离 + +- 业务逻辑应放在 models/view models 中,而非 views +- Views 只负责展示 + +```swift +// Good: Logic in ViewModel +class ConnectionViewModel: ObservableObject { + func validateConnection() -> Bool { + return !host.isEmpty && port > 0 + } +} + +// Bad: Logic in View +struct ConnectionView: View { + var body: some View { + Button("Connect") { + // Don't put validation logic here + } + .disabled(host.isEmpty || port <= 0) + } +} +``` + +### 值类型优先 + +除非需要引用语义,否则优先使用 `struct` 而非 `class`: + +```swift +// Good: Value type for data +struct DatabaseConnection: Codable { + let id: UUID + var name: String + var host: String +} + +// When to use class: shared state, identity matters +@MainActor +class DatabaseManager: ObservableObject { + static let shared = DatabaseManager() +} +``` + +### 不可变性 + +默认使用 `let`,只在需要修改时使用 `var`: + +```swift +// Good +let connection = DatabaseConnection(...) +let results = try await driver.execute(query: sql) + +// Only var when needed +var currentPage = 1 +currentPage += 1 +``` + +## 命名规范 + +### 类型 + +| 元素 | 规范 | 示例 | +|---------|------------|---------| +| 类/结构体 | UpperCamelCase | `DatabaseConnection` | +| 枚举 | UpperCamelCase | `DatabaseType` | +| 枚举值 | lowerCamelCase | `.postgresql` | +| 协议 | UpperCamelCase | `DatabaseDriver` | + +### 函数和变量 + +| 元素 | 规范 | 示例 | +|---------|------------|---------| +| 函数 | lowerCamelCase | `executeQuery()` | +| 变量 | lowerCamelCase | `connectionString` | +| 常量 | lowerCamelCase | `maxRetryAttempts` | +| 参数 | lowerCamelCase | `tableName: String` | + +### 布尔属性 + +使用 `is`/`has`/`can` 前缀: + +```swift +var isConnected: Bool +var hasValidCredentials: Bool +var canExecuteQuery: Bool +``` + +### 工厂方法 + +使用 `make` 前缀: + +```swift +func makeConnection() -> DatabaseConnection +func makeDriver(for type: DatabaseType) -> DatabaseDriver +``` + +## 格式化 + +### 缩进 + +- **4 个空格**(不使用制表符) +- 配置编辑器将制表符转换为空格 + +### 行长度 + +- 每行最多 **120 个字符** +- 过长的行应换行以提高可读性 + +```swift +// Good: Line breaks for readability +let result = try await driver.executeParameterized( + query: "SELECT * FROM users WHERE email = ?", + parameters: [email] +) + +// Avoid: Long single line +let result = try await driver.executeParameterized(query: "SELECT * FROM users WHERE email = ?", parameters: [email]) +``` + +### 花括号 + +K&R 风格 - 左花括号在同一行: + +```swift +// Good +if condition { + doSomething() +} else { + doSomethingElse() +} + +// Bad +if condition +{ + doSomething() +} +``` + +### 空格 + +```swift +// Space around operators +let sum = a + b +let isValid = count > 0 && name.isEmpty == false + +// No space for ranges +for i in 0..<10 { } + +// Space after colon in type declarations +var name: String +func connect(host: String, port: Int) +``` + +## 访问控制 + +### 显式声明 + +始终显式指定访问修饰符: + +```swift +// Good: Explicit access +private var connectionPool: [Connection] = [] +internal func processResult(_ result: QueryResult) +public func connect() async throws + +// Avoid: Implicit internal +var connectionPool: [Connection] = [] // Implicit internal +``` + +### 倾向私有 + +使用尽可能严格的访问级别: + +```swift +class DatabaseManager { + // Public API + public func connect() async throws { ... } + + // Internal helpers + private func validateConnection() -> Bool { ... } + private var activeDriver: DatabaseDriver? +} +``` + +### Extension 访问控制 + +在 extension 上指定访问修饰符,而非单独的成员: + +```swift +// Good +public extension NSEvent { + var semanticKeyCode: KeyCode? { ... } +} + +// Avoid +extension NSEvent { + public var semanticKeyCode: KeyCode? { ... } +} +``` + +## Optional 处理 + +### 避免强制解包 + +不要使用 `!` 解包: + +```swift +// Good +if let connection = connection { + use(connection) +} + +guard let result = result else { return } + +// Bad +let connection = connection! // Crash if nil +``` + +### 安全类型转换 + +使用条件类型转换: + +```swift +// Good +if let value = param as? SQLFunctionLiteral { + return value.property +} + +// Bad +let value = param as! SQLFunctionLiteral // Crash if wrong type +``` + +### 使用 guard 提前退出 + +使用 `guard` 减少嵌套: + +```swift +// Good +func processResult(_ result: QueryResult?) -> [Row] { + guard let result = result else { return [] } + guard result.rowCount > 0 else { return [] } + + return result.rows.map { transform($0) } +} + +// Avoid deep nesting +func processResult(_ result: QueryResult?) -> [Row] { + if let result = result { + if result.rowCount > 0 { + return result.rows.map { transform($0) } + } + } + return [] +} +``` + +## 集合 + +### 使用语义化方法 + +```swift +// Good +if items.isEmpty { } +if items.contains(target) { } +if let first = items.first(where: { $0.isValid }) { } + +// Avoid +if items.count == 0 { } +if items.filter({ $0 == target }).count > 0 { } +if let first = items.filter({ $0.isValid }).first { } +``` + +### 移除不必要的枚举 + +```swift +// Good +items.map { item in item.value } +items.map(\.value) + +// Avoid (if index not used) +items.enumerated().map { _, item in item.value } +``` + +## 闭包 + +### 尾随闭包语法 + +当最后一个参数是闭包时使用尾随闭包: + +```swift +// Good +items.filter { $0.isActive } + .map { $0.name } + +// Avoid +items.filter({ $0.isActive }) + .map({ $0.name }) +``` + +### 隐式返回 + +单表达式闭包使用隐式返回: + +```swift +// Good +items.map { $0.name } +items.filter { $0.isActive } + +// Also good when clearer +items.map { item in + item.name +} +``` + +### 未使用的闭包参数 + +未使用的参数用 `_` 代替: + +```swift +// Good +button.onTap { _ in + handleTap() +} + +// Avoid +button.onTap { event in // event not used + handleTap() +} +``` + +## 注释 + +### 何时需要注释 + +```swift +// Good: Explain "why", not "what" +// 1.5s delay ensures the SSH tunnel is established +// before attempting the database connection +try await Task.sleep(nanoseconds: 1_500_000_000) + +// Avoid: Obvious comments +// Get the user's name +let name = user.name +``` + +### 文档注释 + +公共 API 使用 `///`: + +```swift +/// Executes a SQL query and returns the results. +/// +/// - Parameter query: The SQL query to execute +/// - Returns: A `QueryResult` containing rows and columns +/// - Throws: `DatabaseError` if the query fails +func execute(query: String) async throws -> QueryResult +``` + +### MARK 注释 + +使用 MARK 注释组织代码: + +```swift +// MARK: - Properties + +private var connection: DatabaseConnection +private var driver: DatabaseDriver? + +// MARK: - Lifecycle + +init(connection: DatabaseConnection) { + self.connection = connection +} + +// MARK: - Public Methods + +func connect() async throws { ... } + +// MARK: - Private Helpers + +private func validateConnection() -> Bool { ... } +``` + +## SwiftUI 相关 + +### View 结构 + +```swift +struct ContentView: View { + // MARK: - Properties + + @StateObject private var viewModel = ContentViewModel() + @State private var isLoading = false + + // MARK: - Body + + var body: some View { + VStack { + headerView + contentView + footerView + } + } + + // MARK: - Subviews + + private var headerView: some View { + Text("Header") + } + + private var contentView: some View { + // ... + } +} +``` + +### 属性包装器顺序 + +```swift +struct MyView: View { + // Environment + @Environment(\.dismiss) private var dismiss + @EnvironmentObject private var appState: AppState + + // State Objects + @StateObject private var viewModel = MyViewModel() + + // State + @State private var isEditing = false + @Binding var selection: Item? + + // Regular properties + let title: String +} +``` + +## 限制 + +### SwiftLint 限制 + +| 指标 | 警告 | 错误 | +|--------|---------|-------| +| 函数体长度 | 160 行 | 250 行 | +| 类型体长度 | 1100 行 | 1500 行 | +| 文件长度 | 1200 行 | 1800 行 | +| 圈复杂度 | 40 | 60 | + +### 处理过长文件 + +将 extension 提取到单独的文件中: + + + + + + + + + + +## 参考资料 + +- [Swift.org API Design Guidelines](https://swift.org/documentation/api-design-guidelines/) +- [SwiftLint Rules](https://realm.github.io/SwiftLint/rule-directory.html) +- [SwiftFormat Options](https://github.com/nicklockwood/SwiftFormat#options) + +## 下一步 + + + + 了解代码库结构 + + + 构建和发布流程 + + + 开发环境搭建 + + + 查看源代码 + + diff --git a/docs/zh/development/plugin-registry.mdx b/docs/zh/development/plugin-registry.mdx new file mode 100644 index 00000000..0b76b124 --- /dev/null +++ b/docs/zh/development/plugin-registry.mdx @@ -0,0 +1,132 @@ +--- +title: 插件注册表 +description: 如何将可下载插件发布到 TablePro 插件注册表 +--- + +# 插件注册表 + +插件注册表是托管在 [github.com/TableProApp/plugins](https://github.com/TableProApp/plugins) 上的 JSON 清单。TablePro 通过获取该清单来填充 **Settings > Plugins > Browse** 页面,并自动安装缺失的驱动插件。 + +## 清单格式 + +注册表清单(`plugins.json`)遵循 `RegistryManifest` 格式: + +```json +{ + "schemaVersion": 1, + "plugins": [ + // ... 插件条目 + ] +} +``` + +每个条目对应 `RegistryPlugin` 模型: + +| 字段 | 类型 | 必填 | 描述 | +|-------|------|----------|-------------| +| `id` | `string` | 是 | Bundle 标识符(如 `com.TablePro.OracleDriver`) | +| `name` | `string` | 是 | 显示名称 | +| `version` | `string` | 是 | 语义化版本号 | +| `summary` | `string` | 是 | 一行描述 | +| `author` | `object` | 是 | `{ "name": "...", "url": "..." }` | +| `homepage` | `string` | 否 | 项目 URL | +| `category` | `string` | 是 | 可选值:`database-driver`、`export-format`、`import-format`、`theme`、`other` | +| `databaseTypeIds` | `[string]` | 否 | 映射到 `DatabaseType.pluginTypeId` 值,用于自动安装提示 | +| `downloadURL` | `string` | 否* | `.zip` 文件的直接下载 URL | +| `sha256` | `string` | 否* | ZIP 文件的 SHA-256 十六进制摘要 | +| `binaries` | `[object]` | 否 | 按架构区分的二进制文件:`[{ "architecture": "arm64"\|"x86_64", "downloadURL": "...", "sha256": "..." }]` | +| `minAppVersion` | `string` | 否 | 最低 TablePro 版本(如 `"0.17.0"`) | +| `minPluginKitVersion` | `int` | 否 | 最低 PluginKit 版本(当前为 `1`) | +| `iconName` | `string` | 否 | 用于显示的 SF Symbol 名称 | +| `isVerified` | `bool` | 是 | 插件是否经 TablePro 团队验证 | + +\* 需要提供 `downloadURL`/`sha256`(平级字段)或 `binaries` 数组之一。如果存在 `binaries`,应用会选择匹配的架构。平级字段作为旧版应用的后备方案。 + +## Oracle 和 ClickHouse 条目 + +这两个数据库驱动以可下载插件形式提供,而非内置在应用中。其注册表条目: + +```json +{ + "id": "com.TablePro.OracleDriver", + "name": "Oracle Driver", + "version": "1.0.0", + "summary": "Oracle Database 12c+ driver via OracleNIO", + "author": { + "name": "TablePro", + "url": "https://tablepro.app" + }, + "homepage": "https://tablepro.app/databases/oracle", + "category": "database-driver", + "databaseTypeIds": ["Oracle"], + "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-oracle-v1.0.0/OracleDriver-arm64.zip", + "sha256": "", + "binaries": [ + { "architecture": "arm64", "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-oracle-v1.0.0/OracleDriver-arm64.zip", "sha256": "" }, + { "architecture": "x86_64", "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-oracle-v1.0.0/OracleDriver-x86_64.zip", "sha256": "" } + ], + "minAppVersion": "0.17.0", + "minPluginKitVersion": 1, + "iconName": "server.rack", + "isVerified": true +} +``` + +```json +{ + "id": "com.TablePro.ClickHouseDriver", + "name": "ClickHouse Driver", + "version": "1.0.0", + "summary": "ClickHouse OLAP database driver via HTTP interface", + "author": { + "name": "TablePro", + "url": "https://tablepro.app" + }, + "homepage": "https://tablepro.app/databases/clickhouse", + "category": "database-driver", + "databaseTypeIds": ["ClickHouse"], + "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-clickhouse-v1.0.0/ClickHouseDriver-arm64.zip", + "sha256": "", + "binaries": [ + { "architecture": "arm64", "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-clickhouse-v1.0.0/ClickHouseDriver-arm64.zip", "sha256": "" }, + { "architecture": "x86_64", "downloadURL": "https://github.com/datlechin/TablePro/releases/download/plugin-clickhouse-v1.0.0/ClickHouseDriver-x86_64.zip", "sha256": "" } + ], + "minAppVersion": "0.17.0", + "minPluginKitVersion": 1, + "iconName": "chart.bar.xaxis", + "isVerified": true +} +``` + +将 `` 替换为 `build-plugin.sh` 输出的实际 SHA-256 值。`binaries` 数组提供按架构区分的下载;`downloadURL`/`sha256` 平级字段指向 arm64 作为旧版应用的后备。 + +## databaseTypeIds 映射 + +`databaseTypeIds` 字段将注册表条目映射到 `DatabaseType.pluginTypeId` 值。应用通过此映射确定在用户选择没有已加载驱动的数据库类型时,应安装哪个注册表插件。 + +| DatabaseType | pluginTypeId | +|-------------|-------------| +| MySQL, MariaDB | `"MySQL"` | +| PostgreSQL, Redshift | `"PostgreSQL"` | +| SQLite | `"SQLite"` | +| MongoDB | `"MongoDB"` | +| Redis | `"Redis"` | +| SQL Server | `"SQL Server"` | +| Oracle | `"Oracle"` | +| ClickHouse | `"ClickHouse"` | + +## 发布插件版本 + +1. 给提交打标签:`git tag plugin-oracle-v1.0.0 && git push --tags` +2. `build-plugin.yml` CI 工作流构建双架构版本(arm64 + x86_64),签名,创建包含 ZIP 产物的 GitHub Release,并自动更新插件注册表的 `binaries` 数组 +3. 应用在下次访问 **Browse** 时获取更新后的清单(使用 ETag 缓存) + +## 自动安装流程 + +当用户选择可下载的数据库类型(Oracle 或 ClickHouse)时: + +1. `DatabaseType.isDownloadablePlugin` 返回 `true` +2. `PluginManager.isDriverAvailable(for:)` 返回 `false`(没有已加载的驱动) +3. 连接表单显示下载标记并触发 `installPluginForType` +4. `PluginManager.installMissingPlugin(for:)` 获取注册表,通过匹配 `databaseTypeIds` 找到对应插件,并调用 `installFromRegistry` +5. 下载 ZIP 文件,验证 SHA-256,解压,验证代码签名,然后加载 diff --git a/docs/zh/development/setup.mdx b/docs/zh/development/setup.mdx new file mode 100644 index 00000000..d6540323 --- /dev/null +++ b/docs/zh/development/setup.mdx @@ -0,0 +1,333 @@ +--- +title: 开发环境搭建 +description: 克隆、构建和本地运行 TablePro,使用 Xcode 15+、SwiftLint 和 SwiftFormat +--- + +# 开发环境搭建 + +## 前置要求 + +### 必需软件 + +| 软件 | 版本 | 用途 | +|----------|---------|---------| +| **macOS** | 14.0+(Sonoma) | 目标平台 | +| **Xcode** | 15.0+ | 开发 IDE | +| **Git** | 最新版 | 版本控制 | + +### 可选工具 + +| 工具 | 用途 | +|------|---------| +| **SwiftLint** | 代码检查 | +| **SwiftFormat** | 代码格式化 | +| **Homebrew** | 包管理器 | +| **Git LFS** | 从 `Libs/` 拉取预编译的原生库 | + +## 开始 + +### 步骤 1:克隆和初始化 + +```bash +git clone https://github.com/datlechin/tablepro.git +cd tablepro + +# 拉取原生库(存储在 Git LFS 中) +brew install git-lfs +git lfs install +git lfs pull + +# 创建必需的构建配置文件(开发时留空即可) +touch Secrets.xcconfig + +# 安装代码检查/格式化工具 +brew install swiftlint swiftformat +``` + + +跳过 `git lfs pull` 会导致 `Libs/` 目录下只有指针文件而非实际的二进制文件,从而引发链接器错误。 + + +### 步骤 2:在 Xcode 中打开 + +```bash +open TablePro.xcodeproj +``` + +### 步骤 3:构建并运行 + +1. 选择 **TablePro** scheme +2. 选择 **My Mac** 作为目标设备 +3. 按 `Cmd+R` 构建并运行 + +{/* Screenshot: Xcode with scheme selected */} + + Xcode 设置 + Xcode 设置 + + +## 项目结构 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## 构建 + +### 开发构建 + +```bash +# 为当前架构构建(Debug) +xcodebuild -project TablePro.xcodeproj -scheme TablePro -configuration Debug build -skipPackagePluginValidation + +# 或在 Xcode 中:Cmd+B +``` + +### 发布构建 + +```bash +# Apple Silicon +scripts/build-release.sh arm64 + +# Intel +scripts/build-release.sh x86_64 + +# 双架构 +scripts/build-release.sh both +``` + +详见[构建](/zh/development/building)。 + +## 运行测试 + +```bash +# 所有测试 +xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation + +# 指定测试类 +xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation \ + -only-testing:TableProTests/TestClassName + +# 指定测试方法 +xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation \ + -only-testing:TableProTests/TestClassName/testMethodName +``` + +或在 Xcode 中:**Product** > **Test**(`Cmd+U`)。 + +## 代码质量 + +### SwiftLint + +```bash +# 检查问题 +swiftlint lint + +# 自动修复可修复的问题 +swiftlint --fix +``` + +SwiftLint 也会在 Xcode 构建时自动运行。 + +### SwiftFormat + +```bash +# 格式化所有代码 +swiftformat . + +# 仅检查不应用更改 +swiftformat --lint . +``` + + +提交前运行 SwiftFormat 以保持代码风格一致。 + + +## 配置文件 + +### .swiftlint.yml + +SwiftLint 规则和配置: + +- 行长度限制 +- 函数复杂度限制 +- 禁用的规则 +- 自定义规则 + +### .swiftformat + +SwiftFormat 选项: + +- 缩进风格 +- 花括号位置 +- import 排序 +- 其他格式化规则 + +## 开发工作流 + +### 修改代码 + +1. 创建功能分支: + ```bash + git checkout -b feature/my-feature + ``` + +2. 进行修改 + +3. 运行代码检查: + ```bash + swiftlint lint + swiftformat --lint . + ``` + +4. 运行测试: + ```bash + xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation + ``` + +5. 提交: + ```bash + git add . + git commit -m "Add my feature" + ``` + +6. 推送并创建 Pull Request: + ```bash + git push origin feature/my-feature + ``` + +### 调试 + +1. 点击行号设置断点 +2. 在调试控制台中使用 `po` 打印对象 +3. 使用变量视图检查状态 +4. 使用 Console.app 查看系统日志 + +### 日志 + +TablePro 使用 OSLog: + +```swift +import os + +private static let logger = Logger(subsystem: "com.TablePro", category: "ComponentName") + +// 用法 +logger.debug("Connection established") +logger.info("Query executed in \(duration)s") +logger.error("Failed to connect: \(error.localizedDescription)") +``` + +## 常见任务 + +### 添加新视图 + +1. 在对应的 `Views/` 子文件夹中创建 SwiftUI 视图 +2. 遵循现有命名规范(`FeatureNameView.swift`) +3. 使用 `@Observable` 或 `@StateObject` 管理状态 +4. 根据需要添加到导航/路由中 + +### 添加数据库功能 + +1. 在 `Plugins/` 下创建新的插件 bundle,或修改现有驱动插件 +2. 实现 `PluginDatabaseDriver` 协议方法 +3. 如需桥接新协议方法,更新 `PluginDriverAdapter` +4. 在相关视图组件中添加 UI +5. 添加测试 + +### 修改设置 + +1. 在 `AppSettings.swift` 的相应设置结构体中添加 +2. 更新 `SettingsView` 以显示该设置 +3. 通过 `@AppStorage` 或设置管理器在应用中使用该设置 + +## 故障排除 + +### 构建失败 + +1. 清理构建文件夹:`Cmd+Shift+K` +2. 删除 Derived Data: + ```bash + rm -rf ~/Library/Developer/Xcode/DerivedData + ``` +3. 关闭并重新打开 Xcode +4. 检查 Xcode 更新 + +### SwiftLint 错误 + +1. 阅读错误信息 +2. 检查 `.swiftlint.yml` 中的规则配置 +3. 修复问题或在适当时禁用规则 +4. 运行 `swiftlint --fix` 自动修复 + +### 缺少库文件或 Secrets.xcconfig + +在仓库根目录运行 `git lfs pull` 和 `touch Secrets.xcconfig`。参见[步骤 1](#步骤-1克隆和初始化)。 + +## 下一步 + + + + 了解代码库结构 + + + 遵循编码规范 + + + 构建发布版本 + + + 查看源代码 + + diff --git a/docs/zh/features/ai-chat.mdx b/docs/zh/features/ai-chat.mdx new file mode 100644 index 00000000..6c00946e --- /dev/null +++ b/docs/zh/features/ai-chat.mdx @@ -0,0 +1,355 @@ +--- +title: AI 聊天 +description: 内置 AI 聊天面板,支持 Claude、OpenAI、Gemini、OpenRouter、Ollama 及自定义端点 +--- + +# AI 聊天 + +TablePro 内置 AI 聊天面板,用于编写、解释和修复 SQL 查询。支持 Claude (Anthropic)、OpenAI、Gemini (Google)、OpenRouter、Ollama 以及自定义的 OpenAI 兼容端点。 + +## 打开 AI 聊天面板 + +| 方式 | 操作 | +|------|------| +| 键盘快捷键 | `Cmd+Shift+L` | +| 工具栏 | 点击 AI 按钮(星火图标) | +| 菜单 | **View** > **Toggle AI Chat** | + +面板出现在编辑器右侧,紧邻数据检查器。 + + + AI 聊天面板 + AI 聊天面板 + + +## 与 AI 对话 + +1. 在底部输入框中输入问题 +2. 按 **Enter** 或点击发送 +3. AI 会根据当前数据库连接的上下文给出建议 + +AI 自动接收以下信息: +- 数据库类型(MySQL、PostgreSQL、SQLite) +- 数据库 schema(表、列、类型、外键) +- 编辑器中的当前查询(启用时) + + +AI 会生成匹配你特定数据库方言的 SQL,使用正确的标识符引号和语法。 + + +### Markdown 响应 + +AI 响应支持完整的 Markdown 渲染: +- **格式化文本** — 标题、粗体、斜体、列表 +- **SQL 代码块** — 带语法高亮和操作按钮 +- **行内代码** — 用于表名、列名和 SQL 关键字 + +## 代码块 + +AI 响应中的 SQL 代码块有两个操作按钮: + +- **Copy** — 将 SQL 复制到剪贴板 +- **Insert to Editor** — 将 SQL 插入到活跃的编辑器标签页中 + + + 带代码块操作按钮的 AI 响应 + 带代码块操作按钮的 AI 响应 + + +## Token 用量 + +每次响应后,助手消息下方显示 token 计数: + +- **输入 token** — 发送给 AI 的 token 数(你的消息 + 上下文) +- **输出 token** — AI 生成的 token 数 + +用于跟踪每条消息的 API 使用量和费用。 + + + Token 用量显示 + Token 用量显示 + + +## 对话历史 + +对话自动保存到磁盘并在重新启动时恢复。在聊天面板头部管理对话: + +| 按钮 | 操作 | +|------|------| +| **History**(时钟图标) | 浏览和切换历史对话 | +| **New Chat**(铅笔图标) | 开始新对话 | +| **Clear**(删除图标) | 删除当前对话 | + +对话以 JSON 文件形式存储在 `~/Library/Application Support/TablePro/ai_chats/`。 + + +对话会根据你发送的第一条消息自动命名,方便日后查找。 + + + + 对话历史 + 对话历史 + + +## 重试与重新生成 + +- **重试** — 如果生成失败(网络错误、频率限制等),最后一条用户消息下方会出现"Retry"按钮。点击重新发送相同请求。 +- **重新生成** — 成功响应后,助手消息下方出现"Regenerate"按钮。点击后丢弃当前响应并生成新的。 + +## 流式响应 + +响应以实时流式方式呈现: +- 等待第一个 token 时显示三点打字指示器 +- 随时点击 **Stop** 取消 +- 可向上滚动阅读之前的消息而不会被强制拉回底部。仅当你已在查看最新内容时才自动滚动。 +- 在查看旧消息时也可以开始新对话 + + + 流式响应 + 流式响应 + + +## 支持的 AI 服务商 + +六种服务商类型: + +| 服务商 | 端点 | 需要 API Key | +|--------|------|-------------| +| **Claude** (Anthropic) | `https://api.anthropic.com` | 是 | +| **OpenAI** | `https://api.openai.com` | 是 | +| **OpenRouter** | `https://openrouter.ai/api` | 是 | +| **Gemini** (Google) | `https://generativelanguage.googleapis.com` | 是 | +| **Ollama** | `http://localhost:11434` | 否 | +| **自定义** | 任何 OpenAI 兼容端点 | 可选 | + + +**Ollama 自动检测**:如果 TablePro 启动时 Ollama 正在本地运行,它会自动注册为 AI 服务商并使用第一个可用模型。无需手动设置。 + + + +你可以同时配置多个服务商,并将不同的 AI 功能路由到不同的服务商。 + + +## 配置 AI 服务商 + +在 **Settings**(`Cmd+,`)> **AI** 中设置服务商: + +### 添加服务商 + +1. 在 Providers 部分点击 **Add Provider** +2. 选择服务商类型(Claude、OpenAI、Gemini、OpenRouter、Ollama 或自定义) +3. 输入 API key(端点根据服务商类型自动填充) +4. 指定模型名称,或点击 **Fetch** 从服务商获取可用模型。更改服务商设置时模型会自动获取。 +5. 点击 **Test** 验证连接 + + + AI 设置 - 服务商配置 + AI 设置 - 服务商配置 + + +### API Key 安全 + +API key 存储在 macOS 钥匙串中,不会接触纯文本文件或偏好设置。 + +### 功能路由 + +将特定 AI 功能路由到不同的服务商: + +| 功能 | 说明 | +|------|------| +| **聊天** | 通用 AI 聊天对话 | +| **解释查询** | 查询解释请求 | +| **优化查询** | 查询性能优化建议 | +| **修复错误** | 错误诊断和修复建议 | +| **行内建议** | 行内代码建议 | + +每个功能可以指定特定服务商,或回退到默认服务商(第一个启用的服务商)。 + + + 功能路由配置 + 功能路由配置 + + +## 上下文设置 + +控制发送给 AI 的数据库上下文: + +| 设置 | 默认值 | 说明 | +|------|--------|------| +| **包含数据库 schema** | 开 | 发送表和列定义 | +| **包含当前查询** | 开 | 发送活跃编辑器标签页中的查询 | +| **包含查询结果** | 关 | 发送最近的查询结果 | +| **最大 schema 表数** | 20 | 上下文中包含的最大表数 | + + + 上下文设置 + 上下文设置 + + + +更多上下文意味着更好的 AI 回答,但也意味着更多数据发送给服务商。在启用 schema 和查询共享前,请查看服务商的隐私政策。 + + +## 按连接设置 AI 策略 + +在连接表单中为每个连接控制 AI 访问权限: + +| 策略 | 说明 | +|------|------| +| **使用默认** | 遵循 AI 设置中的全局默认策略 | +| **始终允许** | 此连接始终可用 AI 功能 | +| **每次询问** | 发送数据给 AI 前提示确认 | +| **禁止** | 此连接完全禁用 AI 功能 | + +适合锁定生产数据库连接上的 AI 访问。 + + + 按连接的 AI 策略 + 按连接的 AI 策略 + + +## 编辑器集成 + +### 右键菜单 + +在编辑器中右键点击选中的 SQL 可访问 AI 功能: + +- **Explain with AI** — 将选中的 SQL 发送给 AI 解释 +- **Optimize with AI** — 请求 AI 提供性能优化建议 + + + SQL 编辑器右键菜单中的 AI 选项 + SQL 编辑器右键菜单中的 AI 选项 + + +### 键盘快捷键 + +| 操作 | 快捷键 | 说明 | +|------|--------|------| +| 切换 AI 聊天 | `Cmd+Shift+L` | 打开或关闭 AI 聊天面板 | +| AI 解释 | `Cmd+L` | 解释选中的 SQL(或当前查询) | +| AI 优化 | `Cmd+Option+L` | 优化选中的 SQL(或当前查询) | + +所有 AI 快捷键可在 **Settings** > **Keyboard** 的 **AI** 分类中自定义。 + + +未选中文本时,`Cmd+L` 和 `Cmd+Option+L` 使用活跃编辑器标签页中的完整查询。 + + +### 让 AI 修复错误 + +查询失败时,错误对话框中包含 **Ask AI to Fix** 按钮: + +1. 打开 AI 聊天面板(如果尚未打开) +2. 将失败的查询和错误信息发送给 AI +3. AI 分析错误并给出修正后的查询 + + + 带 Ask AI to Fix 按钮的查询错误对话框 + 带 Ask AI to Fix 按钮的查询错误对话框 + + +## 相关页面 + + + + 编写和执行 SQL 查询 + + + 配置所有 TablePro 设置 + + + 所有键盘快捷键 + + + 浏览历史查询 + + diff --git a/docs/zh/features/autocomplete.mdx b/docs/zh/features/autocomplete.mdx new file mode 100644 index 00000000..d371a61d --- /dev/null +++ b/docs/zh/features/autocomplete.mdx @@ -0,0 +1,432 @@ +--- +title: 自动补全 +description: 感知 Schema 的 SQL 自动补全,支持别名解析、50ms 防抖,适用于 500KB+ 文件 +--- + +# SQL 自动补全 + +自动补全会分析光标位置、SQL 语法上下文、引用的表和别名以及数据库 schema,在查询的每个位置只提供相关的补全建议。 + +{/* Screenshot: Autocomplete popup showing mixed suggestions */} + + 自动补全 + 自动补全 + + +## 自动补全的工作原理 + +自动补全引擎分析四个要素: + +1. **光标的当前位置** +2. **SQL 语法上下文**(SELECT、FROM、WHERE 等) +3. **引用的表**及其别名 +4. **数据库 schema**(表、列、函数) + +建议结果会过滤为光标处有意义的内容。 + +## 触发自动补全 + +### 自动触发 + +输入时自动补全会自动出现: + +- 输入 1-2 个字符后 +- 输入 `.`(点号)访问列时 +- 在特定关键字后(SELECT、FROM、JOIN 等) + +### 手动触发 + +手动呼出自动补全弹窗: + +- 开始输入并稍等片刻 +- 弹窗会显示相关建议 + +### 关闭 + +- 按 `Escape` 关闭弹窗 +- 继续输入以筛选建议 +- 点击弹窗外部 + +## 补全类型 + +### SQL 关键字 + +关键字根据 SQL 语法上下文建议: + +```sql +SEL| -- 建议:SELECT +FROM users WH| -- 建议:WHERE +SELECT * FROM users WHERE name LIKE '%test%' ORD| -- 建议:ORDER +``` + +{/* Screenshot: Keyword suggestions */} + + 关键字建议 + 关键字建议 + + +**建议的关键字包括**: + +| 分类 | 关键字 | +|------|--------| +| 语句 | SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP | +| 子句 | FROM、WHERE、JOIN、ON、GROUP BY、ORDER BY、HAVING、LIMIT | +| 运算符 | AND、OR、NOT、IN、LIKE、BETWEEN、IS NULL、EXISTS | +| 连接 | INNER JOIN、LEFT JOIN、RIGHT JOIN、CROSS JOIN | + +### 表名 + +在需要表引用的关键字后建议表名: + +```sql +SELECT * FROM | -- 建议所有表 +SELECT * FROM us| -- 建议以 "us" 开头的表:users、user_roles +SELECT * FROM users JOIN | -- 建议所有表 +``` + +{/* Screenshot: Table name suggestions */} + + 表名建议 + 表名建议 + + +### 列名 + +根据引用的表建议列名: + +```sql +SELECT | FROM users -- 建议 users 表的列 +SELECT u.| FROM users u -- 建议带 "u." 前缀的列 +SELECT * FROM users WHERE | -- 建议 users 表的列 +``` + +#### 表别名之后 + +输入别名加 `.` 后显示该表的列: + +```sql +SELECT + u.| -- 显示:id、name、email、created_at(来自 users) +FROM users u +JOIN orders o ON u.id = o.| -- 显示:id、user_id、total(来自 orders) +``` + +{/* Screenshot: Column suggestions after alias */} + + 别名建议 + 别名建议 + + +### 函数 + +在适当的上下文中建议 SQL 函数: + +```sql +SELECT | -- 建议:COUNT、SUM、AVG、MAX、MIN 等 +SELECT COUNT(| -- 建议列和 * +WHERE date_column > | -- 建议:NOW()、CURRENT_DATE 等 +``` + +**常见函数建议**: + +| 分类 | 函数 | +|------|------| +| 聚合 | COUNT、SUM、AVG、MAX、MIN | +| 字符串 | CONCAT、SUBSTRING、UPPER、LOWER、TRIM | +| 日期 | NOW、CURRENT_DATE、DATE_FORMAT、DATEADD | +| 数学 | ROUND、ABS、CEIL、FLOOR | +| 条件 | COALESCE、NULLIF、CASE、IF | + +{/* Screenshot: SQL function suggestions */} + + SQL 函数建议 + SQL 函数建议 + + +### Schema 名 + +对于有多个 schema 的数据库(PostgreSQL): + +```sql +SELECT * FROM | -- 建议:public、schema1、schema2 +SELECT * FROM public.| -- 建议 public schema 中的表 +``` + +## 上下文感知建议 + +### SELECT 之后 + +紧跟 SELECT 之后: + +- FROM 子句中表的列名 +- `*` 表示所有列 +- `DISTINCT` 修饰符 +- 聚合函数 + +```sql +SELECT | +-- 建议:*、DISTINCT、列名、函数 +``` + +### FROM/JOIN 之后 + +在 FROM 或 JOIN 关键字之后: + +- 所有可访问的表名 +- 带 schema 限定的名称(schema.table) + +### WHERE 之后 + +在 WHERE 子句中: + +- 已选表的列名 +- 比较运算符 +- 逻辑运算符(AND、OR) + +### ON 之后(JOIN 条件) + +在 JOIN ON 子句中: + +- 两个连接表的列 +- 常用于外键关系 + +```sql +SELECT * FROM users u +JOIN orders o ON | +-- 建议:u.id、o.user_id 等 +``` + +{/* Screenshot: Column suggestions in JOIN ON clause */} + + JOIN ON 子句中的列建议 + JOIN ON 子句中的列建议 + + +### GROUP BY 之后 + +- SELECT 子句中出现的列 +- 非聚合的列名 + +### ORDER BY 之后 + +- 列名 +- SELECT 中定义的别名 +- ASC/DESC 关键字 + +## 使用补全 + +### 键盘导航 + +| 按键 | 操作 | +|------|------| +| `Down` 方向键 | 选择下一个建议 | +| `Up` 方向键 | 选择上一个建议 | +| `Enter` | 接受选中的建议 | +| `Tab` | 接受选中的建议 | +| `Escape` | 关闭弹窗 | + +### 筛选 + +继续输入以筛选建议: + +```sql +SELECT * FROM user| +-- 显示:users、user_roles、user_preferences +-- 输入更多字符可缩小范围 +``` + +### 接受建议 + +接受建议后: + +1. 建议文本插入到光标位置 +2. 已输入的前缀被替换 +3. 光标移到插入文本的末尾 + +## Schema 缓存 + +### Schema 加载方式 + +连接时,TablePro 会: + +1. 获取所有表名 +2. 加载每张表的列信息 +3. 缓存这些信息以加速自动补全 + +### 刷新 Schema + +如果你进行了 schema 变更(添加表、修改列): + +1. 右键点击侧边栏中的连接 +2. 选择 **Refresh** + +或者断开连接后重新连接。 + + +在 TablePro 中进行的 schema 变更(通过结构标签页)会自动反映到自动补全中。 + + +## 性能 + +### 大文件 + +自动补全适用于任意大小的 SQL 文件,包括数 MB 的转储文件。对于大于 500 KB 的文件,引擎会提取光标附近约 10 KB 的窗口,仅分析就近的语句。无论文件总大小如何,建议都能即时呈现。 + +### 大型 Schema + +对于有 100+ 张表的数据库: + +- 初始 schema 加载可能需要一点时间 +- 缓存完成后自动补全保持响应 +- 输入更多字符可更快缩小建议范围 + +### 提升性能的建议 + +1. **输入更多字符**:更快缩小建议范围 +2. **使用表别名**:减少查找范围 +3. **等待缓存完成**:首次加载后 schema 会被缓存 + +## 局限性 + +### 不会建议的内容 + +- 临时表(不在 schema 中) +- 子查询别名 +- 动态列名 +- 来自其他连接的列 + +### 查询复杂度 + +非常复杂的查询上下文感知能力有限: + +- 深度嵌套的子查询 +- 复杂的 CTE +- 动态 SQL + +这些情况下基本的关键字和表名建议仍然有效。 + +## 配置 + +自动补全默认开启,无需配置。补全触发器应用了 50ms 的防抖,以减少不必要的计算。 + +## 最佳实践 + +### 使用表别名 + +别名让自动补全更精准: + +```sql +-- Good: Clear which table each column comes from +SELECT u.name, o.total +FROM users u +JOIN orders o ON u.id = o.user_id + +-- Less clear without aliases +SELECT users.name, orders.total +FROM users +JOIN orders ON users.id = orders.user_id +``` + +### 先写 FROM + +先写 FROM 可以为自动补全提供表的上下文: + +```sql +-- This approach helps autocomplete +FROM users u +JOIN orders o ON u.id = o.user_id +SELECT u.| -- Now knows about u and o tables +``` + +### 让建议引导你 + +如果你不确定确切的列名: + +1. 输入表别名加点号:`u.` +2. 浏览建议列表 +3. 选择正确的列 + +## 故障排除 + +### 建议不出现 + +1. **检查连接**:确保已连接到数据库 +2. **刷新 schema**:右键点击连接 > Refresh +3. **等待缓存**:大型 schema 可能需要时间加载 + +### 建议不正确 + +1. **检查表别名**:确保别名定义正确 +2. **检查 FROM 子句**:必须引用了表才能建议列 +3. **schema 变更后刷新**:schema 变更需要刷新 + +### 建议速度慢 + +1. **输入更多字符**:缩小搜索范围 +2. **使用别名**:限制列搜索范围 +3. **检查数据库连接**:网络延迟会影响 schema 加载 + +## 下一步 + + + + 配合自动补全编写查询 + + + 查看查询结果 + + + 探索你的 schema + + + 提升工作效率 + + diff --git a/docs/zh/features/change-tracking.mdx b/docs/zh/features/change-tracking.mdx new file mode 100644 index 00000000..63b317ef --- /dev/null +++ b/docs/zh/features/change-tracking.mdx @@ -0,0 +1,489 @@ +--- +title: 变更追踪 +description: 在本地队列中暂存单元格编辑、行插入和删除操作,提交前不会写入数据库 +--- + +# 变更追踪 + +TablePro 中的更改会暂存在内存中,不会立即应用。你可以编辑单元格、插入行、删除行,然后在提交前统一审查。在你明确确认之前,数据库不会发生任何变动。 + +{/* Screenshot: Data grid with pending changes highlighted */} + + 变更追踪 + 变更追踪 + + +## 概述 + +对数据或表结构的编辑会在本地排队并在网格中高亮显示。你可以一次性提交所有更改或整体丢弃。这样可以避免意外的数据丢失,让你完全掌控何时将修改提交到数据库。 + + +变更追踪按标签页独立。每个标签页有自己独立的待提交更改集,切换标签页时不会丢失你的编辑。 + + +## 数据变更 + +TablePro 追踪三种数据变更:单元格编辑(更新)、行插入和行删除。所有查找都是 O(1) 的哈希结构,即使有大量待提交更改也能保持快速。 + +### 编辑单元格 + +要编辑现有单元格: + +1. 双击单元格 +2. 输入新值 +3. 按 `Enter` 确认或 `Escape` 取消 + +已修改的单元格在数据网格中高亮显示。 + +{/* Screenshot: Modified cell highlighted in the data grid */} + + 已修改的单元格 + 已修改的单元格 + + + +如果你将值改回原始值,更改会自动从队列中移除。TablePro 能检测到互相抵消的编辑。 + + +### 新增行 + +要插入新行: + +1. 点击工具栏中的 **+** 按钮或使用键盘快捷键 +2. 数据网格底部出现一行新行,标有插入指示器 +3. 为每列填入值 +4. 有默认值的列会预填 `DEFAULT` + +新行与更新分开追踪。对新插入行中单元格的编辑会合并到插入记录中,而非创建单独的更新记录。 + +{/* Screenshot: Newly added row with insertion indicator */} + + 带插入指示器的新增行 + 带插入指示器的新增行 + + +### 删除行 + +要删除行: + +1. 在数据网格中选择一行或多行 +2. 按 `Delete` 键或点击删除按钮 +3. 已删除的行会标有删除线指示器 + +已删除的行在提交或丢弃之前仍可见,以便你需要时撤销删除。 + +{/* Screenshot: Deleted row with deletion indicator */} + + 带删除指示器的已删除行 + 带删除指示器的已删除行 + + + +批量删除多行被记录为单个撤销操作。撤销批量删除会一次恢复所有行。 + + +## 提交与丢弃 + +暂存更改后,你可以提交到数据库或全部丢弃。 + +### 提交更改 + +要应用所有待提交的更改: + +1. 点击工具栏中的 **Commit** 按钮,或按 `Cmd+S` +2. TablePro 为所有排队的更改生成参数化 SQL 语句 +3. 语句在数据库上执行 +4. 成功后,更改队列清空并刷新网格 + +提交生成的 SQL: + +| 变更类型 | 生成的 SQL | +|----------|-----------| +| 单元格编辑 | `UPDATE ... SET column = ? WHERE pk = ?` | +| 行插入 | `INSERT INTO ... (columns) VALUES (?)` | +| 行删除 | `DELETE FROM ... WHERE pk = ?` | + + +UPDATE 语句需要表上有主键。如果没有定义主键,尝试提交更新时 TablePro 会报错。DELETE 语句可以通过匹配所有列值在没有主键的情况下工作。 + + +### 丢弃更改 + +要撤销所有待提交的更改: + +1. 点击工具栏中的 **Discard** 按钮 +2. 所有排队的更改被移除 +3. 已修改的单元格恢复原始值 +4. 已插入的行从网格中移除 +5. 已删除的行取消标记 + +丢弃操作还会清除当前标签页的撤销/重做栈。 + +### 预览数据 SQL + +提交前预览将要执行的确切 SQL 语句: + +1. 在网格中进行数据更改(编辑单元格、插入/删除行) +2. 点击工具栏中的 **Preview SQL** 按钮(眼睛图标),或按 `Cmd+Shift+P` +3. 弹出窗口显示所有待提交的 SQL,带有语法高亮 +4. 使用 **Copy All** 将 SQL 复制到剪贴板 + +{/* Screenshot: SQL Preview popover showing pending statements */} + + +预览显示的是实际 SQL,参数值已内联,让你可以准确验证将要执行的内容。破坏性操作(DROP、TRUNCATE、DELETE)会用警告横幅标记。 + + +{/* Screenshot: Commit and Discard buttons with pending changes count */} + + 带待提交更改计数的提交和丢弃按钮 + 带待提交更改计数的提交和丢弃按钮 + + +## 撤销与重做 + +完整的撤销/重做栈用于数据编辑。可以在提交前前后回溯更改。 + +### 工作原理 + +每个数据更改都会推入撤销栈: + +- **单元格编辑**:存储先前值和新值 +- **行插入**:存储行索引 +- **行删除**:存储行索引和原始行数据 +- **批量删除**:将所有受影响的行存储为单个操作 + +撤销将操作移到重做栈。重做将其移回。 + +### 使用撤销与重做 + +| 操作 | 快捷键 | +|------|--------| +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | + + +撤销和重做具有上下文感知能力。当 SQL 编辑器获得焦点时,`Cmd+Z` 撤销文本编辑;当数据网格获得焦点时,撤销数据更改。 + + +### 栈行为 + +- 撤销/重做栈按标签页维护 +- 提交或丢弃更改会清除两个栈 +- 撤销后进行新更改会清除重做栈(标准撤销行为) + +## Schema 变更 + +TablePro 也使用相同的队列方式追踪表结构(列、索引和外键)的变更。 + +### 追踪的 Schema 操作 + +| 操作 | 追踪内容 | +|------|----------| +| **添加列** | 新列定义(名称、类型、可空、默认值等) | +| **修改列** | 旧的和新的列定义 | +| **删除列** | 标记为待删除的列 | +| **添加索引** | 新索引定义(名称、列、类型、唯一性) | +| **修改索引** | 旧的和新的索引定义 | +| **删除索引** | 标记为待删除的索引 | +| **添加外键** | 新外键定义(列、引用、操作) | +| **修改外键** | 旧的和新的外键定义 | +| **删除外键** | 标记为待删除的外键 | +| **修改主键** | 旧的和新的主键列 | + +### 视觉指示器 + +在结构标签页中,待提交的更改会通过视觉指示器展示: + +- **新增项**(列、索引、外键)以插入颜色高亮 +- **已修改项**显示哪些字段发生了更改 +- **已删除项**标有删除指示器 + +{/* Screenshot: Schema changes highlighted in Structure tab */} + + 结构标签页中高亮的 Schema 变更 + 结构标签页中高亮的 Schema 变更 + + +### Schema 撤销与重做 + +Schema 变更有自己独立的撤销/重做栈,与数据变更分开: + +- 最多 100 级撤销 +- 新操作清除重做栈 +- 支持所有 schema 操作类型 + +### 预览 Schema SQL + +应用 schema 变更前预览生成的 SQL: + + + + 在结构标签页中添加、修改或删除列、索引或外键 + + + 点击 Commit 按钮或按 `Cmd+S` + + + 预览面板显示所有将要执行的 ALTER TABLE 语句 + + + 点击 **Apply Changes** 执行,或 **Cancel** 返回调整 + + + +{/* Screenshot: Schema preview sheet showing ALTER TABLE statements */} + + Schema 预览 + Schema 预览 + + + +使用预览面板中每条语句旁的复制按钮复制单条 SQL 语句。 + + +## SQL 生成 + +TablePro 为数据和 schema 变更生成数据库专用的 SQL。 + +### 数据 SQL(`SQLStatementGenerator`) + +数据变更生成参数化语句以防止 SQL 注入: + + + + ```sql + -- UPDATE with LIMIT 1 for safety + UPDATE `users` SET `name` = ? WHERE `id` = ? LIMIT 1 + + -- INSERT + INSERT INTO `users` (`name`, `email`) VALUES (?, ?) + + -- DELETE (with PK) + DELETE FROM `users` WHERE `id` = ? OR `id` = ? + + -- DELETE (without PK, matches all columns) + DELETE FROM `users` WHERE `name` = ? AND `email` = ? LIMIT 1 + ``` + + + ```sql + -- UPDATE with positional parameters + UPDATE "users" SET "name" = $1 WHERE "id" = $2 + + -- INSERT + INSERT INTO "users" ("name", "email") VALUES ($1, $2) + + -- DELETE (with PK) + DELETE FROM "users" WHERE "id" = $1 OR "id" = $2 + ``` + + + ```sql + -- UPDATE + UPDATE "users" SET "name" = ? WHERE "id" = ? + + -- INSERT + INSERT INTO "users" ("name", "email") VALUES (?, ?) + + -- DELETE + DELETE FROM "users" WHERE "id" = ? OR "id" = ? + ``` + + + +### Schema SQL(`SchemaStatementGenerator`) + +Schema 变更生成带数据库专用语法的 ALTER TABLE 语句: + + + + ```sql + -- Add column + ALTER TABLE `users` ADD COLUMN `phone` VARCHAR(20) NOT NULL + + -- Modify column + ALTER TABLE `users` MODIFY COLUMN `name` VARCHAR(200) NOT NULL + + -- Drop column + ALTER TABLE `users` DROP COLUMN `phone` + + -- Add index + CREATE INDEX `idx_email` ON `users` (`email`) USING BTREE + + -- Drop foreign key + ALTER TABLE `orders` DROP FOREIGN KEY `fk_orders_user` + ``` + + + ```sql + -- Add column + ALTER TABLE "users" ADD COLUMN "phone" VARCHAR(20) NOT NULL + + -- Modify column (multiple statements) + ALTER TABLE "users" RENAME COLUMN "name" TO "full_name"; + ALTER TABLE "users" ALTER COLUMN "full_name" TYPE VARCHAR(200); + ALTER TABLE "users" ALTER COLUMN "full_name" SET NOT NULL + + -- Drop column + ALTER TABLE "users" DROP COLUMN "phone" + + -- Add index + CREATE INDEX "idx_email" ON "users" ("email") + + -- Drop constraint + ALTER TABLE "orders" DROP CONSTRAINT "fk_orders_user" + ``` + + + ```sql + -- Add column + ALTER TABLE "users" ADD COLUMN "phone" TEXT + + -- Drop column + ALTER TABLE "users" DROP COLUMN "phone" + + -- Add index + CREATE INDEX "idx_email" ON "users" ("email") + ``` + + + SQLite 的 ALTER TABLE 支持有限。修改列和删除外键需要重建表,可视化编辑器目前不支持此操作。请使用 SQL 编辑器完成这些操作。 + + + + +### SQL 函数支持 + +编辑单元格时,TablePro 识别常见的 SQL 函数并将其作为字面量而非引号字符串插入: + +| 函数 | 数据库 | +|------|--------| +| `NOW()` | MySQL、MariaDB | +| `CURRENT_TIMESTAMP` | 所有 | +| `CURDATE()` | MySQL、MariaDB | +| `CURRENT_DATE` | 所有 | +| `SYSDATE()` | MySQL | +| `UTC_TIMESTAMP()` | MySQL、MariaDB | + +### 依赖排序 + +Schema 变更在执行前会按依赖顺序自动排序: + +1. 删除外键(必须先执行以避免约束冲突) +2. 删除索引 +3. 删除/修改列 +4. 添加列 +5. 修改主键 +6. 添加索引 +7. 添加外键 + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 提交更改 | `Cmd+S` | +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | +| 删除选中行 | `Delete` 或 `Cmd+Delete` | +| 编辑单元格 | `Enter` 或双击 | +| 取消编辑 | `Escape` | + +## 最佳实践 + +### 提交前审查 + +提交前检查待提交的更改。数据网格中的视觉指示器可以帮你快速发现意外的编辑。 + +### 充分利用撤销 + +提交后撤销栈会清除,所以在编辑期间尽管使用撤销。工作中随时撤销和重做没有任何代价。 + +### 频繁提交 + +避免积累过多更改后再提交。更小、更频繁的提交更容易验证,出问题时风险也更低。 + +### 预览 Schema 变更 + +修改表结构时务必使用 SQL 预览。这可以在执行前显示确切的 ALTER TABLE 语句。 + +### 破坏性更改前备份 + +删除列或进行其他破坏性 schema 变更前,先备份你的表: + +```sql +CREATE TABLE users_backup AS SELECT * FROM users; +``` + +## 下一步 + + + + 在网格中查看和编辑数据 + + + 可视化修改表结构 + + + 编写和执行原始 SQL + + + 所有键盘快捷键 + + diff --git a/docs/zh/features/data-grid.mdx b/docs/zh/features/data-grid.mdx new file mode 100644 index 00000000..be56d39d --- /dev/null +++ b/docs/zh/features/data-grid.mdx @@ -0,0 +1,727 @@ +--- +title: 数据网格 +description: 电子表格式数据网格,支持行内编辑、类型专用编辑器,以及 TSV/CSV/JSON 格式复制 +--- + +# 数据网格 + +查询结果和表内容以电子表格式网格呈现。支持行内编辑单元格、列排序、多格式复制,以及大数据集分页浏览。 + +{/* Screenshot: Data grid showing query results with multiple columns */} + + 数据网格 + 数据网格 + + +## 查看数据 + +### 打开表 + +要查看表的内容: + +1. 在侧边栏中展开数据库 +2. 点击表名 +3. 数据网格加载表的内容 + +或者执行查询: + +```sql +SELECT * FROM users; +``` + +### 结果信息 + +数据网格头部显示: + +- **行数**:返回的行数 +- **执行时间**:查询耗时 +- **影响行数**:UPDATE/DELETE 查询影响的行数 + +## 列功能 + +### 调整列宽 + +- 拖拽列边框调整宽度 +- 双击边框自动适应列宽 +- 列宽按表记忆 + +### 排序数据 + +点击列标题排序: + +- **第一次点击**:升序排列(A-Z、0-9) +- **第二次点击**:降序排列(Z-A、9-0) +- **第三次点击**:取消排序 + + +排序针对已加载的数据在本地执行。如需服务端排序,请在查询中使用 `ORDER BY`。 + + +{/* Screenshot: Column header with sort indicator */} + + 带排序指示器的列标题 + 带排序指示器的列标题 + + +### 列类型 + +每种数据类型有相应的渲染方式: + +| 类型 | 显示方式 | +|------|----------| +| Text/Varchar | 纯文本 | +| Integer | 右对齐数字 | +| Decimal/Float | 格式化数字 | +| Boolean | True/False | +| Date/Time | 格式化日期字符串 | +| NULL | 带样式的 "NULL" 指示器 | +| JSON | 格式化 JSON(可展开) | +| ENUM | 下拉弹出编辑器 | +| SET | 复选框弹出编辑器 | +| Binary/BLOB | 二进制指示器 | + +## 数据编辑 + +### 行内编辑 + +要编辑单元格: + +1. 双击单元格 +2. 输入新值 +3. 按 `Enter` 确认或 `Escape` 取消 + +{/* Screenshot: Cell being edited with cursor */} + + 单元格编辑 + 单元格编辑 + + +### 编辑模式 + +| 模式 | 触发方式 | 说明 | +|------|----------|------| +| 查看 | 默认 | 只读展示 | +| 编辑 | 双击 | 修改单元格值 | + +### 日期/时间选择器 + +编辑 date、datetime、timestamp 或 time 列时,会弹出原生日期选择器,而非纯文本输入框。选择器会根据列类型自动调整: + +| 列类型 | 选择器元素 | +|--------|-----------| +| `DATE` | 年、月、日 | +| `DATETIME` / `TIMESTAMP` | 年、月、日、时、分、秒 | +| `TIME` | 时、分、秒 | + +选择器能处理常见的数据库日期格式,并以标准格式(`YYYY-MM-DD HH:MM:SS`)输出值。你可以使用步进控件或直接在选择器字段中输入。 + + +日期选择器会自动解析现有的单元格值。如果无法解析,则默认为当前日期/时间。 + + +{/* Screenshot: Date picker for editing date columns */} + + 用于编辑日期列的日期选择器 + 用于编辑日期列的日期选择器 + + +### 外键查找 + +编辑外键列时,会弹出一个可搜索的下拉列表,显示来自关联表的有效值: + +- 下拉列表同时显示外键值和描述文本列(例如 `1 — John Doe`) +- 在搜索框中输入以筛选值 +- 单击高亮选中;双击或按 `Enter` 确认 +- 弹出窗口自动检测关联表中最合适的显示列 + + +外键查找最多获取关联表中的 1,000 条值。对于更多记录的表,使用搜索框缩小范围。 + + +{/* Screenshot: Foreign key lookup with search */} + + 带搜索的外键查找 + 带搜索的外键查找 + + +### 布尔值编辑器 + +双击 BOOLEAN、BIT 或 TINYINT(1) 单元格会弹出复选框,方便快速切换 true/false: + +- **复选框**:点击切换 true 和 false +- **确定/取消**:点击 **OK** 或按 `Enter` 确认;点击 **Cancel** 或按 `Escape` 取消 +- **可空列**:第三种不确定状态表示 NULL + +不同数据库的行为: + +| 数据库 | 列类型 | 值 | +|--------|--------|-----| +| MySQL/MariaDB | `TINYINT(1)`、`BIT(1)` | `0` / `1` | +| PostgreSQL | `BOOLEAN` | `TRUE` / `FALSE` | +| SQLite | `INTEGER` | `0` / `1` | + + +对于可空的布尔列,复选框支持三种状态:选中(true)、未选中(false)和不确定(NULL)。 + + +{/* Screenshot: Boolean cell checkbox editor */} + + 布尔值复选框编辑器 + 布尔值复选框编辑器 + + +### ENUM 列编辑器 + +双击 ENUM 单元格会弹出一个可搜索的下拉列表,显示所有允许的值: + +- **搜索框**:输入以筛选列表 +- **NULL 选项**:可空列时显示在顶部(斜体显示) +- **当前值**:以强调色高亮 +- 单击值即可选中并立即确认 +- 按 `Escape` 取消 + +支持所有数据库: + +| 数据库 | ENUM 来源 | +|--------|-----------| +| MySQL/MariaDB | 列定义中的原生 `ENUM` 类型 | +| PostgreSQL | 用户定义的枚举类型(通过 `pg_enum` 目录) | +| SQLite | `CHECK(column IN ('val1','val2'))` 约束 | + +{/* Screenshot: ENUM value selector */} + + ENUM 值选择器 + ENUM 值选择器 + + +### SET 列编辑器 + +双击 SET 单元格(MySQL/MariaDB)会弹出复选框面板: + +- 每个允许的值显示为一个复选框 +- 当前选中的值已预勾选(从逗号分隔的单元格值中解析) +- 点击 **OK** 或按 `Enter` 确认选中的值(以逗号连接) +- 点击 **Cancel** 或按 `Escape` 放弃更改 + + +如果 ENUM/SET 值不可用(例如来自复杂查询结果而非直接浏览表),单元格将回退到行内文本编辑。 + + +{/* Screenshot: SET value multi-select editor */} + + SET 值多选编辑器 + SET 值多选编辑器 + + +### JSON 编辑器 + +编辑 JSON 或 JSONB 单元格会弹出专用的 JSON 编辑器: + +- **实时验证**:输入时显示 JSON 是否有效 +- **保存/取消**:明确的按钮用于确认或放弃更改 + +编辑器在保存前会验证 JSON。无效的 JSON 会在保存前触发确认对话框。 + + +JSON 值在保存到数据库时会自动压缩(最小化)。 + + +{/* Screenshot: JSON editor with validation */} + + 带验证的 JSON 编辑器 + 带验证的 JSON 编辑器 + + +### 多行编辑 + +一次操作多行: + +- **选择多行**:按住 `Cmd` 点击行号(不连续选择)或按住 `Shift`(范围选择) +- **删除多行**:选中行后,点击 **Delete** 或按 `Delete` 键 +- **多行操作**:使用工具栏按钮操作当前选区 + +{/* Screenshot: Multiple rows selected for editing */} + + 选中多行进行编辑 + 选中多行进行编辑 + + +### 保存更改 + +更改会排入队列,不会立即应用。通过以下方式管理待提交的更改: + +- **预览 SQL**:点击 **Preview SQL** 按钮(眼睛图标)或按 `Cmd+Shift+P`,在提交前查看待执行的 SQL 语句 +- **提交**:点击 **Commit** 按钮(或按 `Cmd+S`)应用所有待提交的更改 +- **丢弃**:点击 **Discard** 按钮撤销所有待提交的更改 +- **撤销/重做**:提交前按 `Cmd+Z` 撤销或 `Cmd+Shift+Z` 重做单个编辑 + +详情参见[变更追踪](/zh/features/change-tracking)。 + + +编辑功能仅适用于简单的 `SELECT * FROM table` 查询。包含 JOIN 或聚合的复杂查询为只读模式。 + + +### 新增行 + +要新增一行: + +1. 点击工具栏中的 **+** 按钮(或使用键盘快捷键) +2. 为每列填入值 +3. 应用更改以保存 + +### 删除行 + +要删除行: + +1. 选择要删除的行 +2. 点击 **Delete** 按钮或按 `Delete` 键 +3. 确认删除 +4. 应用更改以执行 + +## 变更指示器 + +待提交的更改会有视觉反馈: + +- **已修改的单元格**以特殊背景色高亮 +- **新增行**显示插入指示器 +- **已删除行**显示删除指示器 +- **工具栏**显示待提交更改的计数 + +在提交到数据库前查看所有修改。详情参见[变更追踪](/zh/features/change-tracking)。 + +## 单元格检查器 + +单元格检查器是一个右侧边栏面板,显示选中行或当前表的详细信息。使用 `Cmd+Shift+B` 或通过 **View** > **Toggle Cell Inspector** 切换。 + +{/* Screenshot: Cell Inspector showing row details */} + + 单元格检查器 + 单元格检查器 + + +### 行详情模式 + +选中某行时,单元格检查器显示该行的所有列值: + +- **可搜索的列列表**:在搜索框中输入即可查找列 +- **列名和数据类型**:每项显示列名及其数据类型 +- **完整单元格值**:值完整显示,不截断 +- **多行文本编辑**:TEXT/VARCHAR 列提供多行文本框编辑长文本 +- **只读指示**:不可编辑的单元格标记为只读 + +可以直接在检查器中编辑值。更改与网格行内编辑一样排入队列,提交前不会生效。 + +### 表信息模式 + +未选中行时,单元格检查器显示表的元数据: + +| 元数据 | 说明 | +|--------|------| +| 表名 | 当前表名 | +| 行数 | 总行数 | +| 存储大小 | 表使用的磁盘空间 | +| 创建日期 | 表的创建时间 | +| 引擎 | 存储引擎(如 InnoDB、MyISAM) | +| 字符集 | 表的字符集 | +| 排序规则 | 排序使用的 collation | + + +安全模式设为只读的连接以及复杂查询结果不可编辑。在这些情况下,单元格检查器中的编辑功能被禁用。详情参见[安全模式](/zh/features/safe-mode)。 + + +## 导航 + +### 键盘导航 + +| 按键 | 操作 | +|------|------| +| 方向键 | 在单元格间移动 | +| `Tab` | 移到下一个单元格 | +| `Shift+Tab` | 移到上一个单元格 | +| `Enter` | 编辑选中的单元格 | +| `Escape` | 取消编辑 / 取消选择 | +| `Home` | 移到行首单元格 | +| `End` | 移到行尾单元格 | +| `Cmd+Home` | 移到第一行 | +| `Cmd+End` | 移到最后一行 | +| `Page Up` | 向上翻页 | +| `Page Down` | 向下翻页 | + +### 鼠标导航 + +- **点击**:选中单元格 +- **双击**:编辑单元格 +- **点击拖拽**:选择多个单元格 +- **滚轮**:垂直滚动 +- **Shift + 滚动**:水平滚动 + +## 选择 + +### 选择单元格 + +- **单个单元格**:点击单元格 +- **单元格范围**:点击拖拽,或点击第一个单元格后 Shift+点击最后一个 +- **整行**:点击行号 +- **多行**:点击行号并拖拽,或 Cmd+点击不连续选择 + +### 复制数据 + +1. 选择要复制的单元格或行 +2. 按 `Cmd+C` +3. 粘贴到其他应用程序 + +多种复制格式: + +| 格式 | 快捷键 | 说明 | +|------|--------|------| +| Tab 分隔 | `Cmd+C` | 默认复制格式,兼容电子表格 | +| CSV | `Cmd+Shift+C` | 逗号分隔值 | +| JSON | `Cmd+Option+C` | JSON 对象数组 | +| TSV | 右键菜单中可用 | 带表头的 Tab 分隔值 | + +默认的 Tab 分隔格式兼容: +- Excel +- Numbers +- Google Sheets +- 文本编辑器 + +{/* Screenshot: Copy options in context menu */} + + 右键菜单中的复制选项 + 右键菜单中的复制选项 + + +## 分页 + +大数据集会自动分页。 + +### 分页控件 + +- **第一页**:跳到开头 +- **上一页**:返回上一页 +- **页码**:当前页 / 总页数 +- **下一页**:前进一页 +- **最后一页**:跳到末尾 + +### 每页行数 + +在 **Settings** > **Data Grid** 中配置默认每页行数: + +| 选项 | 每页行数 | +|------|----------| +| 小 | 100 | +| 中 | 500 | +| 大 | 1,000 | +| 自定义 | 10 - 100,000 | + + +较小的页面大小加载更快且占用更少内存。需要一次查看更多数据时再使用较大值。 + + +{/* Screenshot: Pagination controls with page navigation */} + + 分页导航控件 + 分页导航控件 + + +## NULL 值 + +NULL 值有明显的视觉区分: + +- 显示带样式的 "NULL" 文本(可自定义) +- 与普通值颜色不同 +- 不会与字符串 "NULL" 混淆 + +{/* Screenshot: Data grid showing NULL values */} + + NULL 值 + NULL 值 + + +### 自定义 NULL 显示 + +在 **Settings** > **Data Grid** 中: + +| 设置 | 默认值 | 说明 | +|------|--------|------| +| **NULL 显示** | "NULL" | NULL 值显示的文本 | + +## 日期格式 + +配置日期的显示格式: + +| 格式 | 示例 | +|------|------| +| ISO 8601 | 2024-12-31 23:59:59 | +| ISO Date | 2024-12-31 | +| US Long | 12/31/2024 11:59:59 PM | +| US Short | 12/31/2024 | +| EU Long | 31/12/2024 23:59:59 | +| EU Short | 31/12/2024 | + +在 **Settings** > **Data Grid** > **Date Format** 中配置。 + +## 行高 + +调整行高以提高可读性: + +| 选项 | 高度 | 适用场景 | +|------|------|----------| +| 紧凑 | 20px | 密集数据,可见更多行 | +| 正常 | 24px | 常规查看 | +| 舒适 | 28px | 更好的可读性 | +| 宽敞 | 32px | 无障碍、触控 | + +在 **Settings** > **Data Grid** > **Row Height** 中配置。 + +{/* Screenshot: Row height comparison: Compact, Normal, Comfortable, Spacious */} + + 行高对比:紧凑、正常、舒适、宽敞 + 行高对比:紧凑、正常、舒适、宽敞 + + +## 交替行颜色 + +交替行颜色让浏览更轻松: + +- **开启**:每隔一行显示淡色背景 +- **关闭**:所有行背景相同 + +在 **Settings** > **Data Grid** > **Show Alternate Rows** 中配置。 + +{/* Screenshot: Data grid with alternate row colors */} + + 带交替行颜色的数据网格 + 带交替行颜色的数据网格 + + +## MongoDB 集合 + +MongoDB 集合在数据网格中与 SQL 数据库有一些区别。 + +### 文档模式 + +MongoDB 集合没有固定的 schema。TablePro 通过抽样最多 500 个文档来推断列结构。如果文档结构不一致,缺少对应字段的文档会显示 NULL。 + +### 不可变的 _id 列 + +`_id` 列不可编辑。MongoDB 不允许修改现有文档的 `_id`。要更改文档的 `_id`,需删除后重新插入。 + +### BSON 类型显示 + +MongoDB 的 BSON 类型以适当的格式显示: +- **ObjectId**:显示为 `ObjectId("...")` +- **Date**:格式化为 ISO 8601 日期时间 +- **Binary**:显示为 `BinData(subtype, "base64...")` +- **Decimal128**:显示为十进制字符串 +- **DBRef**:显示为 `DBRef("collection", id)` + +### MQL 语句预览 + +在数据网格中进行变更(插入、更新、删除)时,预览显示 MongoDB shell 命令而非 SQL: +- 插入生成 `db.collection.insertMany([...])` +- 更新生成 `db.collection.updateOne({filter}, {$set: {...}})` +- 删除生成 `db.collection.deleteMany({_id: {$in: [...]}})` + +## 处理大数据集 + +### 性能建议 + +1. **使用 LIMIT**:浏览数据时始终限制结果数 + ```sql + SELECT * FROM large_table LIMIT 100; + ``` + +2. **选择特定列**:多列表避免使用 `SELECT *` + ```sql + SELECT id, name, email FROM users; + ``` + +3. **使用分页**:利用数据网格的分页功能 + +4. **在数据库端过滤**:使用 WHERE 子句代替加载全部数据 + ```sql + SELECT * FROM orders WHERE status = 'pending'; + ``` + +### 内存使用 + +数据网格按页加载数据以管理内存: + +- 仅可见页保留在内存中 +- 滚动时按需加载新页 +- 大型 BLOB/TEXT 列按需加载 + +## 导出选项 + +直接从数据网格导出数据: + +1. 运行查询或打开表 +2. 点击 **Export** 按钮 +3. 选择格式:CSV、JSON、SQL +4. 选择导出位置 + +详情参见[导入与导出](/zh/features/import-export)。 + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 复制选中内容 | `Cmd+C` | +| 复制为 CSV | `Cmd+Shift+C` | +| 复制为 JSON | `Cmd+Option+C` | +| 全选 | `Cmd+A` | +| 删除行 | `Delete` | +| 编辑单元格 | `Enter` | +| 取消编辑 | `Escape` | +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | +| 提交更改 | `Cmd+S` | +| 导航 | 方向键 | +| 下一个单元格 | `Tab` | +| 上一个单元格 | `Shift+Tab` | + +## 下一步 + + + + 编写查询 + + + 从网格导出数据 + + + 查看表定义 + + + 配置数据网格选项 + + diff --git a/docs/zh/features/deep-links.mdx b/docs/zh/features/deep-links.mdx new file mode 100644 index 00000000..5a8f2562 --- /dev/null +++ b/docs/zh/features/deep-links.mdx @@ -0,0 +1,168 @@ +--- +title: 深度链接 +description: 通过终端或其他应用使用数据库 URL 或 tablepro:// 链接打开连接、表和查询 +--- + +TablePro 支持两种基于 URL 的入口:标准数据库 URL(`mysql://`、`postgresql://` 等)和自定义的 `tablepro://` scheme。 + +## 数据库 URL + +使用标准 URL 直接打开任意数据库连接。可从终端、脚本、Alfred、Raycast 或任何能打开 URL 的应用使用。 + +### 支持的 Scheme + +| Scheme | 数据库 | +|--------|--------| +| `mysql://` | MySQL / MariaDB | +| `postgresql://`、`postgres://` | PostgreSQL | +| `mongodb://`、`mongodb+srv://` | MongoDB | +| `redis://`、`rediss://` | Redis | +| `mssql://`、`sqlserver://` | SQL Server | +| `sqlite://` | SQLite(本地文件路径) | + +### URL 格式 + +``` +scheme://[username[:password]@]host[:port][/database][?param=value] +``` + +### 示例 + +```bash +# MySQL +open "mysql://root@localhost/mydb" -a TablePro + +# PostgreSQL with port and database +open "postgresql://admin@db.example.com:5432/analytics" -a TablePro + +# MongoDB +open "mongodb://localhost:27017/mydb" -a TablePro + +# Redis +open "redis://localhost:6379" -a TablePro + +# SQLite (local file) +open "sqlite:///Users/me/data/app.db" -a TablePro +``` + +### 工作原理 + +1. **匹配已保存的连接:**TablePro 检查已保存的连接中是否有与 URL 的 host、port、database 和 username 匹配的。如果找到,会复用该连接(包括其存储的密码)。 +2. **匹配活跃会话:**如果该连接已处于打开状态,TablePro 将现有窗口前置而非创建重复的连接。 +3. **创建临时连接:**如果没有匹配的连接,TablePro 创建一个临时连接并立即连接。URL 中的密码用于初次连接但不会被保存。 + +### 查询参数 + +通过查询参数传递附加选项: + +| 参数 | 说明 | +|------|------| +| `table` | 连接后打开指定的表 | +| `filter_column`、`filter_operation`、`filter_value` | 对打开的表应用筛选条件 | +| `condition` | 应用原始 SQL WHERE 条件 | +| `schema` | 连接后切换到指定的 schema(PostgreSQL)或数据库(MySQL) | + +```bash +# Open a table with a filter +open "mysql://root@localhost/mydb?table=users&filter_column=status&filter_operation=equal&filter_value=active" -a TablePro + +# Open with a raw SQL condition +open "postgresql://admin@localhost/mydb?table=orders&condition=total%20%3E%20100" -a TablePro + +# Switch schema on connect +open "postgresql://admin@localhost/mydb?schema=reporting" -a TablePro +``` + + +密码可以包含在 URL 中(`mysql://user:pass@host/db`),但避免分享包含密码的 URL。推荐使用已保存的连接配合钥匙串存储的密码。 + + +## 自定义深度链接(tablepro://) + +TablePro 注册了 `tablepro://` URL scheme,可以从浏览器、终端、Slack 消息或任何支持链接的应用中打开连接、表和查询。 + +## URL 模式 + +### 打开连接 + +``` +tablepro://connect/{name} +``` + +打开名称匹配 `{name}` 的已保存连接。如果未找到匹配项,会显示错误提示。 + +```bash +open "tablepro://connect/Production" +``` + +### 打开表 + +``` +tablepro://connect/{name}/table/{table} +tablepro://connect/{name}/database/{db}/table/{table} +``` + +连接并打开指定的表。第二种形式指定连接上的特定数据库。 + +```bash +open "tablepro://connect/Production/table/users" +open "tablepro://connect/Production/database/analytics/table/events" +``` + +### 打开查询 + +``` +tablepro://connect/{name}/query?sql={encoded_sql} +``` + +连接并打开一个新的查询标签页,SQL 已预填充。SQL 必须经过 URL 编码。 + +```bash +open "tablepro://connect/Production/query?sql=SELECT%20*%20FROM%20users%20LIMIT%2010" +``` + +### 导入连接 + +``` +tablepro://import?name={n}&host={h}&port={p}&type={t}&username={u}&database={db} +``` + +创建新的已保存连接并打开连接表单供审查。你可以在连接前添加密码。 + +```bash +open "tablepro://import?name=Staging&host=db.example.com&port=5432&type=postgresql&username=admin&database=mydb" +``` + +**必填参数:**`name`、`host`、`type` +**可选参数:**`port`(默认为数据库类型的标准端口)、`username`、`database` + +支持的 `type` 值:`MySQL`、`MariaDB`、`PostgreSQL`、`SQLite`、`MongoDB`(不区分大小写)。 + +## 行为细节 + +- **连接名称匹配**不区分大小写。`Production`、`production` 和 `PRODUCTION` 都匹配同一个连接。 +- **空格和特殊字符**会被浏览器和 macOS 自动进行 URL 编码。 +- **已连接:**如果连接已处于活跃状态,TablePro 跳过重新连接,直接打开请求的标签页。 +- **应用未运行:**macOS 会先启动 TablePro,然后传递 URL。 + + +深度链接 URL 中永远不包含密码。对于导入的连接,用户必须在连接表单中手动输入密码。 + + +## 终端使用 + +使用 `open` 命令在终端中触发深度链接: + +```bash +# Connect +open "tablepro://connect/Production" + +# Open a specific table +open "tablepro://connect/Production/table/users" + +# Run a query +open "tablepro://connect/Production/query?sql=SELECT%20count(*)%20FROM%20orders" + +# Import a new connection for review +open "tablepro://import?name=Dev&host=localhost&port=3306&type=mysql&username=root&database=app" +``` diff --git a/docs/zh/features/filtering.mdx b/docs/zh/features/filtering.mdx new file mode 100644 index 00000000..73938ab3 --- /dev/null +++ b/docs/zh/features/filtering.mdx @@ -0,0 +1,458 @@ +--- +title: 筛选 +description: 通过可视化方式构建 WHERE 子句,支持 18 种运算符、快速搜索和保存预设 +--- + +# 筛选 + +筛选面板让你无需编写 SQL 即可构建 WHERE 子句。选择列、运算符和值,通过可视化方式操作,也可切换到原始 SQL 模式来表达构建器无法实现的条件。筛选器按标签页独立,每个工作区保持各自的状态。 + +{/* Screenshot: Filter panel with multiple active filters */} + + 筛选面板 + 筛选面板 + + +## 概述 + +筛选系统包含五个部分: + +- **筛选面板** — 可视化构建 WHERE 子句条件 +- **快速搜索** — 即时搜索所有可见列 +- **筛选预设** — 保存和加载命名的筛选配置 +- **SQL 预览** — 在应用前查看生成的 WHERE 子句 +- **标签页独立状态** — 每个标签页独立记忆自己的筛选条件 + +## 筛选面板 + +### 打开筛选面板 + +切换筛选面板: + +- 点击工具栏中的 **Filter** 按钮 +- 或按 `Cmd+F` + +面板显示在数据网格上方。打开面板时快速搜索框会自动获得焦点。 + +### 构建筛选条件 + +每个筛选行有三部分: + +1. **列** — 要筛选的列 +2. **运算符** — 比较运算符 +3. **值** — 要比较的值 + +{/* Screenshot: Single filter row showing column, operator, and value */} + + 筛选行 + 筛选行 + + +### 添加和管理筛选条件 + +| 操作 | 方法 | +|------|------| +| 添加筛选条件 | 点击头部的 **+** 按钮 | +| 复制筛选条件 | 点击筛选行上的复制图标 | +| 删除筛选条件 | 点击筛选行上的 **x** 按钮 | +| 聚焦筛选条件 | 点击行的任意位置 | + +### AND / OR 逻辑 + +使用筛选头部的分段控件在 AND 和 OR 逻辑之间切换: + +- **AND** — 所有条件必须匹配(交集) +- **OR** — 任一条件匹配即可(并集) + + +AND 模式逐步缩小结果范围。OR 模式查找符合任一条件的行。 + + +{/* Screenshot: AND/OR logic toggle in filter header */} + + 筛选头部的 AND/OR 逻辑切换 + 筛选头部的 AND/OR 逻辑切换 + + +### 选择和应用筛选条件 + +每个筛选行有一个复选框用于选择性应用: + +| 操作 | 说明 | +|------|------| +| **选中/取消选中** | 切换单个筛选条件的复选框 | +| **全选** | 使用底部的"全选"复选框 | +| **应用单个** | 点击筛选行上的播放按钮仅应用该条件 | +| **应用全部** | 点击底部的 **Apply All** 应用所有选中的条件 | +| **取消设置** | 点击 **Unset** 清除所有已应用的筛选并重新加载未筛选的数据 | + + +只有完整填写了列、运算符和值(如需要)的有效筛选条件才能应用。无效条件的播放按钮会被禁用。 + + +{/* Screenshot: Select All checkbox and Apply All button */} + + 全选复选框和应用全部按钮 + 全选复选框和应用全部按钮 + + +## 运算符 + +筛选构建器支持 18 种运算符: + +| 运算符 | 显示名称 | 需要值 | 说明 | +|--------|----------|--------|------| +| `=` | 等于 | 是 | 精确匹配 | +| `!=` | 不等于 | 是 | 排除精确匹配 | +| CONTAINS | 包含 | 是 | 子串匹配(LIKE %value%) | +| NOT CONTAINS | 不包含 | 是 | 排除子串 | +| STARTS WITH | 开头是 | 是 | 前缀匹配(LIKE value%) | +| ENDS WITH | 结尾是 | 是 | 后缀匹配(LIKE %value) | +| `>` | 大于 | 是 | 大于比较 | +| `>=` | 大于等于 | 是 | 大于等于比较 | +| `<` | 小于 | 是 | 小于比较 | +| `<=` | 小于等于 | 是 | 小于等于比较 | +| IS NULL | 为 NULL | 否 | 列值为 NULL | +| IS NOT NULL | 不为 NULL | 否 | 列值不为 NULL | +| IS EMPTY | 为空 | 否 | 列值为空字符串 | +| IS NOT EMPTY | 不为空 | 否 | 列值不为空字符串 | +| IN | 在列表中 | 是 | 值在逗号分隔的列表中 | +| NOT IN | 不在列表中 | 是 | 值不在逗号分隔的列表中 | +| BETWEEN | 介于 | 是(两个值) | 值在两个边界之间 | +| REGEX | 匹配正则 | 是 | 正则表达式匹配 | + +### 无需值的运算符 + +IS NULL、IS NOT NULL、IS EMPTY 和 IS NOT EMPTY 会隐藏值输入框,显示一个破折号指示器代替。无需输入。 + +### BETWEEN 运算符 + +BETWEEN 显示两个值输入框,中间有"and"标签。两个值都必须填写。 + +{/* Screenshot: BETWEEN filter with two value fields */} + + BETWEEN 筛选器 + BETWEEN 筛选器 + + +### IN / NOT IN 运算符 + +输入逗号分隔的值以匹配列表: + +``` +value1, value2, value3 +``` + +## 原始 SQL 模式 + +对于可视化构建器无法表达的条件,可切换到原始 SQL 模式。 + +### 使用原始 SQL + +1. 点击筛选行的列下拉列表 +2. 选择列表顶部的 **Raw SQL** +3. 运算符下拉消失,值输入框变为自由文本 SQL 输入 +4. 直接输入 WHERE 子句条件 + +{/* Screenshot: Raw SQL filter with arbitrary WHERE clause */} + + 原始 SQL 筛选 + 原始 SQL 筛选 + + +**示例:** + +```sql +created_at > NOW() - INTERVAL 7 DAY +``` + +```sql +LOWER(name) LIKE '%smith%' AND status IN ('active', 'pending') +``` + +```sql +price * quantity > 1000 +``` + + +原始 SQL 会直接注入 WHERE 子句。请确保语法与连接的数据库类型一致。 + + +## 快速搜索 + +快速搜索可同时在所有可见列中筛选,无需构建单独的筛选行。 + +### 使用快速搜索 + +1. 打开筛选面板 +2. 在 **Quick search across all columns...** 输入框中输入 +3. 按 `Enter` 应用 + +{/* Screenshot: Quick search field with search text */} + + 快速搜索 + 快速搜索 + + +筛选面板打开时快速搜索始终可见。点击 **x** 按钮清除。 + + +快速搜索适合一次性查找。对于反复使用的筛选模式,建议保存为预设。 + + +## 筛选预设 + +将当前筛选配置保存为命名预设,方便快速复用。 + +### 保存预设 + +1. 在筛选面板中构建筛选条件 +2. 点击筛选头部的**文件夹**图标 +3. 选择 **Save as Preset...** +4. 输入名称并点击 **Save** + +{/* Screenshot: Save filter preset dialog */} + + 保存筛选预设对话框 + 保存筛选预设对话框 + + +### 加载预设 + +1. 点击筛选头部的**文件夹**图标 +2. 从下拉菜单中选择预设 +3. 保存的筛选条件替换当前筛选列表 + +{/* Screenshot: Load saved filter presets */} + + 加载已保存的筛选预设 + 加载已保存的筛选预设 + + +### 管理预设 + +| 操作 | 方法 | +|------|------| +| 加载 | 在文件夹菜单中点击预设名称 | +| 删除 | 选择 **Delete Preset** > 点击预设名称 | +| 覆盖 | 使用相同名称保存新预设 | + +预设通过 UserDefaults 存储,跨会话持久化。 + + +预设保存筛选定义(列、运算符、值),但不保存是否已应用。加载预设后,点击 **Apply All** 激活筛选条件。 + + +## SQL 预览 + +在应用之前查看将发送到数据库的确切 WHERE 子句。 + +### 查看预览 + +1. 构建筛选条件 +2. 点击筛选底部的 **SQL** 按钮 +3. 弹出窗口显示生成的 WHERE 子句 + +{/* Screenshot: SQL preview sheet showing generated WHERE clause */} + + SQL 预览 + SQL 预览 + + +### 预览内容 + +- 完整的 WHERE 子句,包含与数据库类型匹配的正确引号 +- MySQL 使用反引号(`` `column` ``) +- PostgreSQL 使用双引号(`"column"`) +- 基于当前模式的 AND/OR 逻辑 +- "Copy" 按钮可将 SQL 复制到剪贴板 + +如果部分(非全部)筛选条件被选中,预览只显示选中的条件。否则显示所有有效条件。 + +### 处理无效筛选 + +如果筛选条件存在但没有有效的,预览会提示需要完成的内容: + +- 选择一列 +- 输入值(如果运算符需要) +- 为 BETWEEN 填写第二个值 + +## 标签页独立的筛选状态 + +每个标签页维护独立的筛选状态。 + +### 工作原理 + +- 打开表时为该标签页创建全新的筛选状态 +- 切换标签页时保留各自的筛选条件 +- 已应用的筛选在切换离开和返回时保持活跃 +- 筛选面板的可见性按标签页记忆 + +### 状态组成 + +每个标签页存储: + +| 组成部分 | 说明 | +|----------|------| +| **筛选列表** | 所有筛选行(已应用或未应用) | +| **已应用的筛选** | 当前影响查询的活跃筛选条件 | +| **面板可见性** | 筛选面板是显示还是隐藏 | + +## 筛选设置 + +在设置弹出窗口中配置默认筛选行为。 + +### 访问设置 + +点击筛选面板头部的**齿轮**图标打开设置弹窗。 + +{/* Screenshot: Filter settings popover */} + + 筛选设置 + 筛选设置 + + +### 默认列 + +控制新增筛选条件时预选的列: + +| 选项 | 说明 | +|------|------| +| **Raw SQL** | 新筛选条件默认为原始 SQL 模式 | +| **主键** | 新筛选条件默认为表的主键列 | +| **任意列** | 新筛选条件默认为第一个可用列 | + +### 默认运算符 + +控制新增筛选条件时预选的运算符: + +| 选项 | 说明 | +|------|------| +| **等于 (=)** | 默认精确匹配 | +| **包含** | 默认子串匹配 | + +### 打开时的面板状态 + +控制打开表时筛选面板的行为: + +| 选项 | 说明 | +|------|------| +| **始终隐藏** | 筛选面板初始隐藏(默认) | +| **始终显示** | 打开表时始终显示筛选面板 | +| **恢复上次筛选** | 恢复该表上次使用的筛选条件 | + + +"恢复上次筛选"按表名记忆筛选条件。如果你经常用相同条件筛选同一张表,每次打开都能节省设置时间。 + + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 切换筛选面板 / 快速搜索 | `Cmd+F` | +| 应用筛选条件(在值输入框中) | `Enter` | + +## 下一步 + + + + 查看和浏览筛选结果 + + + 手动编写 WHERE 子句 + + + 导出筛选后的数据 + + + 配置应用偏好 + + diff --git a/docs/zh/features/import-export.mdx b/docs/zh/features/import-export.mdx new file mode 100644 index 00000000..a1964476 --- /dev/null +++ b/docs/zh/features/import-export.mdx @@ -0,0 +1,537 @@ +--- +title: 导入与导出 +description: 导出为 CSV、JSON、SQL、MQL 或 XLSX 格式,导入 SQL 文件支持事务安全和进度追踪 +--- + +# 导入与导出 + +支持五种格式导出数据(CSV、JSON、SQL、MQL、XLSX),导入 SQL 文件支持 gzip 压缩,还可以从剪贴板直接粘贴表格数据到数据网格。 + +## 导出数据 + +### 导出选项 + +从查询结果或表导出数据: + +1. 运行查询或打开表 +2. 点击工具栏中的 **Export** 按钮(或按 `Cmd+Shift+E`) +3. 选择导出格式 +4. 使用树形视图选择要导出的表 +5. 配置格式相关选项 +6. 点击 **Export** + + +**MongoDB**:MongoDB 连接不支持 SQL 导出。请使用 CSV、JSON、MQL 或 XLSX。MQL 生成可在 `mongosh` 中直接运行的 `db.collection.insertMany([...])` 脚本。 + + + +**Redis**:Redis 连接不支持 SQL 和 MQL 导出。请使用 CSV、JSON 或 XLSX 导出键值数据。 + + +{/* Screenshot: Export dialog with format options */} + + 导出对话框 + 导出对话框 + + +### 导出格式 + + + + **逗号分隔值** + + 适用于: + - Excel 和电子表格应用 + - 数据分析工具 + - 简单的数据交换 + + 选项: + | 选项 | 说明 | 默认值 | + |------|------|--------| + | 表头 | 将列名作为第一行包含 | 是 | + | 分隔符 | 分隔字符:逗号、分号、制表符或竖线 | 逗号 | + | 引号处理 | 何时引用值:始终、按需或从不 | 按需 | + | NULL 处理 | 将 NULL 值转换为空字符串 | 是 | + | 数据中的换行 | 将值中的换行转换为空格 | 否 | + | 换行格式 | 行尾格式:LF、CRLF 或 CR | LF | + | 小数格式 | 小数分隔符使用句点或逗号 | 句点 | + | 公式过滤 | 防止 CSV 注入攻击 | 是 | + + 输出示例: + ```csv + id,name,email,created_at + 1,"John Doe",john@example.com,2024-01-15 10:30:00 + 2,"Jane Smith",jane@example.com,2024-01-16 14:45:00 + ``` + + {/* Screenshot: CSV export options: delimiter, quoting, line breaks */} + + CSV 导出选项:分隔符、引号、换行 + CSV 导出选项:分隔符、引号、换行 + + + + **JavaScript 对象表示法** + + 适用于: + - Web 应用 + - API + - NoSQL 数据库 + - 程序化处理 + + 数据导出为对象数组。 + + 选项: + | 选项 | 说明 | 默认值 | + |------|------|--------| + | 美化输出 | 带缩进格式化 | 是 | + | 包含 NULL 值 | 在输出中包含值为 null 的键 | 是 | + | 保留为字符串 | 将所有值保持为字符串(适用于邮编、电话号码) | 否 | + + 输出示例: + ```json + [ + { + "id": 1, + "name": "John Doe", + "email": "john@example.com", + "created_at": "2024-01-15T10:30:00Z" + }, + { + "id": 2, + "name": "Jane Smith", + "email": "jane@example.com", + "created_at": "2024-01-16T14:45:00Z" + } + ] + ``` + + {/* Screenshot: JSON export options */} + + JSON 导出选项 + JSON 导出选项 + + + + **SQL INSERT 语句** + + 适用于: + - 数据库迁移 + - 备份与恢复 + - 数据库初始化填充 + + 全局选项: + | 选项 | 说明 | 默认值 | + |------|------|--------| + | gzip 压缩 | 保存为 `.sql.gz` 以减小文件大小 | 否 | + | 批次大小 | 每条 INSERT 语句包含的行数 | 500 | + + 每表选项(导出多表时可单独配置): + | 选项 | 说明 | 默认值 | + |------|------|--------| + | 包含结构 | 包含 CREATE TABLE 语句 | 是 | + | 包含 DROP | 在 CREATE 之前包含 DROP TABLE IF EXISTS | 是 | + | 包含数据 | 包含带行数据的 INSERT 语句 | 是 | + + 输出示例: + ```sql + DROP TABLE IF EXISTS `users`; + CREATE TABLE `users` ( ... ); + + INSERT INTO `users` (id, name, email, created_at) VALUES + (1, 'John Doe', 'john@example.com', '2024-01-15 10:30:00'), + (2, 'Jane Smith', 'jane@example.com', '2024-01-16 14:45:00'); + ``` + + {/* Screenshot: SQL export options: structure, data, batch size */} + + SQL 导出选项:结构、数据、批次大小 + SQL 导出选项:结构、数据、批次大小 + + + + **MongoDB 查询语言脚本** + + 适用于: + - 通过 `mongosh` 恢复 MongoDB 数据 + - MongoDB 备份和迁移 + - 以可执行脚本分享 MongoDB 数据 + + 选项: + | 选项 | 说明 | 默认值 | + |------|------|--------| + | 批次大小 | 每个 `insertMany` 语句包含的文档数 | 500 | + + 输出示例: + ```javascript + // TablePro MQL Export + // Generated: 2024-01-15T10:30:00Z + // Database: mydb + + // Collection: users + db.users.insertMany([ + {"_id": {"$oid": "507f1f77bcf86cd799439011"}, "name": "Alice", "age": 30}, + {"_id": {"$oid": "507f1f77bcf86cd799439012"}, "name": "Bob", "age": 25} + ]); + ``` + + + MQL 导出仅适用于 MongoDB 连接。输出为可在 `mongosh` 中直接运行的 `.js` 文件。 + + + + **Excel 电子表格** + + 适用于: + - 与非技术人员共享数据 + - Excel 和电子表格应用 + - 商业报告和分析 + + 选项: + | 选项 | 说明 | 默认值 | + |------|------|--------| + | 包含表头 | 列名在第一行(加粗) | 是 | + | NULL 为空 | 将 NULL 值转换为空单元格 | 是 | + + 特性: + - **多工作表导出**:每张表成为一个独立的工作表 + - **数字检测**:数字以数字单元格存储(非文本),确保 Excel 格式正确 + - **共享字符串**:字符串去重以减小文件大小 + - **加粗表头**:包含表头时第一行自动加粗 + - **大数据集支持**:使用流式 Data 缓冲区和后台文件组装,优化 175K+ 行导出 + - **无依赖**:纯 Swift OOXML 写入器,无外部库 + + {/* Screenshot: Excel export options */} + + Excel 导出选项 + Excel 导出选项 + + + + +### 导出查询结果 + +要导出特定查询的结果: + +1. 编写并执行查询 +2. 在结果显示时点击 **Export** +3. 仅导出显示的结果 + + +对于大批量导出,使用分页或在查询中添加 LIMIT 来控制输出大小。 + + +### 导出整张表 + +要导出表的全部数据: + +1. 点击侧边栏中的表 +2. 不应用任何筛选直接点击 **Export** +3. 或运行 `SELECT * FROM table_name` 后导出 + + +在导出对话框的树形视图中选择多张表可以一次导出多张表。以 SQL 格式导出时,每张表可以单独配置结构(DDL)、DROP 语句和数据选项。 + + +### 仅导出结构 + +要仅导出表结构(DDL): + +1. 打开表的 **Structure** 标签页 +2. 进入 **DDL** 子标签页 +3. 复制 CREATE TABLE 语句 + +或使用数据库特定命令: + +```sql +-- MySQL +SHOW CREATE TABLE users; + +-- PostgreSQL +pg_dump -s -t users database_name +``` + +### 导出进度 + +导出大数据集时,进度指示器显示: + +- **已处理行数** / 总行数 +- **当前表**(多表导出时) + +## 剪贴板粘贴(CSV/TSV) + +从剪贴板直接粘贴表格数据到数据网格。TablePro 自动检测内容是 CSV(逗号分隔)还是 TSV(制表符分隔)。 + +**工作流程:** + +1. 从电子表格、文本编辑器或其他来源复制数据 +2. 在数据网格中选择一行 +3. 按 `Cmd+V` 粘贴 + +CSV 解析器符合 RFC 4180 标准,可处理: + +- 包含逗号的引号字段(如 `"New York, NY"`) +- 转义的双引号(如 `"He said ""hello"""`) +- 引号字段中的多行值 +- 自动表头行检测(如果列名匹配则跳过) + + +格式自动检测:如果数据中制表符多于逗号,则按 TSV 解析;否则按 CSV 解析。来自 Excel 或 Google Sheets 的数据通常是制表符分隔的。 + + +## 导入数据 + +TablePro 导入 **SQL 文件**(`.sql` 和 `.sql.gz`)。语句直接在数据库上执行,适合恢复备份、运行迁移或填充初始数据。 + + +**MongoDB**:MongoDB 连接不支持 SQL 导入。请使用 `mongoimport` 或 MQL shell 导入数据。 + + +### 导入流程 + + + + 点击 **File** > **Import**(或按 `Cmd+Shift+I`)。你也可以将 `.sql` 或 `.sql.gz` 文件拖放到应用中。 + + + 从文件系统中选择 `.sql` 或 `.sql.gz` 文件。 + + + 设置编码、事务包裹和外键检查选项。 + + + 在导入前查看 SQL 代码预览、语句数量和文件大小。 + + + 点击 **Import** 执行语句并监控进度。 + + + +{/* Screenshot: Import dialog with SQL preview */} + + 导入对话框 + 导入对话框 + + +### 导入选项 + +| 选项 | 说明 | 默认值 | +|------|------|--------| +| 编码 | 文件编码:UTF-8、UTF-16、Latin1 或 ASCII | UTF-8 | +| 事务包裹 | 在单个事务中执行所有语句 | 是 | +| 禁用外键检查 | 导入期间临时禁用外键约束 | 是 | + + +使用事务包裹可以确保任何语句失败时所有更改回滚,让数据库保持一致状态。 + + +### SQL 预览 + +运行导入前,对话框显示: + +- **SQL 代码预览** +- **语句数量** — 检测到的 SQL 语句总数 +- **文件大小** + +这让你在执行前验证文件是否包含预期的 SQL。 + +## 进度与错误 + +### 导入进度 + +导入期间,进度指示器显示: + +- **已处理语句数** / 总语句数 +- **当前语句**(截断为 50 个字符) +- **进度条**显示整体完成度 + +{/* Screenshot: Import progress bar */} + + 导入进度 + 导入进度 + + +### 错误处理 + +导入在遇到第一个错误时停止。如果导入被事务包裹,所有更改会自动回滚。 + +出现错误时,TablePro 显示: + +- **失败的语句** — 导致错误的 SQL 语句 +- **行号** — 该语句在文件中的位置 +- **错误信息** — 数据库返回的错误 + + +没有"跳过错误"模式。如果语句失败,导入停止。使用"事务包裹"确保部分导入能干净地回滚。 + + +## 压缩 + +### 压缩导出 + +gzip 压缩仅适用于 **SQL 导出**: + +- 在 SQL 导出设置中启用 "Compress with gzip" +- 输出保存为 `.sql.gz` 扩展名 +- 显著减小大型 SQL 转储的文件大小 + + +gzip 压缩不适用于 CSV、JSON 或 XLSX 导出。 + + +### 压缩导入 + +- TablePro 在导入时自动检测 `.sql.gz` 文件 +- 文件即时解压 — 无需手动解压 +- 行为与导入普通 `.sql` 文件完全相同 + +## 最佳实践 + +### 导出 + +1. **先筛选**:只导出你需要的数据 + ```sql + SELECT * FROM orders WHERE status = 'completed' AND year(created_at) = 2024; + ``` + +2. **考虑文件大小**:对大表使用 LIMIT + ```sql + SELECT * FROM logs ORDER BY created_at DESC LIMIT 100000; + ``` + +3. **选择合适的格式**: + - CSV 适合数据分析工具 + - JSON 适合 API/Web 应用 + - SQL 适合数据库迁移 + - MQL 适合通过 `mongosh` 进行 MongoDB 备份/恢复 + - XLSX 适合与非技术人员共享 Excel 数据 + +4. **大型 SQL 导出使用 gzip**:压缩可显著减小文件大小 + +### 导入 + +1. **先备份**:运行 SQL 导入前始终备份数据库 + +2. **先用小文件测试**:在运行大型导入前,用子集验证导入设置 + +3. **使用事务**:保持"事务包裹"启用,以便失败的导入自动回滚 + +4. **禁用外键检查**:导入按特定顺序引用表的转储文件时,保持此选项启用以避免约束错误 + +5. **检查编码**:确保编码设置与 SQL 文件的实际编码匹配,以避免字符乱码 + +## 故障排除 + +### 导出问题 + +**"文件太大"** +- 在查询中使用 LIMIT +- 分批导出 +- SQL 导出启用 gzip 压缩 +- 选择更紧凑的格式(CSV 相对于 JSON) + +**"字符编码问题"** +- 验证数据库编码 +- 使用 UTF-8 编码导出 +- 检查特殊字符 + +### 导入问题 + +**"SQL 语法错误"** +- 确认 SQL 文件是从兼容的数据库引擎导出的 +- 检查文件编码是否与导入对话框中的设置匹配 +- 用文本编辑器打开文件检查问题行 + +**"重复键错误"** +- 数据中包含唯一键或主键列的重复值 +- 在 SQL 导出中包含 DROP TABLE 语句以从头开始 +- 或在导入前手动删除目标表 + +**"外键约束"** +- 在导入选项中启用"禁用外键检查" +- 或确保 SQL 文件中父表在子表之前创建 + +**"事务已回滚"** +- 文件中某条语句导致错误,回滚了整个导入 +- 检查错误信息和行号以定位问题语句 +- 修复 SQL 文件并重新导入 + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 导出 | `Cmd+Shift+E` | +| 导入 | `Cmd+Shift+I` | + +## 下一步 + + + + 导出前查看数据 + + + 用查询筛选数据 + + + 导出 schema DDL + + + 重新运行导入查询 + + diff --git a/docs/zh/features/keyboard-shortcuts.mdx b/docs/zh/features/keyboard-shortcuts.mdx new file mode 100644 index 00000000..0d0fed10 --- /dev/null +++ b/docs/zh/features/keyboard-shortcuts.mdx @@ -0,0 +1,496 @@ +--- +title: 键盘快捷键 +description: SQL 编辑器、数据网格、标签页、Vim 模式的完整快捷键列表及自定义方法 +--- + +# 键盘快捷键 + +TablePro 以键盘操作为核心。大多数操作都有快捷键,大部分菜单快捷键可以自定义。 + +## 速查 + +### 常用快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 执行查询 | `Cmd+Enter` | +| 新建连接 | `Cmd+N` | +| 打开历史 | `Cmd+Y` | +| 设置 | `Cmd+,` | +| 关闭窗口 | `Cmd+W` | +| 退出 | `Cmd+Q` | + +## SQL 编辑器 + +### 查询执行 + +| 操作 | 快捷键 | 说明 | +|------|--------|------| +| 执行查询 | `Cmd+Enter` | 运行光标所在的查询,或按顺序执行所有选中的语句 | +| 解释查询 | `Option+Cmd+E` | 显示光标所在查询的执行计划 | +| 格式化 SQL | `Option+Cmd+F` | 格式化 SQL 查询(美化和标准化 SQL 语法) | + + +`Cmd+Enter` 是最重要的快捷键。它运行光标所在的查询,或仅执行选中的文本。如果选中内容包含多条语句,它们会在事务中按顺序执行。 + + +### 文本编辑 + +| 操作 | 快捷键 | +|------|--------| +| 全选 | `Cmd+A` | +| 剪切 | `Cmd+X` | +| 复制 | `Cmd+C` | +| 粘贴 | `Cmd+V` | +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | +| 删除行 | `Cmd+Shift+K` | +| 复制行 | `Cmd+Shift+D` | + +### 导航 + +| 操作 | 快捷键 | +|------|--------| +| 跳到开头 | `Cmd+Up` | +| 跳到末尾 | `Cmd+Down` | +| 上移行 | `Option+Up` | +| 下移行 | `Option+Down` | + +### 查找和替换 + +| 操作 | 快捷键 | +|------|--------| +| 查找 | `Cmd+F` | +| 查找和替换 | `Cmd+Option+F` | +| 查找下一个 | `Cmd+G` | +| 查找上一个 | `Cmd+Shift+G` | + +### 选择 + +| 操作 | 快捷键 | +|------|--------| +| 选择单词 | `Cmd+D` | +| 扩展选区 | `Cmd+Shift+Right` | +| 收缩选区 | `Cmd+Shift+Left` | + +## 数据网格 + +### 导航 + +| 操作 | 快捷键 | +|------|--------| +| 在单元格间移动 | 方向键 | +| 下一个单元格 | `Tab` | +| 上一个单元格 | `Shift+Tab` | +| 行首单元格 | `Home` | +| 行尾单元格 | `End` | +| 第一行 | `Cmd+Home` | +| 最后一行 | `Cmd+End` | +| 向上翻页 | `Page Up` | +| 向下翻页 | `Page Down` | + +### 编辑 + +| 操作 | 快捷键 | +|------|--------| +| 编辑单元格 | `Enter` 或 `F2` | +| 取消编辑 | `Escape` | +| 删除行 | `Delete` 或 `Backspace` | +| 提交更改 | `Cmd+S` | + +### 数据变更 + +| 操作 | 快捷键 | +|------|--------| +| 撤销更改 | `Cmd+Z` | +| 重做更改 | `Cmd+Shift+Z` | +| 提交所有更改 | `Cmd+S` | +| 预览 SQL | `Cmd+Shift+P` | + +### 选择 + +| 操作 | 快捷键 | +|------|--------| +| 选择单元格 | 点击 | +| 选择行 | 点击行号 | +| 选择多个单元格 | 点击拖拽 | +| 扩展选区 | Shift + 点击 | +| 添加到选区 | Cmd + 点击 | +| 全选 | `Cmd+A` | + +### 剪贴板 + +| 操作 | 快捷键 | +|------|--------| +| 复制选中内容 | `Cmd+C` | +| 复制为 CSV | `Cmd+Shift+C` | +| 复制为 JSON | `Cmd+Option+C` | +| 复制为 TSV | 右键菜单中可用 | + +## 应用程序 + +### 窗口和标签页 + +| 操作 | 快捷键 | +|------|--------| +| 关闭窗口/标签页 | `Cmd+W` | +| 新建查询标签页 | `Cmd+T` | +| 切换到标签页 1-9 | `Cmd+1` 到 `Cmd+9` | +| 下一个标签页 | `Cmd+Shift+]` 或 `Cmd+Option+Right` | +| 上一个标签页 | `Cmd+Shift+[` 或 `Cmd+Option+Left` | +| 最小化 | `Cmd+M` | +| 缩放 | `Cmd+Option+Z` | + +### 连接 + +| 操作 | 快捷键 | +|------|--------| +| 新建连接 | `Cmd+N` | +| 切换连接 | `Cmd+Option+C` | +| 断开连接 | `Cmd+D` | +| 刷新连接 | `Cmd+R` | + +### 视图 + +| 操作 | 快捷键 | +|------|--------| +| 切换侧边栏 | `Cmd+0` | +| 切换全屏 | `Cmd+Control+F` | +| 放大 | `Cmd+=` | +| 缩小 | `Cmd+-` | + +### 面板 + +| 操作 | 快捷键 | +|------|--------| +| 查询历史 | `Cmd+Y` | +| 切换单元格检查器 | `Cmd+Shift+B` | +| 切换 AI 聊天 | `Cmd+Shift+L` | +| 设置 | `Cmd+,` | + +### AI + +| 操作 | 快捷键 | 说明 | +|------|--------|------| +| 切换 AI 聊天 | `Cmd+Shift+L` | 打开或关闭 AI 聊天面板 | +| AI 解释 | `Cmd+L` | 将选中的 SQL(或当前查询)发送给 AI 解释 | +| AI 优化 | `Cmd+Option+L` | 将选中的 SQL(或当前查询)发送给 AI 优化 | + +## Vim 模式键绑定 + +启用 Vim 模式后(**Settings** > **Editor** > **Editing** > **Vim mode**),SQL 编辑器使用模态键绑定。工具栏中会出现模式指示标记。 + +### 模式 + +| 按键 | 操作 | +|------|------| +| `Escape` | 返回 Normal 模式 | +| `i` / `I` | 在光标前插入 / 在行首插入 | +| `a` / `A` | 在光标后追加 / 在行尾追加 | +| `o` / `O` | 在下方新开一行 / 在上方新开一行 | +| `v` | Visual 模式(按字符) | +| `V` | Visual Line 模式(按行) | +| `:` | 命令行模式 | + +### 导航(Normal 模式) + +| 按键 | 操作 | +|------|------| +| `h` / `j` / `k` / `l` | 左 / 下 / 上 / 右 | +| `w` / `b` / `e` | 下一个单词 / 上一个单词 / 单词末尾 | +| `0` / `$` | 行首 / 行尾 | +| `^` / `_` | 行首非空字符 | +| `gg` / `G` | 首行 / 末行 | + +### 操作符(Normal 模式) + +| 按键 | 操作 | +|------|------| +| `dd` | 删除行 | +| `yy` | 复制行 | +| `cc` | 更改行 | +| `x` | 删除字符 | +| `p` / `P` | 在光标后粘贴 / 在光标前粘贴 | +| `d` + 移动 | 按移动范围删除 | +| `y` + 移动 | 按移动范围复制 | +| `c` + 移动 | 按移动范围更改 | + +### Visual 模式 + +| 按键 | 操作 | +|------|------| +| `d` | 删除选区 | +| `y` | 复制选区 | +| `c` | 更改选区 | + +### 命令行模式 + +| 命令 | 操作 | +|------|------| +| `:w` | 执行查询(`Cmd+Enter`) | +| `:q` | 关闭标签页 | + +### 数字前缀 + +在移动和操作符前加数字:`3j`(向下 3 行)、`2dd`(删除 2 行)、`5x`(删除 5 个字符)。 + + +Vim 模式键绑定仅在 SQL 编辑器中生效。不影响数据网格或其他面板。`Cmd+Enter` 等标准快捷键在所有模式下均有效。 + + +## 筛选 + +| 操作 | 快捷键 | +|------|--------| +| 切换筛选面板 / 快速搜索 | `Cmd+F` | +| 快速搜索 | 在搜索框中输入 | +| 应用筛选条件 | `Enter`(在筛选输入框中) | + +## 表结构 + +### 导航 + +| 操作 | 快捷键 | +|------|--------| +| 列标签页 | `Cmd+1` | +| 索引标签页 | `Cmd+2` | +| 外键标签页 | `Cmd+3` | +| DDL 标签页 | `Cmd+4` | + +## 导入/导出 + +| 操作 | 快捷键 | +|------|--------| +| 导出数据 | `Cmd+Shift+E` | +| 导入数据 | `Cmd+Shift+I` | + +## 全局快捷键 + +### 标准 macOS + +| 操作 | 快捷键 | +|------|--------| +| 退出应用 | `Cmd+Q` | +| 隐藏应用 | `Cmd+H` | +| 隐藏其他 | `Cmd+Option+H` | +| 显示全部 | - | +| 偏好设置 | `Cmd+,` | + +### 帮助 + +| 操作 | 快捷键 | +|------|--------| +| 搜索文档 | `Cmd+?` | + +## 自定义快捷键 + +大部分菜单快捷键可在 **Settings** > **Keyboard** 中重新绑定。 + +{/* Screenshot: Keyboard settings */} + + 键盘设置 + 键盘设置 + + +### 重新绑定快捷键 + +1. 打开 **Settings**(`Cmd+,`)并选择 **Keyboard** 标签页 +2. 找到操作(使用搜索框筛选) +3. 点击操作旁的快捷键字段 +4. 按下新的按键组合 +5. 快捷键立即在菜单栏中更新 + +### 清除快捷键 + +1. 点击操作的快捷键字段 +2. 按 `Delete` 或 `Backspace` +3. 快捷键被移除 + +### 冲突检测 + +如果你分配了一个已在使用的快捷键,TablePro 会显示确认对话框: + +- **Cancel** — 保留现有分配 +- **Reassign** — 将快捷键移到新操作(清除之前操作的快捷键) + + +系统保留的快捷键(`Cmd+Q`、`Cmd+H`、`Cmd+M`、`Cmd+,`)无法重新分配。尝试时 TablePro 会发出警告。 + + +### 恢复默认值 + +点击键盘设置底部的 **Reset to Defaults** 将所有快捷键恢复为原始值。 + +### 快捷键分类 + +| 分类 | 示例 | +|------|------| +| **文件** | 新建连接、新建查询标签页、关闭标签页、保存更改 | +| **编辑** | 复制为 CSV、复制为 JSON、导出、导入 | +| **视图** | 切换侧边栏、切换单元格检查器、查询历史 | +| **标签页** | 下一个标签页、上一个标签页 | +| **AI** | 切换 AI 聊天、AI 解释、AI 优化 | + + +标签页切换快捷键(`Cmd+1` 到 `Cmd+9`)遵循标准 macOS 惯例,不可自定义。 + + +## 效率提升技巧 + +### 最常用快捷键 + +从这五个开始: + +1. `Cmd+Enter` - 执行查询 +2. `Cmd+N` - 新建连接 +3. `Cmd+Y` - 查询历史 +4. `Cmd+F` - 查找 +5. `Cmd+C` / `Cmd+V` - 复制/粘贴 + +### 工作流技巧 + +**快速查询迭代**: +1. 在编辑器中编写查询 +2. `Cmd+Enter` 运行 +3. 修改 +4. `Cmd+Enter` 再次运行 + +**浏览数据**: +1. 点击侧边栏中的表 +2. 在网格中查看数据 +3. `Cmd+Enter` 执行自定义查询 +4. `Cmd+Y` 查找之前的查询 + +**编辑数据**: +1. 用方向键导航 +2. `Enter` 编辑单元格 +3. 输入新值 +4. `Tab` 移到下一个单元格 +5. `Cmd+S` 保存所有更改 + +### 记忆技巧 + +**按上下文分组**: +- 所有 `Cmd+` 快捷键是主要操作 +- 加 `Shift` 是变体(如 `Cmd+Z` 撤销 -> `Cmd+Shift+Z` 重做) +- 加 `Option` 是替代操作 + +**常见模式**: +- `Cmd+[字母]` - 常用操作(N=新建、W=关闭、Q=退出) +- `Cmd+Shift+[字母]` - 常用操作的变体 +- 方向键 - 导航 +- `Tab` / `Shift+Tab` - 下一个/上一个 + +## 速查表 + +``` +=== SQL 编辑器 === +Cmd+Enter 执行查询 +Opt+Cmd+E 解释查询 +Opt+Cmd+F 格式化 SQL +Cmd+F 查找 +Cmd+Z 撤销 +Cmd+Shift+Z 重做 + +=== 数据网格 === +方向键 导航单元格 +Enter 编辑单元格 +Tab 下一个单元格 +Cmd+C 复制 +Delete 删除行 + +=== 数据变更 === +Cmd+S 提交更改 +Cmd+Z 撤销 +Cmd+Shift+Z 重做 +Cmd+Shift+P 预览 SQL + +=== 标签页 === +Cmd+T 新建查询标签页 +Cmd+W 关闭标签页 +Cmd+1-9 切换到标签页 N +Cmd+Shift+[ 上一个标签页 +Cmd+Shift+] 下一个标签页 + +=== Vim 模式(启用时) === +Escape Normal 模式 +i/a/o 进入 Insert 模式 +v/V Visual / Visual Line +h/j/k/l 左/下/上/右 +w/b/e 单词移动 +^/_ 行首非空字符 +dd/yy/cc 删除/复制/更改行 +:w 执行查询 +:q 关闭标签页 + +=== 应用程序 === +Cmd+N 新建连接 +Cmd+Y 查询历史 +Cmd+Shift+L 切换 AI 聊天 +Cmd+L AI 解释 +Cmd+Opt+L AI 优化 +Cmd+, 设置 +Cmd+W 关闭窗口 +Cmd+Q 退出 +``` + +## 无障碍 + +### VoiceOver 支持 + +TablePro 支持 macOS VoiceOver: + +- 使用 `Control+Option+Arrow` 键导航 +- 使用 `Control+Option+Space` 交互 +- 所有 UI 元素都有标签 + +### 纯键盘操作 + +TablePro 完全支持无鼠标使用: + +1. `Tab` 在主要 UI 区域间移动 +2. 方向键在区域内导航 +3. `Enter` 或 `Space` 激活控件 +4. `Escape` 关闭对话框/菜单 + +## 故障排除 + +### 快捷键不起作用 + +1. **检查焦点**:确保正确的面板获得了焦点 +2. **检查冲突**:其他应用可能在捕获该快捷键 +3. **检查修饰键**:确认按下了正确的修饰键 + +### 系统级冲突 + +如果快捷键不起作用,检查**系统设置** > **键盘** > **键盘快捷键**中是否与以下功能冲突: + +- 调度中心 +- Spotlight +- 输入法 +- App 快捷键 + +## 下一步 + + + + 练习编辑器快捷键 + + + 掌握网格导航 + + + 使用历史快捷键 + + + 配置 TablePro + + diff --git a/docs/zh/features/query-history.mdx b/docs/zh/features/query-history.mdx new file mode 100644 index 00000000..fc9e2764 --- /dev/null +++ b/docs/zh/features/query-history.mdx @@ -0,0 +1,369 @@ +--- +title: 查询历史 +description: 每条执行的查询都保存在本地 SQLite 数据库中,支持 FTS5 全文搜索 +--- + +# 查询历史 + +每条执行的查询都会自动保存到本地 SQLite 数据库中。支持全文搜索、按连接或时间范围筛选,以及重新运行历史查询。历史记录跨会话持久化。 + +{/* Screenshot: Query history panel showing list of past queries */} + + 查询历史 + 查询历史 + + +## 访问历史 + +### 历史面板 + +打开历史面板: + +1. 点击 **View** > **Query History** +2. 或按 `Cmd+Y` +3. 或点击工具栏中的 **History** 图标 + +### 侧边栏中的历史 + +最近执行的查询也会出现在侧边栏的活跃连接下方。 + +## 历史功能 + +### 查询列表 + +历史面板显示: + +| 列 | 说明 | +|-----|------| +| **查询** | SQL 文本(过长时截断) | +| **时间** | 查询执行时间 | +| **耗时** | 执行时长 | +| **状态** | 成功或失败 | +| **数据库** | 使用的数据库/连接 | + +### 排序 + +可按以下方式排序历史: + +- **时间**:最近的在前(默认) +- **耗时**:最慢的在前 +- **查询文本**:按字母排序 + +点击列标题更改排序方式。 + +### 筛选 + +按以下条件筛选查询: + +- **连接**:只显示特定连接的查询 +- **状态**:只显示成功或失败的查询 +- **时间范围**:今天、本周、本月、全部 + +{/* Screenshot: History panel with filter controls */} + + 带筛选控件的历史面板 + 带筛选控件的历史面板 + + +## 搜索历史 + +### 全文搜索 + +在搜索框中输入以查找包含特定文本的查询: + +``` +SELECT users -- 查找包含 "SELECT" 和 "users" 的所有查询 +``` + +{/* Screenshot: Search results in history */} + + 历史搜索 + 历史搜索 + + +### 搜索技巧 + +- 搜索不区分大小写 +- 支持部分匹配 +- 搜索范围覆盖完整查询文本 + +**搜索示例**: + +| 搜索词 | 查找结果 | +|--------|----------| +| `users` | 提到 "users" 的查询 | +| `JOIN orders` | 连接 orders 表的查询 | +| `WHERE created` | 按 created 筛选的查询 | +| `UPDATE users SET` | 对 users 表的 UPDATE 语句 | + +## 使用历史 + +### 重新运行查询 + +要重新运行历史查询: + +1. 在历史列表中找到该查询 +2. 双击查询 +3. 它会加载到 SQL 编辑器中 +4. 按 `Cmd+Enter` 执行 + +或右键点击选择 **Run Query**。 + +### 复制查询 + +要复制查询: + +1. 在列表中选中查询 +2. 右键 > **Copy Query** +3. 或按 `Cmd+C` + +完整的查询文本会复制到剪贴板。 + +{/* Screenshot: Query history context menu */} + + 查询历史右键菜单 + 查询历史右键菜单 + + +### 修改后运行 + +要修改历史查询: + +1. 双击加载到编辑器 +2. 进行修改 +3. 执行修改后的查询 + +原始历史记录保持不变。修改后的查询会创建新的历史条目。 + +## 历史存储 + +### 存储位置 + +查询历史存储在: + +``` +~/Library/Application Support/TablePro/query_history.db +``` + +该 SQLite 数据库包含: + +- 查询文本 +- 执行时间戳 +- 执行时长 +- 连接/数据库信息 +- 成功/失败状态 +- 错误信息(如果失败) + +### 历史保留策略 + +在 **Settings** > **History** 中配置保留策略: + +| 设置 | 默认值 | 说明 | +|------|--------|------| +| **最大条目数** | 10,000 | 最多存储的查询数 | +| **最大天数** | 90 | 删除超过此天数的查询 | +| **自动清理** | 开 | 自动删除旧条目 | + + +将**最大条目数**设为 0 表示不限制历史数量(历史量很大时可能降低搜索速度)。 + + +### 清除历史 + +要清除所有历史: + +1. 打开 **Settings** > **History** +2. 点击 **Clear All History** +3. 确认操作 + + +清除历史不可撤销。请考虑先导出重要查询。 + + +要清除特定连接的历史: + +1. 右键点击侧边栏中的连接 +2. 选择 **Clear History** + +## 查询详情 + +### 查看完整查询 + +对于长查询,点击展开查看完整文本: + +{/* Screenshot: Expanded query detail view */} + + 查询详情 + 查询详情 + + +### 执行详情 + +每条历史记录包含: + +| 详情 | 说明 | +|------|------| +| **开始时间** | 执行开始的时间戳 | +| **耗时** | 查询执行时长 | +| **影响行数** | 返回/修改的行数 | +| **错误** | 查询失败时的错误信息 | + +### 失败的查询 + +失败的查询显示: + +- 错误信息 +- 导致错误的查询 +- 失败时间戳 + +这对调试很有用: + +1. 找到失败的查询 +2. 阅读错误信息 +3. 加载到编辑器 +4. 修复并重新运行 + +{/* Screenshot: Failed query entry with error message */} + + 带错误信息的失败查询条目 + 带错误信息的失败查询条目 + + +## 最佳实践 + +### 为查询添加注释 + +为重要查询添加注释以便搜索: + +```sql +-- Monthly revenue report 2024 +SELECT + DATE_FORMAT(created_at, '%Y-%m') as month, + SUM(total) as revenue +FROM orders +WHERE created_at >= '2024-01-01' +GROUP BY month; +``` + +之后搜索 "Monthly revenue report" 即可找到。 + +### 使用注释组织 + +使用一致的注释模式: + +```sql +-- [REPORT] User growth +-- [DEBUG] Performance issue +-- [ADMIN] Data cleanup +-- [TEMP] Testing query +``` + +### 导出重要查询 + +对于需要永久保留的查询: + +1. 在历史中找到该查询 +2. 复制到 SQL 文件 +3. 保存到版本控制中 + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 打开历史 | `Cmd+Y` | +| 搜索历史 | `Cmd+F`(历史面板打开时) | +| 加载选中的查询 | `Enter` 或双击 | +| 复制查询 | `Cmd+C` | + +## 故障排除 + +### 历史未保存 + +1. 检查磁盘空间 — 历史需要存储空间 +2. 验证 TablePro 有写入权限 +3. 检查设置中是否禁用了历史 + +### 历史搜索慢 + +对于非常大的历史记录: + +1. 在设置中减少**最大条目数** +2. 清除旧历史 +3. 使用更具体的搜索词 + +### 找不到旧查询 + +检查**最大天数**设置 — 超过此限制的查询会被自动删除。 + +要防止自动删除: +1. 打开 **Settings** > **History** +2. 将**最大天数**设为 0(不限制) + +### 重复条目 + +每次执行都会创建新的历史条目,即使查询完全相同。这是有意为之的:它记录每次查询的运行时间。 + +## 下一步 + + + + 编写和执行查询 + + + 查看查询结果 + + + 配置历史选项 + + + 了解所有快捷键 + + diff --git a/docs/zh/features/safe-mode.mdx b/docs/zh/features/safe-mode.mdx new file mode 100644 index 00000000..4852e324 --- /dev/null +++ b/docs/zh/features/safe-mode.mdx @@ -0,0 +1,91 @@ +--- +title: 安全模式 +description: 按连接设置查询执行控制 - 从无限制到完全只读锁定 +--- + +# 安全模式 + +安全模式是一个按连接的设置,控制 TablePro 如何处理查询执行。每个连接可以有自己的级别,从无限制访问到完全写入保护。 + +在创建或编辑连接时,在连接表单中设置安全模式级别。 + +## 级别 + +TablePro 提供 6 个递进的安全模式级别: + +| 级别 | 图标 | 写入查询 | 读取查询 | 认证 | +|------|------|----------|----------|------| +| **静默** | `lock.open` | 立即执行 | 立即执行 | 无 | +| **提醒** | `exclamationmark.triangle` | 确认对话框 | 立即执行 | 无 | +| **提醒(完整)** | `exclamationmark.triangle.fill` | 确认对话框 | 确认对话框 | 无 | +| **安全模式** | `lock.shield` | 确认 + Touch ID | 立即执行 | Touch ID / 密码 | +| **安全模式(完整)** | `lock.shield.fill` | 确认 + Touch ID | 确认 + Touch ID | Touch ID / 密码 | +| **只读** | `lock.fill` | 完全阻止 | 立即执行 | 无 | + +新建连接默认为**静默**。 + +## 工作原理 + +### 静默 + +无限制。查询立即执行。TablePro 仍会对 DROP、TRUNCATE 和不带 WHERE 的 DELETE 语句显示内置的危险查询警告。 + +### 提醒 + +执行写入查询(INSERT、UPDATE、DELETE、DROP、TRUNCATE、ALTER 等)前出现确认对话框。对话框显示将要执行的 SQL 预览。读取查询无需确认直接运行。 + +### 提醒(完整) + +与"提醒"相同,但确认对话框对**所有**查询都会出现,包括 SELECT 语句。当你想在执行前审查每条查询时很有用。 + +### 安全模式 + +类似"提醒",但确认对话框后还需要通过 Touch ID 或 macOS 密码认证。Touch ID 不可用时回退到系统密码。 + +### 安全模式(完整) + +结合"提醒(完整)"和"安全模式":每条查询都需要确认对话框和 Touch ID/密码认证。 + +### 只读 + +所有写入操作被阻止。界面禁用以下功能: + +- 行内单元格编辑 +- 新增、删除和复制行 +- 清空和删除表操作 +- 导入功能 + +读取查询(SELECT)正常执行。 + +## MongoDB 和 Redis + +MongoDB 和 Redis 不使用 SQL,因此 TablePro 无法通过解析查询文本区分读写操作。这两种数据库类型的所有操作在安全模式中都被视为写入操作。这意味着: + +- **提醒/安全模式**:每条查询都触发确认对话框 +- **只读**:所有操作被阻止 + +## 工具栏标记 + +当前安全模式级别以标记形式显示在工具栏中。点击它可以在不打开连接表单的情况下更改活跃连接的级别。 + +## 安全模式的应用范围 + +安全模式在以下位置执行检查: + +- **查询执行**:从 SQL 编辑器运行查询 +- **保存更改**:提交单元格编辑、行插入和删除 +- **表操作**:从侧边栏清空或删除表 +- **侧边栏更改**:重命名表、通过侧边栏修改结构 + +`silent` 级别保留了现有的危险查询警告(DROP/TRUNCATE/不带 WHERE 的 DELETE)作为安全网。 + +## 相关页面 + + + + 编辑如何被追踪和提交 + + + 清空、删除和其他表级操作 + + diff --git a/docs/zh/features/sql-editor.mdx b/docs/zh/features/sql-editor.mdx new file mode 100644 index 00000000..2521d0de --- /dev/null +++ b/docs/zh/features/sql-editor.mdx @@ -0,0 +1,609 @@ +--- +title: SQL 编辑器 +description: tree-sitter 语法高亮、多语句执行、Vim 模式及内置 SQL 格式化 +--- + +# SQL 编辑器 + +借助 tree-sitter 驱动的语法高亮、感知数据库结构的自动补全以及多语句执行功能,在同一个编辑器中编写和运行 SQL。 + +{/* Screenshot: SQL editor with syntax highlighting and autocomplete popup */} + + SQL 编辑器 + SQL 编辑器 + + +## 编辑器功能 + +### 语法高亮 + +实时语法高亮涵盖: + +- **关键字**:`SELECT`、`FROM`、`WHERE`、`JOIN` 等(粉色) +- **字符串**:单引号和双引号字符串(绿色) +- **数字**:数字字面量(蓝色) +- **注释**:单行注释(`--`)和多行注释(`/* */`)(灰色) +- **函数**:内置 SQL 函数 +- **标识符**:表名和列名 + +### 行号 + +行号默认开启,方便你: + +- 将错误信息定位到具体行 +- 在大型查询中快速导航 +- 在交流时引用代码位置 + + +在 **Settings** > **Editor** > **Show Line Numbers** 中切换行号显示。 + + +### 当前行高亮 + +当前行会显示淡色高亮,让你在长查询中始终清楚光标所在位置。 + +## 编写查询 + +### 单条查询 + +编写并执行单条查询: + +```sql +SELECT * FROM users WHERE active = true; +``` + +按 `Cmd+Enter` 执行。 + +### 多条查询 + +用分号分隔多条查询: + +```sql +SELECT * FROM users LIMIT 10; +SELECT COUNT(*) FROM orders; +SELECT name, email FROM customers WHERE country = 'US'; +``` + +将光标放在任意语句中,按 `Cmd+Enter` 即可单独执行该条。 + +### 选中执行 + +选中文本后按 `Cmd+Enter`,仅运行选中部分。 + +如果选中内容包含**多条语句**(以分号分隔),它们会在一个事务中依次执行: + +- 语句按顺序逐条执行 +- 如果任一语句失败,执行停止并回滚所有变更 +- 错误信息会标明是哪条语句失败(例如 "Statement 3/5 failed: ...") +- 最后一个 `SELECT` 的结果显示在数据网格中 +- 每条语句都会单独记录到查询历史 + +适合运行 SQL 转储文件、数据迁移或一批相关语句: + +```sql +DROP TABLE IF EXISTS users; +CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100)); +INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob'); +SELECT * FROM users; +``` + +{/* Screenshot: Multiple queries in editor with execution results */} + + 多语句执行 + 多语句执行 + + +## 自动补全 + +感知数据库结构的 SQL 自动补全,能根据查询上下文进行调整。 + +### 触发自动补全 + +输入时自动补全会自动出现。你也可以: + +- 开始输入关键字、表名或列名 +- 按 `Escape` 关闭弹出窗口 +- 用方向键浏览建议 +- 按 `Enter` 或 `Tab` 接受建议 + +{/* Screenshot: Autocomplete popup showing table and column suggestions */} + + 自动补全 + 自动补全 + + +### 建议内容 + +| 上下文 | 建议内容 | +|---------|----------| +| `SELECT` 之后 | 列名、`*`、函数 | +| `FROM` 之后 | 表名、schema 名 | +| `JOIN` 之后 | 表名 | +| `WHERE` 之后 | 已选表的列名 | +| `.`(点号)之后 | 指定表的列 | +| 语句开头 | SQL 关键字 | + +### 感知 Schema 的补全 + +自动补全能解析表别名并显示正确的列: + +```sql +SELECT u. -- 显示别名为 'u' 的 'users' 表的列 +FROM users u +JOIN orders o ON u.id = o. -- 显示 'orders' 表的列 +``` + +### SQL 关键字 + +关键字建议基于上下文: + +- `SELECT` 之后:`DISTINCT`、`TOP`、`ALL` +- `FROM` 之后:`JOIN`、`LEFT JOIN`、`INNER JOIN`、`WHERE` +- `WHERE` 之后:`AND`、`OR`、`NOT`、`IN`、`LIKE`、`BETWEEN` + +## 查询执行 + +### 运行查询 + +| 操作 | 快捷键 | 说明 | +|------|--------|------| +| 执行查询 | `Cmd+Enter` | 运行光标所在的查询,或运行所有选中的语句 | +| 解释查询 | `Option+Cmd+E` | 显示光标所在查询的执行计划 | +| 格式化查询 | `Option+Cmd+F` | 格式化当前查询以提高可读性 | + +### 查询结果 + +结果显示在编辑器下方的数据网格中: + +- 显示行数和执行时间 +- 大数据集会自动分页 +- 点击列标题可排序 + +### 查询解释 + +查看查询的执行计划,发现缺失的索引或低效的连接。 + +要查看查询执行计划: + +- 点击编辑器工具栏中的 **Explain** 按钮,或 +- 按 `Option+Cmd+E`,或 +- 通过菜单 **Query** > **Explain Query** + +TablePro 会自动为你的数据库使用正确的语法: + +| 数据库 | 使用的语法 | +|--------|-----------| +| MySQL / MariaDB | `EXPLAIN ` | +| PostgreSQL | `EXPLAIN ` | +| SQLite | `EXPLAIN QUERY PLAN ` | + +执行计划在数据网格中展示索引使用情况、连接策略和预估行数。 + + +在执行高成本查询前运行 Explain,验证其是否使用了预期的索引和连接策略。 + + +{/* Screenshot: EXPLAIN output displayed in data grid */} + + EXPLAIN 查询执行计划 + EXPLAIN 查询执行计划 + + +## SQL 格式化 + +内置 SQL 格式化器,可将查询重新组织以提高可读性。支持方言感知:会根据 MySQL、PostgreSQL 或 SQLite 语法调整输出。 + +### 格式化查询 + +要格式化当前查询: + +- 按 `Option+Cmd+F`,或 +- 点击编辑器工具栏中的 **Format** 按钮,或 +- 通过菜单 **Query** > **Format Query** + +格式化器会进行以下转换: + +| 转换 | 说明 | +|------|------| +| **关键字大写** | SQL 关键字转为大写(`select` 变为 `SELECT`) | +| **智能缩进** | 子句按逻辑层级缩进,间距一致 | +| **换行** | 每个主要子句(`SELECT`、`FROM`、`WHERE`、`JOIN` 等)另起一行 | +| **保留光标** | 格式化后光标位置保持不变 | +| **保留注释** | 单行注释(`--`)和多行注释(`/* */`)完整保留 | +| **保留字符串** | 字符串字面量不会被修改 | + +### 方言感知格式化 + +格式化器检测当前连接的数据库类型,并应用特定方言规则: + +| 数据库 | 格式化行为 | +|--------|-----------| +| MySQL / MariaDB | 保留反引号标识符,处理 MySQL 专有语法 | +| PostgreSQL | 保留双引号标识符,处理 PostgreSQL 专有语法 | +| SQLite | 处理 SQLite 专有关键字和语法 | + +### 格式化前后对比 + +**格式化前**(未格式化): + +```sql +select u.id,u.name,u.email,count(o.id) as order_count from users u left join orders o on u.id=o.user_id where u.created_at>'2024-01-01' and u.status='active' group by u.id,u.name,u.email having count(o.id)>5 order by order_count desc limit 100; +``` + +**格式化后**(`Option+Cmd+F`): + +```sql +SELECT + u.id, + u.name, + u.email, + COUNT(o.id) AS order_count +FROM users u +LEFT JOIN orders o ON u.id = o.user_id +WHERE u.created_at > '2024-01-01' + AND u.status = 'active' +GROUP BY u.id, u.name, u.email +HAVING COUNT(o.id) > 5 +ORDER BY order_count DESC +LIMIT 100; +``` + + +在分享给队友或保存为模板前格式化查询,保持 SQL 的一致性和可读性。 + + +{/* Screenshot: SQL query before and after formatting */} + + SQL 查询格式化前后对比 + SQL 查询格式化前后对比 + + +### 错误处理 + +查询失败时: + +1. 错误信息显示在编辑器下方 +2. 如果错误指向具体行,对应行号会高亮 +3. 阅读错误信息了解问题详情 + +{/* Screenshot: Query error message display */} + + 查询错误 + 查询错误 + + +## Vim 模式 + +可选的 Vim 键绑定,支持模态编辑。完整支持 Normal、Insert、Visual 和命令行模式。 + +### 启用 Vim 模式 + +在 **Settings** > **Editor** > **Editing** > **Vim mode** 中切换。启用后编辑器工具栏会显示模式指示标记。 + +### 模式 + +| 模式 | 说明 | +|------|------| +| **Normal** | 默认模式,用于导航和命令。按 `Escape` 返回此模式。 | +| **Insert** | 文本输入模式,行为与普通编辑器相同。 | +| **Visual** | 按字符选择模式。 | +| **Visual Line** | 按行选择模式。 | +| **命令行** | Ex 命令(`:w`、`:q` 等)。 | + +### 移动 + +| 按键 | 操作 | +|------|------| +| `h` / `j` / `k` / `l` | 左 / 下 / 上 / 右 | +| `w` / `b` / `e` | 下一个单词 / 上一个单词 / 单词末尾 | +| `0` / `$` | 行首 / 行尾 | +| `gg` / `G` | 首行 / 末行 | + +### 操作符 + +| 按键 | 操作 | +|------|------| +| `dd` | 删除行 | +| `yy` | 复制行 | +| `cc` | 更改行 | +| `x` | 删除字符 | +| `p` / `P` | 在后面粘贴 / 在前面粘贴 | +| `d` + 移动 | 按移动范围删除(如 `dw`、`d$`) | +| `y` + 移动 | 按移动范围复制(如 `yw`、`y0`) | +| `c` + 移动 | 按移动范围更改(如 `cw`、`c$`) | + +### 进入 Insert 模式 + +| 按键 | 操作 | +|------|------| +| `i` / `I` | 在光标前插入 / 在行首插入 | +| `a` / `A` | 在光标后追加 / 在行尾追加 | +| `o` / `O` | 在下方新开一行 / 在上方新开一行 | + +### Visual 模式 + +按 `v` 进入按字符选择,按 `V` 进入按行选择。使用移动键扩展选区,然后应用操作符: + +- `d` — 删除选区 +- `y` — 复制选区 +- `c` — 更改选区 + +### 命令行模式 + +在 Normal 模式下按 `:` 进入命令行模式: + +| 命令 | 操作 | +|------|------| +| `:w` | 执行当前查询(等同于 `Cmd+Enter`) | +| `:q` | 关闭当前标签页 | + +### 数字前缀 + +大多数移动和操作符支持数字前缀:`3j` 向下移动 3 行,`2dd` 删除 2 行,`5x` 删除 5 个字符。 + +### Escape 键协调 + +启用 Vim 模式后,`Escape` 返回 Normal 模式。如果 AI 自动补全建议可见,第一次 `Escape` 关闭建议,第二次 `Escape` 才返回 Normal 模式。 + + +工具栏中的模式指示标记会显示当前 Vim 模式(NORMAL、INSERT、VISUAL),让你始终知道处于哪种模式。 + + +## 编辑器设置 + +在 **Settings** > **Editor** 中自定义编辑器: + +### 字体设置 + +| 设置 | 选项 | 默认值 | +|------|------|--------| +| **字体** | System Mono、SF Mono、Menlo、Monaco、Courier New | System Mono | +| **字号** | 11-18 pt | 13 pt | + +### 显示设置 + +| 设置 | 说明 | 默认值 | +|------|------|--------| +| **显示行号** | 显示行号 | 开 | +| **高亮当前行** | 当前行淡色高亮 | 开 | +| **自动换行** | 长行自动换行 | 关 | + +### 编辑设置 + +| 设置 | 说明 | 默认值 | +|------|------|--------| +| **Vim 模式** | 启用 Vim 键绑定(Normal/Insert/Visual 模式) | 关 | + +### 缩进设置 + +| 设置 | 选项 | 默认值 | +|------|------|--------| +| **Tab 宽度** | 2、4、8 个空格 | 4 | +| **自动缩进** | 自动缩进 | 开 | + +{/* Screenshot: Editor settings panel in Preferences */} + + 偏好设置中的编辑器设置 + 偏好设置中的编辑器设置 + + +## 技巧与窍门 + +### AI 辅助 + +SQL 编辑器与 TablePro 的 AI 聊天集成,辅助编写和调试查询: + +- **AI 解释**(`Cmd+L`)— 获取查询的详细解释 +- **AI 优化**(`Cmd+Option+L`)— 获取性能优化建议 +- **AI 修复** — 查询失败时,在错误对话框中点击"Ask AI to Fix" + +详情参见 [AI 聊天](/zh/features/ai-chat)。 + +### 使用注释 + +为查询添加注释: + +```sql +-- Get active users with recent orders +SELECT u.name, COUNT(o.id) as orders +FROM users u +JOIN orders o ON u.id = o.user_id +WHERE u.active = true + AND o.created_at > CURRENT_DATE - INTERVAL '30 days' +GROUP BY u.name; + +/* + * Multi-line comment + * Useful for longer explanations + */ +``` + +### 快速查看表结构 + +快速检查表的结构和数据: + +```sql +-- View table structure (MySQL) +DESCRIBE users; + +-- View table structure (PostgreSQL) +\d users + +-- Sample data +SELECT * FROM users LIMIT 10; + +-- Row count +SELECT COUNT(*) FROM users; +``` + +### 使用别名 + +表别名能让查询更简洁: + +```sql +-- Without aliases (verbose) +SELECT users.name, orders.total +FROM users +JOIN orders ON users.id = orders.user_id; + +-- With aliases (cleaner) +SELECT u.name, o.total +FROM users u +JOIN orders o ON u.id = o.user_id; +``` + +## 打开 SQL 文件 + +TablePro 可直接从 Finder 打开 `.sql` 文件。 + +### 从 Finder 打开 + +两种打开 `.sql` 文件的方式: + +- **双击** Finder 中的 `.sql` 文件(需将 TablePro 设为默认应用) +- **右键点击** `.sql` 文件 > **打开方式** > **TablePro** + +### 连接行为 + +| 状态 | 行为 | +|------|------| +| **已连接**数据库 | 文件立即在新编辑器标签页中打开 | +| **未连接** | 文件排入队列,连接数据库后自动打开 | + +### 多文件 + +同时打开多个 `.sql` 文件时,每个文件会创建一个单独的标签页。 + + +文件内容会被加载到编辑器标签页中。在编辑器中所做的更改不会修改磁盘上的原始 `.sql` 文件。 + + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 执行查询 | `Cmd+Enter` | +| 解释查询 | `Option+Cmd+E` | +| 格式化查询 | `Option+Cmd+F` | +| 全选 | `Cmd+A` | +| 剪切 | `Cmd+X` | +| 复制 | `Cmd+C` | +| 粘贴 | `Cmd+V` | +| 撤销 | `Cmd+Z` | +| 重做 | `Cmd+Shift+Z` | +| 查找 | `Cmd+F` | +| 查找和替换 | `Cmd+Option+F` | + +## 最佳实践 + +### 始终使用 LIMIT + +浏览数据时,始终添加 `LIMIT` 以避免加载数百万行: + +```sql +SELECT * FROM large_table LIMIT 100; +``` + +### 先用 SELECT 测试 DELETE/UPDATE + +执行破坏性查询前,先用 SELECT 验证: + +```sql +-- First, verify what will be affected +SELECT * FROM users WHERE last_login < '2023-01-01'; + +-- Then run the actual delete +DELETE FROM users WHERE last_login < '2023-01-01'; +``` + +### 使用事务保障安全 + +用事务包裹危险操作: + +```sql +BEGIN; + +DELETE FROM important_table WHERE condition; + +-- Verify the results +SELECT COUNT(*) FROM important_table; + +-- If correct: +COMMIT; + +-- If wrong: +ROLLBACK; +``` + +## 下一步 + + + + 了解更多自动补全功能 + + + 查看和编辑查询结果 + + + 访问历史查询 + + + 所有键盘快捷键 + + diff --git a/docs/zh/features/table-operations.mdx b/docs/zh/features/table-operations.mdx new file mode 100644 index 00000000..810cda95 --- /dev/null +++ b/docs/zh/features/table-operations.mdx @@ -0,0 +1,353 @@ +--- +title: 表操作 +description: 删除表、清空表、复制表、创建视图,以及从侧边栏切换数据库 +--- + +# 表操作 + +右键点击侧边栏中的表,可以删除、清空或复制表。创建和管理视图。在同一连接上切换数据库。 + +## 表操作 + +右键点击侧边栏中的表以访问以下操作。 + +### 删除表 + +永久删除一张表及其所有数据。 + +1. 右键点击表(或选择多张表) +2. 选择 **Delete** +3. 在确认对话框中配置选项 +4. 点击 **OK** 执行 + +{/* Screenshot: Drop table confirmation dialog */} + + 删除表对话框 + 删除表对话框 + + +**各数据库的选项:** + + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 临时禁用外键验证 | + | **级联** | 不支持 | + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 不支持(请使用 CASCADE) | + | **级联** | 删除所有依赖对象(视图、外键) | + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 临时禁用外键验证 | + | **级联** | 不支持 | + + + + +删除表是不可逆的操作。删除前请务必备份重要数据。 + + +### 清空表 + +删除所有行但保留表结构。 + +1. 右键点击表(或选择多张表) +2. 选择 **Truncate** +3. 在确认对话框中配置选项 +4. 点击 **OK** 执行 + +**各数据库的选项:** + + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 临时禁用外键验证 | + | **级联** | TRUNCATE 不支持 | + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 不支持(请使用 CASCADE) | + | **级联** | 清空所有通过外键关联的表 | + + + | 选项 | 说明 | + |------|------| + | **忽略外键检查** | 临时禁用外键验证 | + | **级联** | 不支持 | + + + + +Truncate 比 `DELETE FROM table` 更快,因为它跳过逐行删除日志。它还会重置自增计数器。 + + +{/* Screenshot: Truncate table confirmation with options */} + + 清空表确认对话框及选项 + 清空表确认对话框及选项 + + +### 批量操作 + +选择多张表可一次性执行删除或清空操作。相同的选项应用于所有选中的表。 + +1. 按住 `Cmd` 点击选择多张表 +2. 右键选择 **Delete** 或 **Truncate** +3. 在对话框中统一配置选项 +4. 对所有选中的表执行操作 + +## 视图管理 + +数据库视图是由 SQL 查询定义的虚拟表。TablePro 在侧边栏中以独特的眼睛图标和紫色标记显示视图。 + +### 创建视图 + +通过打开带模板的 SQL 编辑器标签页来创建新视图: + +1. 右键点击侧边栏并选择 **Create New View...** +2. 或通过 **File** > **New View...** +3. 一个新的 SQL 编辑器标签页会打开,其中包含 CREATE VIEW 模板 +4. 修改视图名称和 SELECT 查询 +5. 执行查询以创建视图 + +模板会根据你的数据库类型自动适配: + + + + ```sql + CREATE VIEW view_name AS + SELECT column1, column2 + FROM table_name + WHERE condition; + ``` + + + ```sql + CREATE OR REPLACE VIEW view_name AS + SELECT column1, column2 + FROM table_name + WHERE condition; + ``` + + + ```sql + CREATE VIEW IF NOT EXISTS view_name AS + SELECT column1, column2 + FROM table_name + WHERE condition; + ``` + + + +{/* Screenshot: Create View with SQL template */} + + 使用 SQL 模板创建视图 + 使用 SQL 模板创建视图 + + +### 编辑视图定义 + +修改现有视图的 SQL 定义: + +1. 右键点击侧边栏中的视图 +2. 选择 **Edit View Definition** +3. 当前视图定义在新的 SQL 编辑器标签页中打开 +4. 修改查询并执行以更新视图 + + +MySQL/MariaDB 使用 `ALTER VIEW` 修改视图。PostgreSQL 使用 `CREATE OR REPLACE VIEW`。SQLite 不支持 ALTER VIEW,需要先删除再重建视图。 + + +### 删除视图 + +从数据库中移除视图: + +1. 右键点击侧边栏中的视图 +2. 选择 **Drop View** +3. 确认删除 + + +视图不存储数据。删除视图只会移除视图定义,底层表数据不受影响。 + + +### 右键菜单差异 + +侧边栏右键菜单在视图和表之间有所不同: + +| 操作 | 表 | 视图 | +|------|-----|------| +| 查看结构 | 是 | 是 | +| 导出 | 是 | 是 | +| 导入 | 是 | 否 | +| 清空 | 是 | 否 | +| 编辑定义 | 否 | 是 | +| 删除 | 是 | 是 | + +{/* Screenshot: View-specific context menu options */} + + 视图专属的右键菜单选项 + 视图专属的右键菜单选项 + + +## 数据库操作 + +### 创建数据库 + +从界面创建新数据库(MySQL/MariaDB): + + + + 点击工具栏中的数据库名称或按 `Cmd+K` 打开数据库切换器 + + + 点击数据库切换器工具栏中的 **Create** 按钮 + + + 输入名称,选择字符集和排序规则 + + + 点击 **Create** 执行 + + + +{/* Screenshot: Create database dialog */} + + 创建数据库 + 创建数据库 + + +可用的字符集和排序规则: + +| 字符集 | 排序规则 | +|--------|----------| +| **utf8mb4** | utf8mb4_unicode_ci、utf8mb4_general_ci、utf8mb4_bin | +| **utf8** | utf8_unicode_ci、utf8_general_ci、utf8_bin | +| **latin1** | latin1_swedish_ci、latin1_general_ci、latin1_bin | +| **ascii** | ascii_general_ci、ascii_bin | + +### 数据库切换器 + +在同一连接上切换数据库: + +1. 点击工具栏中的数据库名称 +2. 浏览可用数据库及其元数据 +3. 按名称搜索筛选 +4. 双击或选中后点击 **Open** 切换 + +切换器显示最近使用的数据库以便快速访问,并支持刷新数据库列表。 + +{/* Screenshot: Database switcher with search and recent databases */} + + 带搜索和最近数据库的数据库切换器 + 带搜索和最近数据库的数据库切换器 + + +## MongoDB 集合操作 + +MongoDB 集合操作与 SQL 表操作有所不同。 + +### 创建集合 + +使用 MQL 编辑器创建 MongoDB 集合。对于需要特定选项(capped、validator)的集合: + +```javascript +db.createCollection("myCollection", { + capped: true, + size: 1048576, + max: 1000 +}) +``` + +### 删除集合 + +右键点击侧边栏中的集合并选择 **Drop Table**。这会执行 `db.collection.drop()` 并移除所有文档和索引。 + +### 显示所有集合 + +在侧边栏中选择 **Show All Tables** 以自动执行 `listCollections` 并显示当前数据库中的所有集合。 + + +MongoDB 集合不支持 **Truncate**。要删除所有文档但保留集合,请在 MQL 编辑器中使用 `db.collection.deleteMany({})`。 + + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 删除选中的表 | `Cmd+Delete` | +| 复制表名 | `Cmd+C`(在侧边栏中) | +| 导出表 | `Cmd+E`(在侧边栏中) | +| 导入数据 | `Cmd+I`(在侧边栏中) | + +## 下一步 + + + + 查看和修改现有表的 schema + + + 查看和编辑表数据 + + + 编写 DDL 和 DML 查询 + + + 导入和导出表数据 + + diff --git a/docs/zh/features/table-structure.mdx b/docs/zh/features/table-structure.mdx new file mode 100644 index 00000000..fc0c10a6 --- /dev/null +++ b/docs/zh/features/table-structure.mdx @@ -0,0 +1,559 @@ +--- +title: 表结构 +description: 浏览列定义、索引、外键和 DDL,并使用可视化结构编辑器 +--- + +# 表结构 + +浏览列定义、索引、外键以及任意表的 DDL(CREATE TABLE 语句)。通过可视化方式或 SQL 编辑表结构。 + +{/* Screenshot: Table structure view showing columns tab */} + + 表结构 + 表结构 + + +## 访问表结构 + +要查看表的结构: + + + + 在侧边栏中点击表名 + + + 点击数据网格下方的 **Structure** 标签页 + + + 在列、索引、外键和 DDL 标签页之间切换 + + + +或者右键点击表名并选择 **Show Structure**。 + +## 列标签页 + +列标签页列出所有列定义: + +{/* Screenshot: Columns tab with column list */} + + 列标签页 + 列标签页 + + +### 列信息 + +| 属性 | 说明 | +|------|------| +| **名称** | 列名 | +| **类型** | 数据类型(VARCHAR、INT 等) | +| **可空** | 是否允许 NULL 值 | +| **默认值** | 未指定时的默认值 | +| **附加属性** | 额外属性(AUTO_INCREMENT 等) | +| **键** | 主键(PRI)、外键(FOR)等 | + +### 复制为 TSV + +右键点击结构网格可将列定义复制为 TSV(Tab 分隔值)。便于粘贴到电子表格或文档工具中。 + +### 各数据库的数据类型 + + + + 常见 MySQL 数据类型: + + | 分类 | 类型 | + |------|------| + | 数值 | INT、BIGINT、DECIMAL、FLOAT、DOUBLE | + | 字符串 | VARCHAR、TEXT、CHAR、ENUM | + | 日期/时间 | DATE、DATETIME、TIMESTAMP、TIME | + | 二进制 | BLOB、BINARY、VARBINARY | + | JSON | JSON | + + + 常见 PostgreSQL 数据类型: + + | 分类 | 类型 | + |------|------| + | 数值 | INTEGER、BIGINT、NUMERIC、REAL | + | 字符串 | VARCHAR、TEXT、CHAR | + | 日期/时间 | DATE、TIMESTAMP、TIMESTAMPTZ、TIME | + | 二进制 | BYTEA | + | 特殊 | JSON、JSONB、ARRAY、UUID、INET | + + + SQLite 类型亲和性: + + | 亲和性 | 说明 | + |--------|------| + | TEXT | 字符串数据 | + | INTEGER | 有符号整数 | + | REAL | 浮点数 | + | NUMERIC | 数值或文本 | + | BLOB | 二进制数据 | + + + +## 索引标签页 + +查看表上定义的所有索引: + +{/* Screenshot: Indexes tab showing index list */} + + 索引标签页 + 索引标签页 + + +### 索引信息 + +| 属性 | 说明 | +|------|------| +| **名称** | 索引名 | +| **列** | 索引包含的列 | +| **类型** | BTREE、HASH、FULLTEXT 等 | +| **唯一** | 是否强制唯一性 | +| **主键** | 是否为主键 | + +### 索引类型 + +| 类型 | 用途 | +|------|------| +| **PRIMARY** | 主键约束 | +| **UNIQUE** | 唯一约束/索引 | +| **INDEX** | 用于性能优化的常规索引 | +| **FULLTEXT** | 全文搜索(MySQL) | +| **SPATIAL** | 地理空间数据(PostGIS) | + +## 外键标签页 + +查看外键关系: + +{/* Screenshot: Foreign keys tab */} + + 外键标签页 + 外键标签页 + + +### 外键信息 + +| 属性 | 说明 | +|------|------| +| **名称** | 约束名 | +| **列** | 本地列 | +| **引用** | 目标表和列 | +| **删除时** | 引用行被删除时的操作 | +| **更新时** | 引用行被更新时的操作 | + +### 引用操作 + +| 操作 | 说明 | +|------|------| +| **RESTRICT** | 有引用时阻止删除/更新 | +| **CASCADE** | 级联删除/更新引用行 | +| **SET NULL** | 将引用列设为 NULL | +| **SET DEFAULT** | 设为默认值 | +| **NO ACTION** | 类似 RESTRICT(延迟检查) | + +## DDL 标签页 + +查看表的 CREATE TABLE 语句: + +{/* Screenshot: DDL tab showing CREATE TABLE statement */} + + DDL 标签页 + DDL 标签页 + + +### 复制 DDL + +1. 打开 DDL 标签页 +2. 全选(`Cmd+A`) +3. 复制(`Cmd+C`) + +DDL 可用于: + +- 在其他数据库中重建表 +- 对 schema 变更进行版本控制 +- 编写文档 +- 创建类似的表 + +### DDL 示例 + + + + ```sql + CREATE TABLE `users` ( + `id` int NOT NULL AUTO_INCREMENT, + `email` varchar(255) NOT NULL, + `name` varchar(100) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`), + KEY `created_at` (`created_at`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + ``` + + + ```sql + CREATE TABLE users ( + id SERIAL PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE, + name VARCHAR(100), + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE + ); + + CREATE INDEX idx_users_created_at ON users(created_at); + ``` + + + ```sql + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + email TEXT NOT NULL UNIQUE, + name TEXT, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT + ); + + CREATE INDEX idx_users_created_at ON users(created_at); + ``` + + + +## 表元数据 + +还可能显示以下表信息: + +| 属性 | 说明 | +|------|------| +| **引擎** | 存储引擎(MySQL:InnoDB、MyISAM) | +| **排序规则** | 字符排序规则 | +| **行数** | 预估行数 | +| **数据大小** | 表数据大小 | +| **索引大小** | 索引数据大小 | +| **注释** | 表注释/说明 | + +## 修改结构 + + +修改结构会改变数据库 schema。进行变更前请务必备份重要数据。 + + +### 可视化结构编辑器 + +通过可视化方式编辑表结构,无需编写 SQL: + +#### 添加列 + +1. 打开 **Structure** 标签页 > **Columns** +2. 点击 **+** 按钮添加新列 +3. 设置列属性:名称、类型、可空、默认值、自增、注释 + - 点击 **Type** 单元格打开类型选择器。按分类浏览数据库专有类型,或按名称搜索。 + - 对于参数化类型(如 `VARCHAR(255)`、`DECIMAL(10,2)`),直接在自由输入框中输入 +4. 点击 **Apply** 预览并执行更改 + +{/* Screenshot: Adding a new column in Structure editor */} + + 在结构编辑器中添加新列 + 在结构编辑器中添加新列 + + +#### 修改列 + +1. 在列标签页中点击某列 +2. 在详情面板中编辑属性 +3. 更改支持撤销/重做 +4. 点击 **Apply** 预览 ALTER TABLE SQL + +#### 删除列 + +1. 选择要删除的列 +2. 点击 **-** 按钮或按 Delete +3. 确认删除 +4. 应用更改 + +#### 类型选择器 + +编辑 **Type** 列时,会弹出一个可搜索的面板,按分类展示数据库专有数据类型: + +| 分类 | 示例 | +|------|------| +| **数值** | INT、BIGINT、DECIMAL、FLOAT、DOUBLE | +| **字符串** | VARCHAR、TEXT、CHAR、ENUM | +| **日期和时间** | DATE、DATETIME、TIMESTAMP、TIME | +| **二进制** | BLOB、BINARY、BYTEA | +| **其他** | JSON、JSONB、UUID、BOOLEAN | + +可用类型与当前连接的数据库(MySQL、PostgreSQL 或 SQLite)匹配。对于参数化类型如 `VARCHAR(255)` 或 `NUMERIC(10,2)`,直接输入自定义类型。 + +{/* Screenshot: Type picker popover in Structure editor */} + + 类型选择器 + 类型选择器 + + +### Schema 变更预览 + +在应用结构变更之前,TablePro 会显示生成的 ALTER TABLE SQL。查看确切的 SQL 语句,验证更改是否符合预期,必要时可取消。 + +{/* Screenshot: Schema change preview with ALTER TABLE statements */} + + 带 ALTER TABLE 语句的 Schema 变更预览 + 带 ALTER TABLE 语句的 Schema 变更预览 + + +### 撤销/重做 + +结构变更完整支持撤销/重做: + +- 按 `Cmd+Z` 撤销更改 +- 按 `Cmd+Shift+Z` 重做更改 +- 在应用到数据库之前均可追踪变更 +- 详情参见[变更追踪](/zh/features/change-tracking) + +{/* Screenshot: Undo and redo for structure changes */} + + 结构变更的撤销和重做 + 结构变更的撤销和重做 + + +### 通过 SQL 添加列 + +直接用 SQL 添加列: + +```sql +-- MySQL +ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email; + +-- PostgreSQL +ALTER TABLE users ADD COLUMN phone VARCHAR(20); + +-- SQLite (limited ALTER TABLE) +ALTER TABLE users ADD COLUMN phone TEXT; +``` + +### 通过 SQL 修改列 + +```sql +-- MySQL +ALTER TABLE users MODIFY COLUMN name VARCHAR(200) NOT NULL; + +-- PostgreSQL +ALTER TABLE users ALTER COLUMN name TYPE VARCHAR(200); +ALTER TABLE users ALTER COLUMN name SET NOT NULL; + +-- SQLite (requires table recreation) +-- See SQLite documentation for workarounds +``` + +### 通过 SQL 删除列 + +```sql +-- MySQL/PostgreSQL +ALTER TABLE users DROP COLUMN phone; + +-- SQLite (requires table recreation) +``` + +### 管理索引 + +```sql +-- Create index +CREATE INDEX idx_users_email ON users(email); + +-- Create unique index +CREATE UNIQUE INDEX idx_users_username ON users(username); + +-- Drop index +DROP INDEX idx_users_email ON users; -- MySQL +DROP INDEX idx_users_email; -- PostgreSQL +``` + +### 管理外键 + +```sql +-- Add foreign key +ALTER TABLE orders +ADD CONSTRAINT fk_orders_user +FOREIGN KEY (user_id) REFERENCES users(id) +ON DELETE CASCADE; + +-- Drop foreign key +ALTER TABLE orders DROP FOREIGN KEY fk_orders_user; -- MySQL +ALTER TABLE orders DROP CONSTRAINT fk_orders_user; -- PostgreSQL +``` + +## 刷新结构 + +进行 schema 变更后: + +1. **通过侧边栏**:右键点击表 > Refresh +2. **通过菜单**:View > Refresh +3. **自动刷新**:在 TablePro 中进行的变更会自动刷新 + +## 最佳实践 + +### Schema 设计 + +1. **选择合适的数据类型**:使用能容纳数据的最小类型 +2. **为查询添加索引**:对 WHERE 和 JOIN 中使用的列建索引 +3. **定义外键**:维护引用完整性 +4. **使用 NOT NULL**:当列必须有值时 +5. **设置默认值**:为可选列提供合理的默认值 + +### 命名规范 + +| 元素 | 规范 | 示例 | +|------|------|------| +| 表 | 复数,snake_case | `users`、`order_items` | +| 列 | 单数,snake_case | `user_id`、`created_at` | +| 索引 | `idx_table_columns` | `idx_users_email` | +| 外键 | `fk_table_reference` | `fk_orders_user` | +| 主键 | `id` 或 `table_id` | `id`、`user_id` | + +### 性能考量 + +1. **主键**:每张表都应有主键 +2. **外键索引**:为外键列建索引 +3. **组合索引**:按选择性排列列的顺序 +4. **避免过多索引**:索引会降低写入速度 + +## MongoDB 集合 + +MongoDB 集合的结构模型与 SQL 表不同。 + +### Schema 视图 + +MongoDB 集合的结构标签页为**只读**。由于 MongoDB 是无 schema 的,TablePro 通过抽样文档推断 schema。结构视图显示三列: + +- **名称**:字段名(包括点号表示的嵌套路径) +- **类型**:BSON 类型(ObjectId、String、Int32、Int64、Double、Boolean、Date、Array、Object 等) +- **可空**:该字段是否在所有抽样文档中都存在 + +### 索引 + +索引标签页显示集合索引。MongoDB 索引显示为可复制并在 `mongosh` 中运行的 `createIndex()` 命令。 + +### DDL 标签页 + +MongoDB 的 DDL 标签页显示: +- **索引定义**,以 `db.collection.createIndex()` 语句形式 +- **集合验证器**,以 `db.runCommand({collMod: ...})` 语句形式 +- **集合选项**(capped、size、max),如果适用 + + +MongoDB 集合不支持结构修改(添加/删除字段),因为 MongoDB 是无 schema 的。要修改 schema,请直接在数据网格中编辑文档。 + + +## 故障排除 + +### 结构未加载 + +1. 检查数据库连接 +2. 确认用户有查看 schema 的权限 +3. 刷新连接 + +### 缺少列 + +1. 刷新表结构 +2. 检查列是否在未提交的事务中添加 +3. 确认正在查看的是正确的数据库/schema + +### DDL 语法错误 + +将 DDL 复制到其他数据库时: + +1. 检查数据库之间的语法差异 +2. 为目标数据库调整数据类型 +3. 移除不支持的特性(如 PostgreSQL 不支持 MySQL 的 ENGINE) + +## 下一步 + + + + 编写 ALTER TABLE 查询 + + + 查看表数据 + + + 导出 schema 和数据 + + + 管理数据库连接 + + diff --git a/docs/zh/features/tabs.mdx b/docs/zh/features/tabs.mdx new file mode 100644 index 00000000..1d50bf85 --- /dev/null +++ b/docs/zh/features/tabs.mdx @@ -0,0 +1,398 @@ +--- +title: 查询标签页 +description: 每个标签页独立保存 SQL、结果、分页、排序和筛选状态,跨重启持久化 +--- + +# 查询标签页 + +每个标签页都是一个独立的工作区,拥有自己的 SQL 内容、查询结果、分页、排序和筛选状态。你可以同时打开任意多个标签页。它们在应用重启后依然保留。 + +{/* Screenshot: Tab bar showing multiple open tabs */} + + 查询标签页 + 查询标签页 + + +## 概述 + +标签页是 TablePro 中的主要工作区。每个连接记住自己的标签页集合,标签页在应用重启后持久化,让你可以从上次离开的地方继续工作。 + +## 标签页类型 + +TablePro 有两种标签页类型: + +| 类型 | 图标 | 用途 | +|------|------|------| +| **查询标签页** | 文档图标 | 编写和执行自定义 SQL 查询 | +| **表标签页** | 表图标(蓝色) | 浏览表数据,支持分页和筛选 | + +### 查询标签页 + +查询标签页是通用的 SQL 编辑器。适用于临时查询、用自定义 SELECT 语句探索数据、运行 DDL 或 DML 操作,以及在添加到应用程序前测试查询。 + +查询标签页初始为空编辑器。输入 SQL 后按 `Cmd+Enter` 执行。 + +### 表标签页 + +在侧边栏中点击表名时打开表标签页。它提供: + +- 自动生成 `SELECT * FROM table LIMIT n` 查询 +- 带页面导航控件的服务端分页 +- 带变更追踪的行内编辑 +- 结构视图切换,用于查看/修改表 schema +- 筛选功能,用于缩小结果范围 + + +表标签页默认可编辑。查询标签页为只读,除非查询是简单的 `SELECT * FROM table` 语句。 + + +### 智能标签页复用 + +在侧边栏中点击表时: + +- **相同的表**:切换到现有标签页(不执行新查询) +- **不同的表**:打开新标签页 + +你可以在 **Settings** > **Tabs** 中启用 **Reuse clean table tab**,获得类似 TablePlus 的行为:点击不同的表时替换当前表标签页,前提是它没有未保存的更改、没有用户交互(排序、筛选等),且未被固定。这样既能保持标签栏整洁,又能保护你的工作。 + +### 预览标签页 + +预览标签页减少浏览表时的标签页混乱。在侧边栏中单击表会打开一个临时标签页,当你点击另一张表时会被替换。这类似于 VS Code 的预览标签页。 + +预览标签页通过窗口副标题中的 "Preview" 标识。在以下情况下会变为永久标签页: + +- **双击**侧边栏中的表 +- 与标签页**交互**(排序、筛选、编辑数据、选择行) + +预览标签页不会在应用重启时保存。 + + +如果你希望每次点击都打开永久标签页,可以在 **Settings** > **Tabs** 中禁用预览标签页。 + + +{/* Screenshot: Different tab types: Query and Table */} + + 不同的标签页类型:查询和表 + 不同的标签页类型:查询和表 + + +## 管理标签页 + +### 创建标签页 + +| 操作 | 方法 | +|------|------| +| 新建查询标签页 | 点击标签栏的 **+** 按钮,或按 `Cmd+T` | +| 新建查询标签页(从工具栏) | 点击工具栏中的 **SQL** 按钮 | +| 新建表标签页 | 点击侧边栏中的表名 | +| 新建表标签页(通过查询) | 打开查询标签页,然后使用 SQL 编辑器 | + +### 关闭标签页 + +| 操作 | 方法 | +|------|------| +| 关闭当前标签页 | 按 `Cmd+W` | +| 关闭指定标签页 | 鼠标悬停在标签页上点击 **x** 按钮 | +| 从右键菜单关闭 | 右键点击标签页选择 **Close Tab** | +| 关闭其他标签页 | 右键点击标签页选择 **Close Other Tabs** | + + +关闭有未保存更改的标签页会丢弃这些更改。如果有待提交的数据修改,TablePro 会在关闭前发出提醒。 + + +### 切换标签页 + +点击标签栏中的任意标签页,或使用键盘快捷键: + +- `Cmd+1` 到 `Cmd+9` 按位置跳转到标签页 +- `Cmd+Shift+[` 或 `Cmd+Option+Left` 切换到上一个标签页 +- `Cmd+Shift+]` 或 `Cmd+Option+Right` 切换到下一个标签页 + +上一个标签页的状态完全保留: + +- SQL 编辑器内容和光标位置 +- 查询结果 +- 数据网格的滚动位置 +- 选中的行 +- 排序和筛选状态 +- 待提交的更改 + +### 重排标签页 + +拖拽标签页到标签栏中的新位置。蓝色插入指示器显示标签页将落在哪里。 + +当标签页超出可用空间时,标签栏会水平滚动。选中的标签页会自动滚动到可见区域。 + +{/* Screenshot: Drag and drop tab reordering */} + + 拖拽重排标签页 + 拖拽重排标签页 + + +### 固定标签页 + +固定重要标签页以防止意外关闭: + +1. 右键点击标签页 +2. 选择 **Pin Tab** +3. 标签页上出现固定图标 + +已固定的标签页: + +- 无法通过关闭按钮、`Cmd+W` 或右键菜单关闭 +- 选择 **Close Other Tabs** 时不会被关闭 +- 在侧边栏中点击其他表时不会被替换 +- 跨会话保持打开 + +要取消固定,右键点击并选择 **Unpin Tab**。 + +{/* Screenshot: Pinned tab with pin indicator */} + + 带固定标记的固定标签页 + 带固定标记的固定标签页 + + +### 复制标签页 + +要创建现有标签页的副本: + +1. 右键点击标签页 +2. 选择 **Duplicate Tab** +3. 一个包含相同查询内容和结果的新标签页打开 + +复制的标签页插入到原始标签页之后。 + +## 标签页状态 + +每个标签页存储其全部状态,切换标签页时完全保留。 + +### 状态属性 + +| 属性 | 说明 | +|------|------| +| **标签页 ID** | 唯一标识符(UUID) | +| **标题** | 标签栏中显示的名称 | +| **SQL 内容** | SQL 编辑器中的查询文本 | +| **标签页类型** | 查询或表 | +| **表名** | 关联的表名(表标签页) | +| **结果列** | 上次查询的列名 | +| **结果行** | 上次查询的行数据(缓存) | +| **列类型** | 用于格式化的数据类型元数据 | +| **执行时间** | 上次查询的耗时 | +| **错误信息** | 上次失败查询的错误 | +| **可编辑** | 是否启用行内编辑 | +| **分页状态** | 当前页、每页行数、总行数 | +| **排序状态** | 排序列和方向 | +| **筛选状态** | 活跃的筛选条件和可见性 | +| **待提交更改** | 排队的数据修改 | +| **选中行** | 当前选中的行索引 | +| **结果版本** | 缓存失效计数器 | + +### 标签页独立的变更追踪 + +每个标签页维护自己的待提交更改。切换标签页时: + +1. 当前标签页的更改保存到该标签页的 `pendingChanges` 属性 +2. 变更管理器加载新标签页的待提交更改 +3. 视觉指示器更新以反映新标签页的状态 + +你可以同时在多个标签页中有待提交的编辑,互不干扰。 + +## 标签页持久化 + +标签页在应用重启后持久化。 + +### 持久化内容 + +| 保存 | 不保存 | +|------|--------| +| 标签页 ID 和标题 | 查询结果(重新打开时重新查询) | +| SQL 内容 | 待提交的数据更改 | +| 标签页类型 | 选中的行 | +| 表名 | 排序和筛选状态 | +| 固定状态 | 执行时间 | +| -- | 预览标签页状态(预览标签页被丢弃) | + +### 持久化工作原理 + + + + 标签页状态在任何更改后 500ms 自动保存(防抖以避免频繁写入) + + + 每个数据库连接有自己的保存标签页状态,以连接特定的键存储在 UserDefaults 中 + + + 重新连接数据库时,TablePro 恢复保存的标签页并为表标签页重新执行查询 + + + 关闭窗口时,任何待处理的防抖保存会立即刷新,防止数据丢失 + + + +### 最后查询记忆 + +TablePro 还会记住每个连接的最后一次查询文本,类似 TablePlus。即使关闭了所有标签页,最后的查询也会在你创建新标签页时恢复。 + +## 标签页中的分页 + +TablePro 根据标签页类型使用不同的分页策略。 + +### 表标签页(服务端分页) + +表标签页使用 SQL `LIMIT` 和 `OFFSET`: + +- 只从数据库加载当前页 +- 翻页触发新查询 +- 默认每页行数可在 **Settings** > **Data Grid** 中配置 + +| 控件 | 操作 | +|------|------| +| 第一页 | 跳到第 1 页 | +| 上一页 | 返回上一页 | +| 页码指示 | 显示当前页 / 总页数 | +| 下一页 | 前进一页 | +| 最后一页 | 跳到最后一页 | + + +服务端分页内存效率高。即使表有数百万行,内存中也只保留可见页的数据。 + + +{/* Screenshot: Server-side pagination in a table tab */} + + 表标签页中的服务端分页 + 表标签页中的服务端分页 + + +### 查询标签页(客户端分页) + +查询标签页执行完整查询并接收所有结果。对于大数据集,TablePro 应用客户端分页: + +- 结果存储在内存中 +- 分页切割结果数组,无需重新查询 +- 排序在缓存的结果上本地执行 + +### 每页行数配置 + +在 **Settings** > **Data Grid** 中配置默认每页行数: + +| 选项 | 每页行数 | +|------|----------| +| 小 | 100 | +| 中 | 500 | +| 大 | 1,000 | +| 自定义 | 10 - 100,000 | + +## 标签页右键菜单 + +右键点击任意标签页访问右键菜单: + +| 操作 | 说明 | +|------|------| +| **Duplicate Tab** | 创建此标签页的副本 | +| **Pin Tab** / **Unpin Tab** | 切换固定状态 | +| **Close Tab** | 关闭此标签页 | +| **Close Other Tabs** | 关闭除此标签页外的所有标签页(尊重固定标签页) | + +{/* Screenshot: Tab context menu */} + + 标签页右键菜单 + 标签页右键菜单 + + +## 键盘快捷键 + +| 操作 | 快捷键 | +|------|--------| +| 新建查询标签页 | `Cmd+T` | +| 关闭当前标签页 | `Cmd+W` | +| 切换到标签页 1-9 | `Cmd+1` 到 `Cmd+9` | +| 上一个标签页 | `Cmd+Shift+[` 或 `Cmd+Option+Left` | +| 下一个标签页 | `Cmd+Shift+]` 或 `Cmd+Option+Right` | + +## 最佳实践 + +### 按任务组织 + +为不同任务使用不同标签页:一个用于浏览数据,一个用于编写迁移查询,一个用于测试。这样可以保持工作区有条理。 + +### 固定重要标签页 + +固定你经常引用的查询标签页。这样可以防止它们被意外关闭。 + +### 浏览数据用表标签页 + +只需要查看数据时,点击侧边栏中的表打开表标签页。这样无需编写 SQL 就能获得分页、编辑和结构视图。 + +### 复杂工作用查询标签页 + +对于连接、聚合、子查询和多语句操作,使用查询标签页。SQL 编辑器让你完全掌控执行内容。 + +### 关闭不用的标签页 + +虽然标签页很轻量,但关闭不再需要的标签页可以保持标签栏整洁,让导航更方便。 + +## 下一步 + + + + 在查询标签页中编写查询 + + + 查看和编辑查询结果 + + + 访问之前执行的查询 + + + 所有键盘快捷键 + + diff --git a/docs/zh/index.mdx b/docs/zh/index.mdx new file mode 100644 index 00000000..a958d795 --- /dev/null +++ b/docs/zh/index.mdx @@ -0,0 +1,108 @@ +--- +title: 简介 +description: 原生 macOS 数据库客户端,支持 MySQL、PostgreSQL、SQLite、MongoDB、Redis、SQL Server、ClickHouse、Oracle、Redshift,并内置 AI SQL 助手 +--- + +# TablePro + +一款原生 macOS 数据库客户端。快速、轻量,内置 AI SQL 助手。基于 SwiftUI 和 AppKit 构建,使用 Apple 原生框架和系统库,带来真正的 macOS 性能体验。 + +{/* Screenshot: Main application window showing the SQL editor, sidebar with connections, and data grid */} + + TablePro 主界面 + TablePro 主界面 + + +## 为什么选择 TablePro? + + + + Swift 与 Apple 原生框架。没有 Electron,没有 Web 视图。响应速度符合真正 Mac 应用的标准。 + + + MySQL、MariaDB、PostgreSQL、SQLite、MongoDB、Redis、SQL Server、ClickHouse、Oracle 和 Amazon Redshift,一个界面全搞定。 + + + 上下文感知的 SQL 自动补全,能识别你的 schema、表、列和 SQL 语法。 + + + 支持 SSH 隧道,提供密码和私钥认证,安全访问远程数据库。 + + + 与 AI 对话、获取内联建议,通过右键菜单解释、优化或修复 SQL。支持 Claude、OpenAI、Gemini、Ollama 等多种服务。 + + + +## 核心功能 + +### SQL 编辑器 +语法高亮、行号显示,以及能根据数据库 schema 自适应的自动补全。 + + +使用 `Cmd+Enter` 执行当前查询或选中的文本。 + + +### 数据表格 +高性能的电子表格式数据网格,支持内联编辑、排序和筛选。 + +### 表结构 +通过可视化界面查看和修改列、索引和外键。 + +### 导入与导出 +支持从 CSV、JSON 和 SQL 文件导入。支持多种格式导出,用于备份或迁移。 + +### 查询历史 +在完整的查询历史中进行全文搜索。即时重新运行或修改历史查询。 + +### AI SQL 助手 +用自然语言编写查询,获取 Copilot 风格的内联建议,右键即可解释或优化 SQL。支持 Claude、OpenAI、Gemini、OpenRouter、Ollama 和自定义端点。 + +## 支持的数据库 + +| 数据库 | 状态 | 默认端口 | +|----------|--------|--------------| +| MySQL | 完全支持 | 3306 | +| MariaDB | 完全支持 | 3306 | +| PostgreSQL | 完全支持 | 5432 | +| SQLite | 完全支持 | 不适用(基于文件) | +| Amazon Redshift | 完全支持 | 5439 | +| MongoDB | 完全支持 | 27017 | +| Redis | 完全支持 | 6379 | +| Microsoft SQL Server | 完全支持 | 1433 | +| ClickHouse | 完全支持 | 8123 | +| Oracle Database | 完全支持 | 1521 | + +## 系统要求 + +- **macOS**: 14.0 (Sonoma) 或更高版本 +- **架构**: Apple Silicon (arm64) 或 Intel (x86_64) +- **存储空间**: 应用约 50 MB(建议预留约 200 MB 可用磁盘空间,包含数据存储) + +## 开始使用 + +按照[快速入门指南](/zh/quickstart)下载 TablePro,并连接到你的第一个数据库。 + + + + 下载、安装并在 5 分钟内连接到数据库。 + + + 系统要求、Homebrew 安装和常见问题排查。 + + + +## 开源项目 + +TablePro 是免费的开源软件,采用 [GNU Affero General Public License v3.0 (AGPLv3)](https://www.gnu.org/licenses/agpl-3.0.html) 许可证。完整源代码托管在 GitHub 上。 + + + 查看源代码、报告问题并参与 TablePro 的开发。 + diff --git a/docs/zh/installation.mdx b/docs/zh/installation.mdx new file mode 100644 index 00000000..dcbb15f5 --- /dev/null +++ b/docs/zh/installation.mdx @@ -0,0 +1,221 @@ +--- +title: 安装 +description: 在 macOS 14.0+ 上通过 Homebrew 或 DMG 安装 TablePro +--- + +# 安装 + +## 系统要求 + +### 最低要求 + +| 要求 | 规格 | +|-------------|---------------| +| **macOS 版本** | macOS 14.0 (Sonoma) 或更高版本 | +| **处理器** | Apple Silicon (M1/M2/M3/M4/M5) 或 Intel x86_64 | +| **内存** | 最低 4 GB RAM | +| **存储空间** | 约 200 MB 可用磁盘空间(应用约 50 MB;额外空间用于查询历史、标签页状态和插件) | + +### 推荐配置 + +- **macOS**: 最新版本以获得最佳性能 +- **内存**: 8 GB RAM 或更多,适用于大型数据库 +- **存储**: SSD 硬盘,提升查询历史和标签页持久化的速度 + + +TablePro 仅使用 Apple 原生框架。无需 Java、.NET 或其他运行时环境。 + + +## 通过 Homebrew 安装 + +最快的安装方式: + +```bash +brew install --cask tablepro +``` + + +Homebrew 可以在同一个地方管理安装和更新。 + + +更新: + +```bash +brew upgrade tablepro +``` + +卸载: + +```bash +brew uninstall tablepro +``` + +同时删除应用数据: + +```bash +brew zap tablepro +``` + +## 下载 + +### 从 GitHub Releases 下载 + +1. 前往 [TablePro Releases](https://github.com/datlechin/tablepro/releases) 页面 +2. 找到最新版本 +3. 下载适合你 Mac 的 DMG 文件: + +| 架构 | 文件 | 适用于 | +|--------------|------|---------------| +| Apple Silicon | `TablePro-arm64.dmg` | M1、M2、M3、M4、M5 芯片 | +| Intel | `TablePro-x86_64.dmg` | Intel 处理器 | + +### 查看你的 Mac 架构 + +1. 点击菜单栏中的 **Apple 菜单** () +2. 选择 **About This Mac** +3. 查看: + - **Chip**: Apple M1/M2/M3/M4/M5 = Apple Silicon + - **Processor**: Intel = x86_64 + +## 安装步骤 + +### 标准安装 + +1. **打开 DMG 文件** + - 双击下载的 `.dmg` 文件 + - 会出现一个新的 Finder 窗口 + +2. **拖到 Applications 文件夹** + - 将 TablePro 图标拖到 Applications 文件夹快捷方式上 + - 等待复制完成 + +{/* Screenshot: DMG window with drag-to-Applications illustration */} + + 拖到 Applications + 拖到 Applications + + +3. **推出 DMG** + - 在 Finder 侧边栏中右键点击已挂载的 DMG + - 选择 **Eject** + +4. **启动 TablePro** + - 打开 **Finder** > **Applications** + - 双击 **TablePro** + +## 更新 TablePro + +### 自动更新 + +TablePro 通过 [Sparkle](https://sparkle-project.org/) 在后台检查更新,有新版本时会通知你。 + +### 手动检查更新 + +手动检查: + +1. 打开菜单栏中的 **TablePro** 菜单 +2. 点击 **Check for Updates...** + +### 更新设置 + +在 **Settings** > **General** > **Software Update** 中配置更新行为: + +- 启用或禁用自动检查更新 +- 设置检查频率 + + +连接和设置与应用程序本体分开存储,更新不会丢失。 + + +### 数据存储位置 + +| 数据 | 位置 | 存储类型 | +|------|----------|--------------| +| **连接** | `~/Library/Preferences/com.TablePro.plist` | UserDefaults | +| **设置** | `~/Library/Preferences/com.TablePro.plist` | UserDefaults | +| **密码** | macOS 钥匙串(安全存储) | Keychain | +| **查询历史** | `~/Library/Application Support/TablePro/query_history.db` | SQLite | + +## 卸载 + +### 移除应用 + +1. 如果 TablePro 正在运行,先退出 +2. 打开 **Finder** > **Applications** +3. 将 **TablePro** 拖到废纸篓 + +### 删除应用数据(可选) + +删除所有 TablePro 数据: + +```bash +# 删除 Application Support 数据 +rm -rf ~/Library/Application\ Support/TablePro + +# 删除偏好设置 +rm ~/Library/Preferences/com.TablePro.plist + +# 删除钥匙串项目(通过 Keychain Access 应用) +# 搜索 "TablePro" 并删除相关项目 +``` + + +此操作将删除所有已保存的连接和查询历史。请先导出重要数据。 + + +## 故障排查 + +### 应用启动时崩溃 + +1. 检查是否下载了正确架构版本的安装包 +2. 确认你正在运行 macOS 14.0 或更高版本 +3. 尝试删除并重新安装应用 +4. 在 Console.app 中查看崩溃日志 + +### 安装后的连接问题 + +如果 TablePro 可以打开但无法连接数据库: + +1. 确认数据库服务器正在运行 +2. 检查防火墙设置(System Settings > Network > Firewall) +3. 确保数据库服务器接受来自 localhost 的连接 + +## 从源码构建 + +适用于希望从源码构建 TablePro 的开发者: + +1. 克隆仓库: +```bash +git clone https://github.com/datlechin/tablepro.git +cd tablepro +``` + +2. 打开 Xcode 项目: +```bash +open TablePro.xcodeproj +``` + +3. 构建并运行: + - 选择 **TablePro** scheme + - 按 `Cmd+R` 构建并运行 + +更多详细说明请参阅 [Development Setup](/zh/development/setup) 指南。 + +## 后续步骤 + + + + 连接到你的第一个数据库 + + + 连接管理与组织 + + diff --git a/docs/zh/quickstart.mdx b/docs/zh/quickstart.mdx new file mode 100644 index 00000000..40fcfd26 --- /dev/null +++ b/docs/zh/quickstart.mdx @@ -0,0 +1,218 @@ +--- +title: 快速入门 +description: 下载 TablePro,安装并在 5 分钟内连接到你的第一个数据库 +--- + +# 快速入门指南 + +下载、安装,然后运行你的第一条查询。 + +## 步骤 1:下载 TablePro + +最快的方式是通过 [Homebrew](https://brew.sh): + +```bash +brew install --cask tablepro +``` + + +如果通过 Homebrew 安装,可以直接跳到[步骤 3](#步骤-3创建你的第一个连接)。 + + +也可以手动下载: + +1. 访问 [GitHub Releases 页面](https://github.com/datlechin/tablepro/releases) +2. 下载适合你 Mac 的 DMG 文件: + - **Apple Silicon** (M1/M2/M3/M4/M5): `TablePro-arm64.dmg` + - **Intel**: `TablePro-x86_64.dmg` + + +不确定你的 Mac 使用哪种芯片?点击 Apple 菜单,选择 **About This Mac**。查看 "Chip"(Apple Silicon)或 "Processor"(Intel)。 + + +## 步骤 2:安装 TablePro + +1. 打开下载的 DMG 文件 +2. 将 **TablePro** 拖到 **Applications** 文件夹 +3. 推出 DMG +4. 从 Applications 文件夹打开 TablePro + +{/* Screenshot: DMG installation window showing drag to Applications */} + + 安装对话框 + 安装对话框 + + +## 步骤 3:创建你的第一个连接 + +启动后会显示欢迎界面。在这里创建新的数据库连接。 + +### MySQL/MariaDB + +1. 点击 **New Connection** +2. 选择 **MySQL** 或 **MariaDB** 作为数据库类型 +3. 填写连接信息: + - **Name**: 连接的名称(例如 "Local MySQL") + - **Host**: `localhost`(或你的服务器地址) + - **Port**: `3306`(默认) + - **Username**: 数据库用户名(例如 `root`) + - **Password**: 数据库密码 + - **Database**: (可选)默认连接的数据库 + +{/* Screenshot: Connection form with MySQL selected and fields filled in */} + + MySQL 连接表单 + MySQL 连接表单 + + +### PostgreSQL + +1. 点击 **New Connection** +2. 选择 **PostgreSQL** 作为数据库类型 +3. 填写连接信息: + - **Name**: 连接的名称(例如 "Local PostgreSQL") + - **Host**: `localhost`(或你的服务器地址) + - **Port**: `5432`(默认) + - **Username**: 数据库用户名(例如 `postgres`) + - **Password**: 数据库密码 + - **Database**: 要连接的数据库名称 + +### Amazon Redshift + +1. 点击 **New Connection** +2. 选择 **Amazon Redshift** 作为数据库类型 +3. 填写连接信息: + - **Name**: 连接的名称(例如 "Redshift Warehouse") + - **Host**: 你的集群端点(例如 `my-cluster.abc123.us-east-1.redshift.amazonaws.com`) + - **Port**: `5439`(默认) + - **Username**: Redshift 用户名(例如 `awsuser`) + - **Password**: 密码 + - **Database**: 数据库名称(通常为 `dev`) + +### SQLite + +1. 点击 **New Connection** +2. 选择 **SQLite** 作为数据库类型 +3. 点击 **Browse** 选择 SQLite 数据库文件 +4. 为连接命名 + + +SQLite 数据库不需要认证。只需在 Mac 上选择 `.sqlite` 或 `.db` 文件即可。 + + +### MongoDB + +1. 点击 **New Connection** +2. 选择 **MongoDB** 作为数据库类型 +3. 填写连接信息: + - **Name**: 连接的名称(例如 "Local MongoDB") + - **Host**: `localhost`(或你的服务器地址) + - **Port**: `27017`(默认) + - **Username**: 数据库用户名(如果启用了认证) + - **Password**: 数据库密码 + - **Database**: 要连接的数据库名称 + - **Auth Database**: 认证数据库(默认为 `admin`) + + +本地 MongoDB 实例如果没有启用认证,只需填写 host 和 port。连接内部使用 `mongodb://` URI 协议。 + + +## 步骤 4:测试并连接 + +1. 点击 **Test Connection** 验证你的设置 +2. 绿色勾号表示连接成功 +3. 点击 **Create** 保存并连接 + +{/* Screenshot: Successful connection test showing green checkmark */} + + 连接测试成功 + 连接测试成功 + + +## 步骤 5:探索你的数据库 + +主界面分为三个面板: + +- **侧边栏**: 你的数据库和表 +- **SQL 编辑器**: 编写和执行 SQL 查询 +- **数据网格**: 查看和编辑查询结果 + +{/* Screenshot: Main interface after connecting, showing sidebar with tables */} + + 主界面 + 主界面 + + +### 尝试你的第一条查询 + +1. 点击侧边栏中的表来查看其内容 +2. 或者在 SQL 编辑器中输入查询: + +```sql +SELECT * FROM users LIMIT 10; +``` + +3. 按 `Cmd+Enter` 执行查询 +4. 在下方的数据网格中查看结果 + +## 后续步骤 + +一切就绪。接下来可以探索: + + + + 管理和组织你的连接。 + + + 语法高亮、自动补全和多光标编辑。 + + + 通过 SSH 连接远程数据库。 + + + 用键盘快捷键提升你的工作效率。 + + + 用 AI 编写、解释和优化 SQL。 + + + +## 需要帮助? + +如果遇到问题: + +- 查看[安装指南](/zh/installation)了解系统要求和故障排查 +- 参阅各数据库的专用指南解决连接问题 +- 在 GitHub 上[提交 issue](https://github.com/datlechin/tablepro/issues)