dsh-db-tool 1.8.4 → 1.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 mengqi1436
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -2,65 +2,166 @@
2
2
 
3
3
  [English](README_EN.md) | 简体中文
4
4
 
5
- DSH 社区插件:在聊天中安全操作数据库,配套侧边栏管理台与 `db-admin` skill。架构与交互模式对齐 [dsh-ssh-tunnel](https://github.com/thirsty5034/dsh-ssh-tunnel)。
5
+ 在 DSH 聊天中安全操作数据库:9 种数据库、项目级细粒度授权、危险操作确认、全量审计,配套侧边栏管理台与 SQL 控制台。
6
6
 
7
- ## 功能
7
+ ## 功能流程
8
8
 
9
- - **9 种数据库**:MySQL、PostgreSQL、GaussDB、SQLite、Redis、MongoDB、Oracle、达梦(DM)、SQL Server
10
- - **DatabaseManager 单工具多 action**:`list_connections / query / execute / schema / preview / run_script`(`run_script` 在 node:vm 沙箱中执行,60s 超时,仅注入受限 `db.{query,execute}` 句柄)
11
- - **分级权限**:连接级只读(ro)/读写(rw)+ 项目级授权(`grants.json`:projectPathKey → 连接 → 模式);未授权项目一律拒绝
12
- - **危险操作确认**:DDL / FLUSHALL / dropDatabase 等先返回 `NEEDS_CONFIRMATION`,对话内(模型经 ask)或 SQL 控制台(弹窗)确认后携一次性 `challengeId`(绑定语句 SHA256、5 分钟过期)重试
13
- - **审计**:全部执行落 `audit.jsonl`(语句、危险级、是否确认、结果)
14
- - **侧边栏 4 面板**(dsh-better-sidebar,zh/en):连接管理、项目授权、数据浏览、SQL 控制台
15
- - **db-admin skill**:随插件分发,覆盖 9 库方言速查、安全规范、确认流程
9
+ 一次数据库操作从入口到落库审计的完整路径——两个入口共用一套语义,中间必须穿过项目级授权与语句级风险分级两道闸门:
10
+
11
+ ![dsh-db-tool 功能流程](assets/feature-flow.png)
12
+
13
+ [**打开交互式版本**](assets/feature-flow.html) —— 支持缩放、拖动、路径高亮,可点节点查看源码证据。
14
+
15
+ > 有问题或建议?[提 Issue](https://github.com/mengqi1436/dsh-db-tool/issues/new/choose)(已有 Bug 模板与功能请求模板)。
16
+
17
+ ---
18
+
19
+ ## 支持的数据库
20
+
21
+ | 类别 | 数据库 |
22
+ |---|---|
23
+ | 关系型 | MySQL、PostgreSQL、GaussDB、SQLite、Oracle、达梦 DM、SQL Server |
24
+ | NoSQL | Redis、MongoDB |
25
+
26
+ 每种数据库都实现了完整的连接、元数据浏览、查询、预览与数据传输能力,方言差异在适配器内部处理——对上层统一暴露 `?` 占位符与标准结果集。
27
+
28
+ ---
29
+
30
+ ## 核心能力
31
+
32
+ ### 模型工具 `DatabaseManager`
33
+
34
+ 单一工具、多 action,减少模型选工具的歧义:
35
+
36
+ | action | 作用 |
37
+ |---|---|
38
+ | `list_connections` | 列出可选连接(不含凭据) |
39
+ | `query` | 执行只读查询,返回列与行 |
40
+ | `execute` | 执行写语句,危险操作需确认 |
41
+ | `schema` | 查看库/表/列结构 |
42
+ | `preview` | 预览表数据(分页,≤50 行/页) |
43
+ | `run_script` | 在沙箱中跑脚本,可多次调用 `db.query` / `db.execute` |
44
+
45
+ `run_script` 的隔离边界:独立子进程 + `node:vm` 沙箱,60 秒超时后进程级强杀,只注入受限的 `db.{query,execute}` 句柄——不给文件系统、网络与 `require`。
46
+
47
+ ### 项目级授权(ro / rw)
48
+
49
+ 授权以「项目路径 → 连接 → 模式」三级存储(`grants.json`):
50
+
51
+ - **ro(只读)**:允许查询与浏览,拒绝一切写操作
52
+ - **rw(读写)**:允许执行语句、脚本与事务
53
+
54
+ 未授权的项目对任何连接一律拒绝。授权模式变更(含 rw→ro 降级)会立即作废旧会话,不需要重连。
55
+
56
+ Windows 下路径按 NTFS 语义归一(大小写不敏感),`E:\GitHub\MyApp` 与 `e:\github\myapp` 视为同一项目。
57
+
58
+ ### 危险操作确认
59
+
60
+ DDL、`FLUSHALL`、`dropDatabase` 等语句先返回 `NEEDS_CONFIRMATION`,不会直接执行:
61
+
62
+ 1. 首次调用返回待确认状态与一次性 `challengeId`
63
+ 2. `challengeId` 绑定语句的 SHA256,5 分钟内有效、用后即废
64
+ 3. 用户确认后携同一 `challengeId` 重试才真正执行
65
+
66
+ 模型侧经对话确认,SQL 控制台侧经弹窗确认——两条路径共用同一套语义,任一处都无法绕过。
67
+
68
+ ### 全量审计
69
+
70
+ 每次执行(包括被拒绝的请求)都追加一行到 `audit.jsonl`:语句、危险级别、是否经过确认、结果与耗时。侧边栏可实时查看。
71
+
72
+ ### 数据浏览
73
+
74
+ - 连接 → 库 → schema → 表四级树形展开
75
+ - 库筛选 + 跨库表名模糊搜索(MySQL / PostgreSQL / GaussDB 走 `information_schema` 原生查询,其余库回退内存过滤)
76
+ - 表结构查看与数据预览,结果网格支持排序、分页、单元格复制
16
77
 
17
78
  ### SQL 控制台
18
79
 
19
- 侧边栏 SQL 控制台面板已升级为 Navicat 式多标签编辑器(CodeMirror 6):
80
+ Navicat 风格的侧边栏多标签编辑器(CodeMirror 6):
20
81
 
21
- - **多标签**:新建/关闭/切换查询标签,每个标签独立保存 SQL、结果与历史(历史上限 50 条,可展开点击回填)
22
- - **语法高亮与补全**:按方言切换——mysql→MySQL、postgresql/gaussdb→PostgreSQL、sqlite→SQLite、oracle/dmdb→PL/SQL、sqlserver→T-SQL(`@codemirror/lang-sql` 的 MSSQL 方言);Redis/Mongo 为关键字/方法补全的纯文本编辑;表列元数据自动拉取注入补全(上限 50 表)。编辑器 bundle(`vendor/codemirror-sql.cjs`,`npm run build:codemirror` 生成,`npm run build` 自动串接)加载失败时静默降级 textarea
82
+ - **多标签**:每标签独立保存 SQL、结果与历史(50 条上限,点击回填)
83
+ - **语法高亮与补全**:按方言自动切换(MySQL / PostgreSQL / SQLite / PL/SQL / T-SQL),表列元数据注入补全
23
84
  - **快捷键**:`Ctrl/Cmd+Enter` 执行全部,`Ctrl/Cmd+Shift+Enter` 执行选中
24
- - **格式化**:sql-formatter 按方言格式化(sqlserver→`transactsql`),解析失败回退原文
25
- - **逐条执行**:客户端预分类读/写语句分别路由 `/api/query` 与 `/api/execute`,只读授权下写语句自动跳过并标注;出错可一键定位到对应语句起始处
26
- - **批分隔符 GO**:支持 `GO` 与 `GO n`——按 sqlcmd 语义把上一批重复执行 n 次(`GO 0` / `GO 1` 均等同 1 次),`GO` 行本身不产生语句;重复计数上限 **1000**,超出按 1000 截断,防止一次执行被放大成天量请求
27
- - **事务**:rw 授权下可开始/提交/回滚(服务端粘性连接会话;空闲 5 分钟超时自动回滚并审计,授权回收/降级即时生效)
28
- - **结果网格**:表头三态排序、50 行/页分页、单元格点击复制、CSV/JSON 导出
29
-
30
- ## SQL Server 支持范围与边界
31
-
32
- 覆盖 SQL Server 2008/2008R2 → 2022 与 Azure SQL Database;方言与元数据只使用 SQL Server 2005+ 的通用写法。
33
-
34
- - **连接形态**:唯一形态为 `sqlserver://user:password@host:port/db`,支持 query 参数 `encrypt` / `trustServerCertificate` / `tdsVersion` / `instanceName` / `useUTC`(参数名大小写不敏感)。`tdsVersion` 默认 `7_4`,可配 `7_3_A` / `7_3_B` / `7_2` / `7_1`;端口默认 1433,指定 `instanceName` 时按 tedious 语义忽略端口、走 SQL Browser(UDP 1434);最低 TLS 版本经 `cryptoCredentialsDetails.minVersion` 配置,`ssl=true` 等价于 `encrypt=true`。**不接受** ADO.NET 键值连接串(`Server=...;Database=...`)。
35
- 默认 `encrypt=true` + `trustServerCertificate=false`(与 mssql 官方默认一致)。**连 SQL Server 2008/2008R2 时通常要在 URL 追加 `?trustServerCertificate=true`**:旧实例多为自签名证书且可能只支持 TLS 1.0,而 Node 默认最低 TLSv1.2,直接按默认值会握手失败;服务器未强制加密时也可用 `?encrypt=false`,并建议显式写 `?tdsVersion=7_3_A`(2008)/ `7_3_B`(2008R2)。
36
- - **认证边界**:仅 SQL 认证(`user` / `password`)。**不支持 Windows 集成认证**,**不支持 Azure AD 认证**。
37
- - **方言**:参数占位符对外只写 `?`,适配器内部按顺序重写为 `@p1..@pN`;标识符用 `[x]`,名字中的 `]` 双写为 `]]`;库/表/列元数据只走 `sys.*` catalog views(`sys.databases` / `sys.schemas` / `sys.objects` / `sys.columns` / `sys.types` / `sys.indexes` / `sys.extended_properties`),只用 2005+ 通用写法。
38
- - **分页按版本分流**:连接后查 `SERVERPROPERTY('ProductMajorVersion')`(取不到时回退解析 `ProductVersion` 前缀)并缓存;major ≥ 11(2012+,含 Azure SQL 的 12)用 `ORDER BY (SELECT NULL) OFFSET n ROWS FETCH NEXT m ROWS ONLY`,< 11(2008/2008R2)降级 `ROW_NUMBER() OVER (ORDER BY (SELECT NULL))` 子查询;探测失败同样走降级分支。
39
- - **decimal 精度分侧口径**:浏览侧(`query` / `preview` / 数据浏览网格)**不保证 decimal/numeric 逐位保真**——tedious 在解析阶段已把 decimal 转成 JS number(>15 有效位即丢精度),适配器转字符串只能防后续数值化,且 >1e21 会出现科学计数法;需要逐位保真时请在 SQL 里显式 `CONVERT(nvarchar(...), col)`。数据传输(transfer)读端已内建该转换(`CONVERT(nvarchar(64), col)`),写入时按字符串绑定,精度不经过 JS 浮点。
40
- - **类型搬运口径(传输侧)**:`hierarchyid` / `geometry` / `geography` 按二进制(bytes)保真搬运,目标端建 `VARBINARY(MAX)`——**UDT 类型语义不保留**(目标端没有 `ST_*` / `hierarchyid` 方法);`sql_variant` 读端 `CONVERT(nvarchar(max), col)` 转文本,**原类型信息丢失**(驱动按值的实际类型返回标量,无法统一搬运);`text` / `ntext` / `xml` → `NVARCHAR(MAX)`,源 `varchar` / `char` 长度 4001–8000 也映射为 `NVARCHAR(MAX)` 类(保容量,不做隐式收窄),`varbinary` / `image` / `rowversion` → `VARBINARY(MAX)`,`decimal` / `numeric` / `money` → `DECIMAL`;`datetime2` 读端 `CONVERT(nvarchar(33), col, 126)`、`time` 用 `CONVERT(nvarchar(16), col, 126)` 保真。
41
- - **ro 只读强度弱于 MySQL/PG**:SQL Server 没有等价的会话级只读语句。ro 授权下适配器 query 闸门共五道:① 首词白名单(`select / with / show / describe / desc / explain / use / set / help / table`);② 拒绝多语句(词法级:顶层分号之后出现任何内容即拒);③ 拒绝 `SELECT ... INTO`(词法 token 级判定,字符串、方括号标识符与注释内的 `into` 不误伤);④ 拒绝 `WITH ... (INSERT|UPDATE|DELETE|MERGE)`;⑤ 拒绝 `OPENQUERY` / `OPENROWSET` / `OPENDATASOURCE`(其字符串参数会在远端/外部数据源执行任意语句、不可审计,连合法的只读远端查询也一律拒)。服务层另拦 `execute`,guard 层对同样两类「读头写体」还会要求确认。**这仍是应用层拦截,不等同于数据库侧的只读会话**;需要强隔离时请给连接配数据库侧只读账号。
42
- - **数据传输**:写入走参数化多行 `VALUES` INSERT(TDS 单语句参数上限 2100、`VALUES` 表值构造器单语句最多 1000 行,每语句行数取两者最小值;replace/ignore 走 `MERGE`)。传输分页同样按目标库版本分流:2012+ 用 `OFFSET/FETCH`,2008/2008R2 降级——有序游标(keyset/range)用 `SELECT TOP (n) ... ORDER BY key`,无分片键的 offset 全序与 `keyAt` 切块用 `ROW_NUMBER() OVER (...)` 子查询;版本探测失败时按 0 走保守降级,因此**传输在 SQL Server 2008/2008R2 同样可用**。已知限制:目标表已存在且该列为 IDENTITY 时,写入显式值会报错 544(当前不自动 `SET IDENTITY_INSERT ON`);传输自动建表不生成 IDENTITY 列。建表 DDL 在显式事务中可回滚,不需要 Oracle/DM 那样的隐式提交处理。
43
- - **验证状态**:本轮只交付离线单测(Fake 驱动),SQL Server 路径**未经真机验证**;真机冒烟开关 `DBT_TEST_SQLSERVER_URL`(形如 `sqlserver://sa:pw@host:1433/db`)。
44
- - **驱动形态**:`mssql@12` 仅在 devDependencies,运行时加载 `npm run build:sqlserver` 生成的 `vendor/sqlserver-driver.cjs`;原因是 mssql → tedious → bl → readable-stream 会把 buffer/events/process/string_decoder 带进生产依赖树,触发宿主 `dsh-app-boot` 的 `require.resolve.paths` bug,导致插件整体加载失败。
45
- - **错误消息脱敏**:连接 URL 解析失败时,错误文案里的 userinfo 已脱敏,不回显明文密码(错误会进 `audit.jsonl` 与模型上下文,故必须脱敏)。
46
- - **不支持**:SQL Server 2005(9.x)及更早版本,未支持也未验证;`tdsVersion=8_0`(TDS 8.0)与 `encrypt='strict'`(严格加密)亦未支持——SQL Server 2022 用默认 `7_4` 即可正常连接,TDS 8.0 强加密属后续增强。
47
-
48
- ## 数据布局
49
-
50
- `$DSH_HOME/db-tool/`(0700):
85
+ - **格式化**:按方言调用 sql-formatter,解析失败回退原文
86
+ - **逐条执行**:客户端预分类读写语句,分别路由到查询与执行通道;ro 授权下写语句自动跳过并标注
87
+ - **批分隔符 `GO`**:支持 `GO` 与 `GO n`(sqlcmd 语义,`GO 0`/`GO 1` 均等同 1 次),重复上限 1000 次防放大
88
+ - **事务**:rw 授权下可开始/提交/回滚,服务端粘性连接;空闲 5 分钟自动回滚并审计
89
+ - **结果网格**:三态排序、50 行/页、CSV/JSON 导出
51
90
 
52
- | 文件 | 内容 |
91
+ ### 数据传输(transfer)
92
+
93
+ 同类或跨类数据库之间的表数据搬运:
94
+
95
+ - **写入模式**:`insert`(追加)、`ignore`(跳过冲突)、`replace`(覆盖)、`truncate`(先清空)
96
+ - **自动建表**:目标表不存在时按源表结构生成 DDL
97
+ - **分页读取**:有序游标(keyset)/ 范围 / 偏移三种策略,按目标库版本自动选择
98
+ - **进度与历史**:实时进度推送 + 按项目隔离的传输历史
99
+
100
+ ### 连接导出 / 导入
101
+
102
+ 一键把所有连接(含密码)导出为口令加密文件,用于跨机器迁移:
103
+
104
+ - scrypt 派生密钥 + AES-256-GCM 整体加密,文件打开无明文
105
+ - 口令最短 8 位,由服务端强制校验
106
+ - 导入时已存在的连接 id 一律跳过不覆盖,返回「已导入 / 跳过 / 失败」摘要
107
+
108
+ ---
109
+
110
+ ## 侧边栏
111
+
112
+ 通过 `dsh-better-sidebar` 注册一个 tab,内含四个面板(中英双语):
113
+
114
+ | 面板 | 用途 |
53
115
  |---|---|
54
- | `connections.json` | 连接定义(`urlSafe` 中密码脱敏为 `***`) |
55
- | `secrets.json` | 0600,密码/URL 凭据,永不返回给模型 |
56
- | `grants.json` | 项目授权(归一化路径 → connId → ro/rw) |
57
- | `audit.jsonl` | 追加式审计日志 |
116
+ | 连接管理 | 新增/编辑/删除连接,测试连通性,导出导入 |
117
+ | 项目授权 | 为当前项目勾选各连接的 ro/rw |
118
+ | 数据浏览 | 树形浏览库表、搜索、预览数据 |
119
+ | SQL 控制台 | 多标签编辑器、事务、历史、结果网格 |
58
120
 
59
- ## 安装
121
+ ---
122
+
123
+ ## 安全模型
124
+
125
+ | 层次 | 机制 |
126
+ |---|---|
127
+ | 存储 | 密码与完整 URL 存 `secrets.json`(0600),永不返回给模型,返回给界面的连接信息密码一律脱敏为 `***` |
128
+ | 授权 | 项目级 ro/rw 白名单,未授权即拒绝 |
129
+ | 语句级 | 风险分级(danger / warning / none)+ 一次性确认 |
130
+ | 只读强制 | MySQL/PG 走会话级 `SET TRANSACTION READ ONLY`;SQL Server 无等价语句,退化为应用层五道闸门(见下) |
131
+ | 错误脱敏 | 连接串解析失败时,错误文案中的 userinfo 已脱敏,不回显明文密码 |
132
+ | 脚本隔离 | 独立子进程 + vm 沙箱 + 60s 强杀 + 仅注入 db 句柄 |
133
+
134
+ **SQL Server 的 ro 强度弱于 MySQL/PG**:SQL Server 没有等价的会话级只读语句,ro 授权下由应用层五道拦截兜底——首词白名单、拒绝多语句、拒绝 `SELECT ... INTO`、拒绝 `WITH ... (INSERT|UPDATE|DELETE|MERGE)`、拒绝 `OPENQUERY`/`OPENROWSET`/`OPENDATASOURCE`。这仍是应用层拦截,需要数据库侧强隔离时请为连接配置只读账号。
60
135
 
61
- 9 种数据库驱动随 npm 包分发(SQLite 优先用 Node 内置 `node:sqlite`,可选 `better-sqlite3`;GaussDB 驱动为华为云官方 npm 包 `gaussdb-node`),无需任何构建步骤。其中 SQL Server 驱动(`mssql@12`)只在 devDependencies,运行时加载发布包内置的 `vendor/sqlserver-driver.cjs`(`npm run build:sqlserver` 生成)——mssql 的生产依赖树会带入 buffer/events/process/string_decoder,触发宿主 resolve.paths bug。GaussDB 认证支持 sha256 与 md5,md5-sha256 混合与 SM3 暂不支持。
136
+ ---
62
137
 
63
- 唯一的一次性交互来自 oracledb:其 install 脚本会被 pnpm 默认拦截并使首次安装报告失败——在 DSH 插件安装界面点 **"Allow these scripts and retry"** 即可完成安装(该脚本仅做 Node 版本检查与横幅打印,批准无风险;批准持久化到 profile,后续升级不再提示)。
138
+ ## SQL Server 连接说明
139
+
140
+ 覆盖 SQL Server 2008 / 2008 R2 → 2022 与 Azure SQL Database。
141
+
142
+ **连接 URL 参数**(分字段表单同样支持):
143
+
144
+ | 参数 | 取值 | 默认 |
145
+ |---|---|---|
146
+ | `encrypt` | `true` / `false` | `true` |
147
+ | `trustServerCertificate` | `true` / `false` | `false` |
148
+ | `tdsVersion` | `7_4` / `7_3_A` / `7_3_B` / `7_2` / `7_1` | `7_4` |
149
+ | `tlsMinVersion` | `TLSv1` / `TLSv1.1` / `TLSv1.2` | 不设置(Node 默认 TLSv1.2) |
150
+ | `instanceName` | 命名实例名(与 port 互斥) | — |
151
+ | `useUTC` | `true` / `false` | `true` |
152
+
153
+ **连老实例时先分清两类 TLS 失败,解法不通用**:
154
+
155
+ - **证书类**(`self signed certificate` / `unable to verify` / `CERT_`)→ 追加 `?trustServerCertificate=true`;服务器未强制加密时也可 `?encrypt=false`
156
+ - **协议版本类**(`UNSUPPORTED_PROTOCOL` / `no protocols available` / `alert protocol version`)→ 客户端与服务端没有共同的 TLS 版本,握手在协商阶段就失败,**证书校验根本没执行**,`trustServerCertificate` 对它无效。根治靠服务端启用 TLS 1.2(2008 R2 SP3 装 KB4057113、2008 SP4 装 KB4057114);暂时动不了服务端时用 `?tlsMinVersion=TLSv1` 让客户端下探
157
+
158
+ `tlsMinVersion` 不含 `TLSv1.3`:底层 tedious 会把 TLS 上限封顶在 1.2,设 1.3 会让最小版本大于最大版本,握手必然失败。
159
+
160
+ **其他边界**:仅 SQL 认证(不支持 Windows 集成认证与 Azure AD 认证);不支持 SQL Server 2005 及更早;`tdsVersion=8_0`(TDS 8.0)与 `encrypt='strict'` 暂未支持。
161
+
162
+ ---
163
+
164
+ ## 安装
64
165
 
65
166
  ```bash
66
167
  # npm(推荐)
@@ -70,48 +171,82 @@ dsh plugin --profile web add dsh-db-tool
70
171
  dsh plugin --profile web add "dsh-db-tool@github:mengqi1436/dsh-db-tool"
71
172
 
72
173
  # 本地开发
73
- dsh plugin --profile web add "link:E:\path\to\dsh-db-tool"
174
+ dsh plugin --profile web add "link:/path/to/dsh-db-tool"
74
175
  ```
75
176
 
76
- ### 桌面端安装
177
+ ### 桌面端
77
178
 
78
- DSH 桌面端 0.2.0-rc.2+ 捆绑了 `dsh` 命令,全程无需另装 Node 或 pnpm:
179
+ DSH 桌面端 0.2.0-rc.2+ 已捆绑 `dsh` 命令:
79
180
 
80
- 1. **首次使用**:打开桌面端菜单栏,点 **"Manage dsh command"(管理 dsh 命令)**,安装捆绑的 CLI——该操作把 `dsh` 命令注册到系统 PATH。
81
- 2. **安装插件**(必须钉精确版本:`@latest` 会因 release-age 校验回落到旧版):
181
+ 1. 打开桌面端菜单栏,点 **"Manage dsh command"** 把 `dsh` 注册到 PATH
182
+ 2. 安装插件(npm 安装须钉精确版本,`@latest` 会因 release-age 校验回落):
82
183
 
83
184
  ```bash
84
- dsh plugin --profile desktop add dsh-db-tool@1.4.0 --registry=https://registry.npmjs.org/
185
+ dsh plugin --profile desktop add dsh-db-tool@1.8.8 --registry=https://registry.npmjs.org/
85
186
  ```
86
187
 
87
- 已有 npm 镜像源偏好的用户,可把 `--registry` 替换为自己的镜像地址。
88
- 3. **重启桌面端**生效。
188
+ 3. **重启桌面端**生效
189
+
190
+ **关于 oracledb**:其安装脚本会被 pnpm 默认拦截,首次安装会报告失败。在 DSH 插件安装界面点 **"Allow these scripts and retry"** 即可完成——该脚本仅做 Node 版本检查与横幅打印,批准无风险,且批准会持久化到 profile,后续升级不再提示。
191
+
192
+ **运行环境要求**:Node.js ≥ 22。部分数据库驱动(tedious 及其 Azure 依赖)要求 Node 22 起,Node 20 会在建连时报 `Promise.withResolvers is not a function`。
193
+
194
+ ---
195
+
196
+ ## 数据存放
89
197
 
90
- mongodb 驱动已 bundle 进发布包(`vendor/mongodb-driver.cjs`),依赖树不含 mongodb/punycode——桌面端宿主打包在 `app.asar` 内、无法应用宿主补丁,本插件免补丁可直接安装加载。
198
+ `$DSH_HOME/db-tool/`(目录权限 0700):
91
199
 
92
- ## 测试
200
+ | 文件 | 内容 |
201
+ |---|---|
202
+ | `connections.json` | 连接定义(`urlSafe` 中密码脱敏为 `***`) |
203
+ | `secrets.json` | 0600,密码与完整 URL,永不返回给模型 |
204
+ | `grants.json` | 项目授权(归一化路径 → connId → ro/rw) |
205
+ | `audit.jsonl` | 追加式审计日志,每行一条 JSON |
206
+
207
+ ---
208
+
209
+ ## 开发
93
210
 
94
211
  ```bash
95
- npm test # 离线 mock 全量(含 e2e-mock 全链路与对抗用例)
96
- npx tsc --noEmit
97
- npx stryker run # 变异测试(范围 lib/guard + lib/manager + lib/store,报告 reports/mutation/)
212
+ npm install
213
+ npm run build # 编译 + 生成 vendor bundle(mongodb / sqlserver / codemirror)
214
+ npm test # vitest 全量
215
+ npm run typecheck # tsc --noEmit
216
+ ```
217
+
218
+ 真机冒烟测试由环境变量门控,设置了才运行:
219
+
220
+ ```
221
+ DBT_TEST_MYSQL_URL / DBT_TEST_PG_URL / DBT_TEST_REDIS_URL / DBT_TEST_DM_CONNECT
222
+ DBT_TEST_MONGO_URL / DBT_TEST_ORACLE_CONNECT / DBT_TEST_SQLSERVER_URL
98
223
  ```
99
224
 
100
- 真机冒烟(设了才跑):`DBT_TEST_MYSQL_URL / DBT_TEST_PG_URL / DBT_TEST_REDIS_URL / DBT_TEST_DM_CONNECT / DBT_TEST_MONGO_URL / DBT_TEST_ORACLE_CONNECT / DBT_TEST_SQLSERVER_URL`(SQL Server 形如 `sqlserver://sa:pw@host:1433/db`)。GaussDB、Oracle/Mongo 与 SQL Server 的要求均按官方文档实现,未真机验证处以代码内标注为准;**本轮 SQL Server 只有离线单测(Fake 驱动),未经真机验证**。
225
+ 同步执行器与测试的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml):Node 22 与 24 两档,跑 `npm ci → build → typecheck → test`。
101
226
 
102
- ## 目录结构
227
+ ### 目录结构
103
228
 
104
229
  ```
105
- lib/ host 插件(store / adapters×9 / guard / manager / http / index)
106
- client/ 侧边栏单文件产物(client.js,即源码)
107
- skills/ db-admin skill
108
- scripts/ 构建与工具脚本(mongodb / sqlserver 驱动、CodeMirror 编辑器 bundle、DSH 宿主热修复 patch:dsh 等)
109
- patches/ DSH 宿主 dsh-app-boot 热修复补丁(patch:dsh 按宿主版本选用)
110
- docs/ 预留(当前为空)
111
- tests/ vitest(离线 mock + DBT_TEST_* 门控真机)
112
- vendor/ mongodb-driver.cjs、sqlserver-driver.cjs 与 codemirror-sql.cjs bundle(gitignore,发布经 files 白名单收录)
230
+ lib/ 插件主体
231
+ adapters/ 9 种数据库适配器 + 传输实现
232
+ store/ 连接/授权/审计/密钥存储
233
+ guard/ 语句风险分级
234
+ manager.ts 业务编排(授权、分派、确认、审计)
235
+ http/ 侧边栏 HTTP 路由
236
+ script/ run_script 沙箱与子进程
237
+ client/ 侧边栏单文件产物
238
+ skills/ db-admin skill
239
+ scripts/ 构建与工具脚本
240
+ patches/ DSH 宿主热修复补丁
241
+ tests/ vitest(离线 mock + 真机门控)
242
+ assets/ 功能流程图
243
+ vendor/ 驱动与编辑器 bundle(构建产物,发布时收录)
113
244
  ```
114
245
 
246
+ ---
247
+
115
248
  ## 许可证
116
249
 
117
- MIT
250
+ [Apache License 2.0](LICENSE) © 2026 mengqi1436
251
+
252
+ 可自由商用、修改、分发与再许可,需保留版权与许可声明,修改过的文件需标注改动;附带的专利授权不可撤回,但对本作品发起专利诉讼时终止。