Files
henlo_migration_wpf10/AGENTS.md
T

174 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md
## 项目定位
恒诺迁移工具是一个仅运行于 Windows 的 Oracle 数据库迁移桌面工具。当前维护目标是 `henlo_migration_wpf10/`:WPF + .NET 10,程序集名为“恒诺迁移工具”。工具从源库读取表结构、BOS 配置、存储过程/函数和表数据,将 SQL 保存为本地文本;经用户确认后,再把本地 SQL 执行到目标库。
本文是仓库级开发约定。分析、修改和验证默认都以当前 WPF 项目为准,除非任务明确点名旧项目。
## 目录边界
- `henlo_migration_wpf10/`:当前唯一主程序,优先分析和修改。
- `henlo_migration/`:旧 .NET Framework 4.8 / WinForm 版本,已废弃;不要把旧版的窗体、AntdUI 或 AutoUpdater.NET 设计套到主程序。
- `henlo_migration_core10/`:未投入使用的 .NET Core 版本,默认不修改。
- `hc_preview/`:界面预览或辅助内容,不是主程序源码。
- `产品部署/`:部署相关资料或产物,只有发布任务才处理。
- `VELOPACK_MIGRATION.md`、`VELOPACK操作手册.md`:更新与发布背景资料;若与代码冲突,以当前代码和 `pack.bat` 为准。
## Git 仓库
- 项目远程仓库:`https://gitea.momozhua.site/qiangayi/henlo_migration_wpf10.git`
- 当前根目录已经初始化为 Git 工作区,默认分支为 `main`,远程名为 `origin`。
- 可以使用 `git status`、`git diff` 和提交历史检查改动。不要使用 `git reset --hard`、强制推送或其他会丢失本地/远程改动的命令。
- fetch、pull、commit、push 等会改变工作区、历史或远程状态的操作必须符合用户当前任务;上传远程仓库需要明确授权。
## 当前技术基线
- 项目文件:`henlo_migration_wpf10/henlo_migration_wpf10.csproj`
- 目标框架:`net10.0-windows`
- UI:WPF + HandyControl 3.5.1
- MVVM:手写 `INotifyPropertyChanged`/命令实现,引用 CommunityToolkit.Mvvm 8.3.2,但当前主 ViewModel 未使用其源生成器
- Oracle 访问:SqlSugar 5.1.4.157 + Oracle.ManagedDataAccess.Core 23.5.0
- 配置解析:ini-parser 2.5.2
- JSON:Newtonsoft.Json 13.0.3
- 自动更新:Velopack 0.0.1298
- 当前版本号:以 `.csproj` 的 `<Version>` 为唯一事实来源,不在本文硬编码版本
- Nullable:项目设置为 `<Nullable>disable</Nullable>`,源码中仍存在 `?` 注解,因此构建有既有 `CS8632` 警告
## 主程序结构
### 启动与界面
- `App.xaml`:应用资源、HandyControl 主题和 `MainViewModel` 资源注册;启动页是 `Views/HomeWindow.xaml`。
- `App.xaml.cs`:Velopack 初始化、旧版 `current/config.ini` 更新迁移、后台/手动更新、更新前后 `config.ini`、`data/` 与 `pre/` 备份恢复、全局异常日志。
- `Views/HomeWindow.xaml`:单窗口主界面,包含五个迁移 Tab、连接状态、SQL 编辑区和批量操作。
- `Views/HomeWindow.xaml.cs`:只处理窗口关闭和手动检查更新等窗口事件。
- `Views/ConnectionDialog.*`:源库/目标库连接配置与测试。
- `Views/ErrorDialog.*`:错误详情展示和复制。
- `Behaviors/ClickToCopyBehavior.cs`、`Converters/StatusColorConverter.cs`:界面辅助行为与状态颜色转换。
### 状态与编排
- `ViewModels/MainViewModel.cs`:主状态容器和命令编排;初始化五个 `TabServices`,管理数据库连接、单行/批量读写、SQL 编辑与断点续写。
- `Models/TableRowModel.cs`:每个迁移对象的名称、所属 Tab、读写状态。
- `Enums/`:Tab、状态、工作类型和输出扩展名枚举。
### 业务与数据访问
- `Services/TabConfig.cs` / `ITabConfig.cs`:将 Tab、索引文件、输出后缀和读取委托组合成配置。
- `Services/TabServices.cs`:索引列表加载/保存、单行读写、排序、删除和状态切换。
- `Services/DbServices.cs`:Oracle SQL 的提取与执行核心:
- `GetTableSql`:读取表 DDL、注释、主外键、唯一键和索引;
- `GetTableBos`:读取 BOS 配置;
- `GetTableBosField`:按 `TABLE.COLUMN` 读取单个 BOS 字段配置,生成目标物理字段补充 SQL,并包含关联限定值/引用元数据;
- `GetPrcSql` / `GetAllPrc`:读取存储过程或函数源码;
- `GetTableData`:生成表数据 INSERT SQL;
- `ExecuteCreate`:按 `\n/` 分隔 SQL,在目标库逐条执行并检查 `USER_ERRORS`。
- `Common/SqlSugarHelper.cs`:维护 `orig`(源库)和 `dest`(目标库)两个 SqlSugar 连接。
- `Common/SysConfig.cs`:读取和写入用户持久目录下的 `config.ini`。
- `Common/CommonHelper.cs`:运行目录、Velopack 持久目录、`config.ini`、`data/`、`data/from/`、`pre/` 路径及文本读写。
## 真实数据流
五个 Tab 的映射由 `MainViewModel` 构造函数定义:
| Tab | 索引文件 | 内容文件 | 源库读取方法 |
| --- | --- | --- | --- |
| 表配置 | `data/from/table.txt` | `data/{对象名}_creat.txt` | `DbServices.GetTableSql` |
| BOS 配置 | `data/from/bos.txt` | `data/{对象名}_bos.txt` | `DbServices.GetTableBos` |
| BOS 字段配置 | `data/from/bos_field.txt` | `data/{表名}.{字段名}_bos_field.txt` | `DbServices.GetTableBosField` |
| 存储过程 | `data/from/prc.txt` | `data/{对象名}_prc.txt` | `DbServices.GetPrcSql` |
| 表数据 | `data/from/data.txt` | `data/{对象名}_data.txt` | `DbServices.GetTableData` |
读取流程:索引项 -> 调用源库读取委托 -> 生成 SQL 文本 -> 保存到 `data/` -> 更新读取状态并显示内容。
读取 BOS 配置前会检查源库当前用户下的辅助过程。整表读取使用 `HMIG_GET_TABLE_BOS_31`,单字段读取使用 `HMIG_GET_TABLE_BOS_FIELD_31`;若过程不存在,程序从运行目录的同名 `pre/*.prc` 脚本安装,检查 `USER_ERRORS` 和对象状态后再读取。单字段列表项必须采用 `TABLE.COLUMN` 格式。界面不提供手动“预处理”入口。
单字段 SQL 写入目标库时,限定值组按名称、限定值按组和值判断,只补充缺失项;引用元数据按引用表名和字段 `DBNAME` 映射,目标引用字段不存在或不唯一时直接报错,不自动创建。
单字段读取还会查询源库 `USER_TABLES`、`USER_TAB_COLUMNS`。源对象是物理表且源字段存在时,输出文件首先检查目标库物理表和字段:目标表不存在时报错,目标字段不存在时按源字段的数据类型、长度、精度和字符语义执行 `ALTER TABLE ... ADD`。源对象是视图或 BOS 计算字段时不生成物理字段 DDL。
写入流程:索引项 -> 读取对应 `data/*_{后缀}.txt` -> `DbServices.ExecuteCreate` -> 在目标库执行 -> 更新写入状态。批量写入遇到第一条失败即停止,并在内存中记录断点;断点不会跨进程持久化。
删除列表项会同时删除对应内容文件。调整顺序会立即覆盖索引文件。新增对象名会被转为小写,数据库读取时再按需要转大写。
## 配置和运行时文件
- `config.ini` 保存源库和目标库的 IP/服务名、用户名、密码。当前实现是明文读写,首次运行缺失时创建空配置;发布包不得携带本机配置。Velopack 安装态/便携态必须写在与 `Update.exe` 同级的根目录,不能写回每次更新都会整体替换的 `current/`;普通未打包运行时仍写程序目录。
- 从旧版本首次更新时,`OnAfterUpdateFastCallback` 会在 Velopack 删除旧 `current/` 临时备份之前,将其中的 `config.ini` 迁移到根目录。不要移除该兼容逻辑,除非已确认所有在用旧版本完成迁移。
- 不要在日志、回答、补丁或测试输出中展示真实连接串和密码。
- 修改或发布时不要用样例配置覆盖用户现有 `config.ini`。
- `data/` 和 `pre/` 是用户可编辑、更新时需要保留的运行数据;不要无故清空、批量改名或删除。
- `error.log` 是全局异常日志,`execute_log.txt` 记录目标库执行的 SQL;两者都是运行时文件,排查时可能含敏感业务信息。
- `bin/`、`obj/`、`publish/`、`releases/`、`.vs/` 是构建、IDE 或发布产物。不要手工修改其中的 DLL、EXE、PDB、NuGet 包或生成源码。
- `*.csproj.Backup*.tmp`、`_build*`、`_make_pack.bat`、`_write_pack.ps1`、`_debug_encoding.ps1` 是历史/辅助文件;正常构建和发布不要以它们为权威入口。
## 开发约定
- 保持现有命名空间 `henlo_migration` 和现有目录分层。
- UI 状态、命令和业务编排放在 `MainViewModel`;可绑定的属性变更必须触发 `OnPropertyChanged`,命令可用性变化时同步触发 `RaiseCanExecuteChanged`。
- XAML 负责布局、样式和绑定;code-behind 仅保留必须依赖 Window/控件事件的逻辑。
- 通用 Oracle 提取/执行逻辑放在 `DbServices`,不要在 View 或 ViewModel 中复制 SQL。
- 新增 Tab 能力时同时检查 `TabsEnum`、`CodeExt`、`TabConfig`、`MainViewModel` 映射、XAML 绑定、索引文件复制规则和更新备份范围。
- 耗时数据库调用不得阻塞 UI 线程;沿用现有异步命令和 `Task.Run` 边界,UI 更新通过 WPF Dispatcher 或正常 await 回到 UI 上下文。
- 保持 SQL 文件的 Oracle 分隔约定:`DbServices.SplitStatements` 依赖换行后的 `/`(实际分隔符为 `\n/`)。修改生成 SQL 时必须验证普通 DDL、PL/SQL 块和末尾分隔符。
- 数据库对象名和用户数据不能直接拼入任意 SQL。查询参数优先使用 `SugarParameter`;确需生成 DDL 时必须处理标识符和字符串转义。
- 不要静默吞掉新异常。UI 可展示友好提示,但排障信息应保留在错误对话框或日志中;修改现有空 `catch` 时要评估用户体验。
- 不做与任务无关的大规模格式化、Nullable 改造、依赖升级或旧项目同步。
## 数据库安全边界
源库和目标库不是等价环境:
- `Get*` 方法通常查询源库;`ExecuteCreate` 明确写目标库。
- 首次读取整表或单字段 BOS 配置时可能在源库自动创建对应的 `HMIG_GET_TABLE_BOS_31` 或 `HMIG_GET_TABLE_BOS_FIELD_31`;这不是只读操作,源库账号需要相应的 `CREATE PROCEDURE` 权限。
- 连接按钮会把界面中的连接信息写回 `config.ini`,并重建同时包含源库和目标库的 SqlSugarScope。
- 界面的“断开”当前只更新连接状态,并未释放或关闭底层连接对象。
除非用户明确要求并确认数据库、对象和影响范围,否则不要连接真实数据库、触发 BOS 辅助过程安装、执行目标库写入、清理数据或测试破坏性 SQL。需要验证数据库写入逻辑时优先使用代码审查、可控测试库或事务化的最小复现。真实目标库写入前必须提醒备份并确认权限。
## 构建与验证
在仓库根目录运行:
```powershell
dotnet restore .\henlo_migration_wpf10\henlo_migration_wpf10.csproj
dotnet build .\henlo_migration_wpf10\henlo_migration_wpf10.csproj -c Debug
```
仅在依赖已经恢复且不希望访问包源时可用:
```powershell
dotnet build .\henlo_migration_wpf10\henlo_migration_wpf10.csproj -c Debug --no-restore
```
当前没有测试项目。最低验证要求:
1. 所有 C#/XAML 修改至少执行一次主项目构建。
2. 仅文档修改可不构建,但要重新读取文件检查 Markdown、路径和命令。
3. XAML/绑定修改除构建外,应在 Windows 上启动应用,检查五个 Tab、连接弹窗、按钮可用性和错误弹窗;不要因此连接生产库。
4. SQL 生成/拆分修改需用不含真实数据的代表性 SQL 验证表 DDL、注释、约束、PL/SQL 和 INSERT。
5. 更新逻辑修改需分别考虑普通 `dotnet run`(非 Velopack 安装)和 Velopack 安装态。
既有 `CS8632` 警告不是本次修改自动引入的错误,但不得新增编译错误。若任务专门处理 Nullable,应统一决定启用 Nullable 还是移除注解,不要零散压制警告。
本地调试可运行:
```powershell
dotnet run --project .\henlo_migration_wpf10\henlo_migration_wpf10.csproj
```
启动会读取或创建用户持久目录下的配置,并可能尝试初始化更新检查;不适合无界面的 CI 验证。
## 版本与发布
- 仓库根目录的 `RELEASE.md` 是当前发版流程、产物、上传和自动更新风险的权威说明。凡任务涉及版本号、Release 构建、Velopack、打包、便携包、自动更新、服务器部署或上传,必须先完整读取 `RELEASE.md`,再执行或给出结论。
- 正式版本的用户可见变更记录维护在仓库根目录 `CHANGELOG.md`,发版时必须新增对应版本条目。
- 版本号只修改 `.csproj` 中的 `<Version>`,必须单调递增;正式发布入口是 `henlo_migration_wpf10/pack.bat`。
- 发布是显式任务。未经要求不要运行打包、删除发布目录、修改版本号或上传更新服务器;构建通过不等于打包或自动更新验证通过。
- 若代码、脚本和 `RELEASE.md` 不一致,以实际代码和 `pack.bat` 为准,并在同一任务中同步修正文档。
## 完成任务时的交付说明
简要说明:修改了什么、影响哪一层、执行了哪些验证、构建是否有错误/警告、是否因缺少 Oracle 测试库或 Velopack 安装态而存在未验证项。不要声称已验证真实数据库迁移,除非确实在明确授权的测试环境完成。