dsh-db-tool 1.8.5 → 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 +201 -0
- package/README.md +206 -71
- package/README_EN.md +207 -72
- package/client/client.js +117 -5
- package/dist/adapters/mysql/index.js +36 -22
- package/dist/adapters/redis/index.js +5 -2
- package/dist/adapters/sql-shared/pg-like.js +53 -4
- package/dist/adapters/sqlserver/index.js +99 -21
- package/dist/http/index.js +4 -0
- package/dist/manager.js +63 -2
- package/dist/store/connections.js +3 -1
- package/dist/store/grants.js +46 -10
- package/dist/store/normalize.js +11 -2
- package/package.json +5 -3
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
|
|
5
|
+
在 DSH 聊天中安全操作数据库:9 种数据库、项目级细粒度授权、危险操作确认、全量审计,配套侧边栏管理台与 SQL 控制台。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 功能流程
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
-
|
|
9
|
+
一次数据库操作从入口到落库审计的完整路径——两个入口共用一套语义,中间必须穿过项目级授权与语句级风险分级两道闸门:
|
|
10
|
+
|
|
11
|
+

|
|
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
|
-
|
|
80
|
+
Navicat 风格的侧边栏多标签编辑器(CodeMirror 6):
|
|
20
81
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
82
|
+
- **多标签**:每标签独立保存 SQL、结果与历史(50 条上限,点击回填)
|
|
83
|
+
- **语法高亮与补全**:按方言自动切换(MySQL / PostgreSQL / SQLite / PL/SQL / T-SQL),表列元数据注入补全
|
|
23
84
|
- **快捷键**:`Ctrl/Cmd+Enter` 执行全部,`Ctrl/Cmd+Shift+Enter` 执行选中
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- **批分隔符 GO
|
|
27
|
-
- **事务**:rw
|
|
28
|
-
-
|
|
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
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
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
|
-
|
|
136
|
+
---
|
|
62
137
|
|
|
63
|
-
|
|
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
|
|
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+
|
|
179
|
+
DSH 桌面端 0.2.0-rc.2+ 已捆绑 `dsh` 命令:
|
|
79
180
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
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.
|
|
185
|
+
dsh plugin --profile desktop add dsh-db-tool@1.8.8 --registry=https://registry.npmjs.org/
|
|
85
186
|
```
|
|
86
187
|
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
250
|
+
[Apache License 2.0](LICENSE) © 2026 mengqi1436
|
|
251
|
+
|
|
252
|
+
可自由商用、修改、分发与再许可,需保留版权与许可声明,修改过的文件需标注改动;附带的专利授权不可撤回,但对本作品发起专利诉讼时终止。
|