a
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
# 数据导入
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
|
||||
- [IOManager.h](file://h/IOManager.h)
|
||||
- [Constant.h](file://h/Constant.h)
|
||||
- [DataOperator.h](file://h/DataOperator.h)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文件面向“数据导入”功能的完整流程进行深入文档化,重点覆盖:
|
||||
- CIOManager::Import 方法如何验证源.accdb文件的有效性(数据库版本检查、密码验证机制)
|
||||
- 导入过程中的事务管理与数据一致性保障
|
||||
- ImportProjectToDB、ImportTzToDB 等系列方法如何解析外部数据库并安全导入到当前系统数据库
|
||||
- 数据映射规则、主键处理、外键约束维护及冲突解决策略
|
||||
- 导入失败时的回滚机制与错误报告方式
|
||||
|
||||
## 项目结构
|
||||
数据导入功能位于 Managers 层,核心类为 CIOManager,负责导入与导出的统一入口;导入流程围绕 Access 数据库(.accdb)展开,使用 ADO/ADOX 进行连接与表结构创建,并通过事务保证一致性。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "导入模块"
|
||||
CIO["CIOManager<br/>导入/导出入口"]
|
||||
Imp["Import()<br/>验证与事务控制"]
|
||||
Proj["ImportProjectToDB()"]
|
||||
Tz["ImportTzToDB()"]
|
||||
Spt["ImportSptToDB()"]
|
||||
Rsp["ImportRspTdToDB()"]
|
||||
Ipsp["ImportIpspTdToDB()"]
|
||||
end
|
||||
subgraph "系统数据库"
|
||||
SysConn["_ConnectionPtr<br/>系统数据库连接"]
|
||||
Cat["ADOX::Catalog<br/>表结构管理"]
|
||||
end
|
||||
subgraph "外部数据库(.accdb)"
|
||||
ExtConn["_ConnectionPtr<br/>外部数据库连接"]
|
||||
DbVer["dbversion 表<br/>版本校验"]
|
||||
end
|
||||
CIO --> Imp
|
||||
Imp --> Proj
|
||||
Imp --> Tz
|
||||
Imp --> Spt
|
||||
Imp --> Rsp
|
||||
Imp --> Ipsp
|
||||
Imp --> SysConn
|
||||
CIO --> Cat
|
||||
Imp --> ExtConn
|
||||
ExtConn --> DbVer
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
|
||||
## 核心组件
|
||||
- CIOManager:导入/导出的统一入口,提供 Import/Export 方法,内部封装对各业务表的导入逻辑。
|
||||
- 外部数据库(.accdb):包含 project、tz、td、tdhead、parameter、rspcon、ipspcon、gr、scon、channel、script、dbversion 等表。
|
||||
- 系统数据库:通过 ADOX 创建目标表结构,使用 ADO 执行插入与更新。
|
||||
- 常量与返回码:统一的执行状态码(成功/失败/取消/重复/关联异常等),用于错误上报与流程控制。
|
||||
|
||||
章节来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 架构总览
|
||||
导入流程采用“打开外部数据库 -> 版本校验 -> 开启系统数据库事务 -> 分表导入 -> 提交或回滚”的模式。每个导入方法均以“先查询是否存在同名记录 -> 若不存在则插入 -> 存在则跳过(去重)”的策略避免重复导入;同时通过外键字段(如 PRID、TZID、PAID、SCID、DEID、TDID)将不同表之间的关系映射到系统数据库。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant M as "CIOManager"
|
||||
participant E as "外部数据库(.accdb)"
|
||||
participant S as "系统数据库"
|
||||
participant T as "事务"
|
||||
U->>M : 调用 Import()
|
||||
M->>E : 打开外部数据库并设置密码
|
||||
M->>E : 查询 dbversion 表进行版本校验
|
||||
alt 校验失败
|
||||
M-->>U : 返回取消/失败
|
||||
else 校验成功
|
||||
M->>S : BeginTrans()
|
||||
M->>S : 导入 project
|
||||
M->>S : 导入 tz
|
||||
M->>S : 导入 scon/channel/script
|
||||
M->>S : 导入 td/rspcon/ipspcon/gr
|
||||
alt 导入过程中发生异常
|
||||
M->>S : RollbackTrans()
|
||||
M-->>U : 返回失败
|
||||
else 成功
|
||||
M->>S : CommitTrans()
|
||||
M-->>U : 返回成功
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2064)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### CIOManager::Import 验证与事务控制
|
||||
- 文件选择与连接
|
||||
- 弹出文件对话框选择 .accdb 文件,构造连接字符串并设置数据库密码。
|
||||
- 设置最大锁数属性以提升并发写入能力。
|
||||
- 版本检查
|
||||
- 通过查询外部数据库的 dbversion 表,要求存在特定键值(版本标识)才视为有效外部数据库。
|
||||
- 若未命中或抛出异常,关闭连接并提示错误后返回取消/失败。
|
||||
- 事务管理
|
||||
- 成功通过版本检查后,开启系统数据库事务。
|
||||
- 按顺序调用 ImportProjectToDB、ImportTzToDB、ImportSptToDB、ImportRspTdToDB、ImportIpspTdToDB。
|
||||
- 成功则提交,失败则回滚并返回失败。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
|
||||
### ImportProjectToDB:工程表导入
|
||||
- 映射字段
|
||||
- 将外部 project 的 CN、PRname、PRdesc、location、PRdate、duration、PS、CS、PM、QAS、standard 映射到系统 project。
|
||||
- 冲突处理
|
||||
- 先按 CN 查询系统 project 是否已存在,若不存在则插入;存在则跳过。
|
||||
- 主键/唯一性
|
||||
- 以 CN 作为唯一键进行去重判断。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L2013-L2062)
|
||||
|
||||
### ImportTzToDB:测区表导入
|
||||
- 映射字段
|
||||
- 外部 tz 的 TZname、PRCN、TZdesc、location 映射到系统 tz。
|
||||
- 关系解析
|
||||
- 通过外部 tz.PRCN 查找系统 project 的 ID(PRID),再以 PRID+TZname 在系统 tz 中查重。
|
||||
- 冲突处理
|
||||
- 若系统 tz 中不存在相同 PRID+TZname,则插入;否则跳过。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2011)
|
||||
|
||||
### ImportSptToDB:脚本与通道导入
|
||||
- 映射字段
|
||||
- 外部 scon 的 CN、Sname、Eamount、CHamount、TPamount、definer、DEdate、SCdesc 映射到系统 scon。
|
||||
- 外部 channel 的 CN、CHnumber、AR 映射到系统 channel(通过 SCID 关联 scon)。
|
||||
- 外部 script2d 的 CN、CHnumber、TSN、C1、C2、P1、P2、K、N 映射到系统 script2d(通过 CHID 关联 channel)。
|
||||
- 冲突处理
|
||||
- scon:按 CN 去重;插入后获取新 ID(SCID)。
|
||||
- channel:按 CN+CHnumber 去重;插入后获取新 ID(CHID)。
|
||||
- script2d:按 CN+CHnumber+TSN 去重;插入时使用 CHID。
|
||||
- 外键维护
|
||||
- td 表导入完成后,根据外部 SCCN 更新 td.SCID 字段,完成脚本与测线的关联。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
|
||||
### ImportRspTdToDB:电阻率测线导入
|
||||
- 映射字段
|
||||
- 外部 td 的 TDname、DESN、PRCN、TZname、SCCN、TDtype、HFname、CFname、CFRamount、GRFname、GRFRamount 映射到系统 td。
|
||||
- 外部 tdhead 的 TDname、DESN、Cdate、Ctime、rolling、RCamount、Rdirection、CRtime、CPE、CPN、weather、temperature、height、humidity、PM、OP、QA 映射到系统 tdhead。
|
||||
- 外部 parameter 的 TDname、DESN 对应的 LCHamount、RCHamount、LCamount、RCamount、LEamount、REamount、Felectrode、Espacing、Clayout、CLfun 映射到系统 parameter。
|
||||
- 外部 rspcon 的 TDname、DESN 对应的 A、B、M、N、K、SP、Ro、Vp、Ip、SD、RgA、RgB、RgM、RgN、Ttime 映射到系统 rspcon。
|
||||
- 外部 gr 的 TDname、DESN 对应的 electrode、CableH、CableT、P1GR、P2GR 映射到系统 gr。
|
||||
- 关系解析
|
||||
- 通过 PRCN 获取 PRID,再通过 PRID+TZname 获取 TZID。
|
||||
- 通过 DESN 获取 DEID(设备 ID),若不存在则置为 0。
|
||||
- 通过 SCCN 获取 SCID,若不存在则置为 0。
|
||||
- 插入 parameter 后获取 PAID;插入 td 后获取 TDID;随后插入 rspcon/gr 使用 TDID。
|
||||
- 冲突处理
|
||||
- td:按 TDname+DESN 去重;不存在则插入并生成 TDID。
|
||||
- rspcon/gr:按 TDname+DESN+时间戳(或唯一组合)去重;不存在则插入。
|
||||
- 外键维护
|
||||
- 通过 PRID、TZID、PAID、SCID、DEID、TDID 维护层级关系。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1743-L1957)
|
||||
|
||||
### ImportIpspTdToDB:激电测线导入
|
||||
- 映射字段
|
||||
- 与电阻率测线类似,但映射到系统 rspcon 的字段为 SP、Ro、VP、IP、M1..M7、TH、D、Zp、FG、Am、Bm、Cm、Dm、r。
|
||||
- 关系解析与冲突处理
|
||||
- 同样基于 PRCN->PRID、PRID+TZname->TZID、DESN->DEID、SCCN->SCID、TDname+DESN->TDID 的映射链路。
|
||||
- 以 TDname+DESN 去重插入 td;随后按 TDname+DESN+唯一字段去重插入 rspcon/gr。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1741)
|
||||
|
||||
### 数据映射规则与主键/外键处理
|
||||
- 映射规则
|
||||
- 外部表字段与系统表字段一一对应,部分日期/数值类型在插入前进行格式化或空值处理。
|
||||
- 外部表中的“编号”字段(如 CN、PRCN、SCCN、DESN)作为跨表关联与去重的关键键。
|
||||
- 主键处理
|
||||
- 系统侧通过自增主键(如 scon.ID、channel.ID、script2d.ID、td.ID、parameter.ID)生成并维护。
|
||||
- 外部侧以 CN、PRCN、SCCN、DESN 等作为唯一键进行去重。
|
||||
- 外键约束维护
|
||||
- 通过 PRCN->PRID、PRID+TZname->TZID、DESN->DEID、SCCN->SCID、TDname+DESN->TDID 等映射,确保 td、rspcon、gr、parameter 等表的外键字段正确指向父表。
|
||||
- 冲突解决策略
|
||||
- 优先采用“存在即跳过”的策略,避免重复导入导致的数据冗余与索引冲突。
|
||||
- 对于脚本与测线的二次关联(如 td.SCID 的更新),在导入 scon 后统一执行,确保外键完整性。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1957)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L2013-L2062)
|
||||
|
||||
### 事务管理与一致性保障
|
||||
- 事务边界
|
||||
- 在 Import() 中开启系统数据库事务,随后依次导入各表;任一环节失败均触发回滚。
|
||||
- 错误传播
|
||||
- 导入过程中捕获 COM 错误并返回失败码;UI 层根据返回码进行提示与后续处理。
|
||||
- 并发与锁
|
||||
- 外部数据库连接设置最大锁数,减少锁竞争带来的写入阻塞。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
|
||||
### 导入失败的回滚与错误报告
|
||||
- 回滚机制
|
||||
- 导入任一阶段抛错,立即回滚系统数据库事务并关闭外部数据库连接。
|
||||
- 错误报告
|
||||
- 通过统一的状态码(成功/失败/取消/重复/关联异常等)向调用方反馈结果。
|
||||
- UI 层根据状态码弹出提示或进入错误处理流程。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 依赖关系分析
|
||||
- CIOManager 依赖系统数据库连接与 ADOX Catalog,用于创建目标表结构与执行插入。
|
||||
- 导入方法之间存在强依赖顺序:project -> tz -> scon/channel/script -> td/rspcon/ipspcon/gr。
|
||||
- 外部数据库必须包含 dbversion 表且包含特定键值,否则导入被拒绝。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CIOManager {
|
||||
+Import() uint
|
||||
+Export() uint
|
||||
-ImportProjectToDB(pImp)
|
||||
-ImportTzToDB(pImp)
|
||||
-ImportSptToDB(pImp)
|
||||
-ImportRspTdToDB(pImp)
|
||||
-ImportIpspTdToDB(pImp)
|
||||
-m_pConnection
|
||||
-m_pCatalog
|
||||
}
|
||||
class Constant {
|
||||
+APP_SUCCESS
|
||||
+APP_FAIL
|
||||
+APP_CANCLE
|
||||
+APP_DUPLICATE
|
||||
+APP_RELATION
|
||||
+APP_OVERFLOW
|
||||
+APP_DEFAULT
|
||||
}
|
||||
CIOManager --> Constant : "使用返回码"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
章节来源
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L51)
|
||||
- [Constant.h](file://h/Constant.h#L138-L151)
|
||||
|
||||
## 性能考量
|
||||
- 外部数据库写入优化
|
||||
- 在导入前设置最大锁数,降低锁竞争,提高批量写入效率。
|
||||
- 查询与去重策略
|
||||
- 通过唯一键(CN、PRCN、SCCN、DESN、TDname+DESN 等)进行去重,避免重复插入。
|
||||
- 事务粒度
|
||||
- 将所有导入步骤置于同一事务内,减少中间态,保证一致性的同时也意味着单次失败需整体回滚。
|
||||
- I/O 与网络
|
||||
- .accdb 文件通常本地存储,性能瓶颈主要在数据库写入与索引构建;建议在导入前关闭不必要的 UI 刷新与日志输出。
|
||||
|
||||
[本节为通用性能建议,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 常见问题与定位
|
||||
- 外部数据库无法打开或密码错误:检查连接字符串与密码设置;确认 .accdb 文件未损坏。
|
||||
- 版本校验失败:确认外部数据库包含 dbversion 表且包含指定键值。
|
||||
- 导入失败回滚:查看返回码与异常栈,定位具体导入方法;检查唯一键冲突与外键映射是否正确。
|
||||
- 建议排查步骤
|
||||
- 独立运行 ImportProjectToDB/ImportTzToDB,确认基础表导入成功。
|
||||
- 检查 scon/channel/script 的关联是否正确,必要时手动执行 td.SCID 更新。
|
||||
- 对照外部与系统表结构,核对字段映射与空值处理逻辑。
|
||||
|
||||
章节来源
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L100-L204)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1385-L1519)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1521-L1957)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1960-L2062)
|
||||
|
||||
## 结论
|
||||
本导入流程通过严格的版本校验、事务控制与去重策略,实现了从外部 .accdb 到系统数据库的可靠迁移。其关键特性包括:
|
||||
- 明确的验证与错误处理路径
|
||||
- 以唯一键驱动的去重与外键映射
|
||||
- 事务边界内的原子性与一致性
|
||||
- 清晰的失败回滚与状态码反馈
|
||||
|
||||
在实际部署中,建议结合业务场景对字段映射与去重策略进行微调,并在导入前做好备份与测试,以确保数据完整性与可追溯性。
|
||||
@@ -0,0 +1,293 @@
|
||||
# 数据导入导出
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
|
||||
- [IOManager.h](file://h/IOManager.h)
|
||||
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp)
|
||||
- [SComPort.cpp](file://cpp/Tools/SComPort.cpp)
|
||||
- [HandleProcessor.cpp](file://cpp/Tools/HandleProcessor.cpp)
|
||||
- [StateProcessor.cpp](file://cpp/Tools/StateProcessor.cpp)
|
||||
- [FileTransfer.h](file://h/FileTransfer.h)
|
||||
- [_zmodem.h](file://h/_zmodem.h)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [CIOManager类架构](#ciomanager类架构)
|
||||
3. [数据导出功能](#数据导出功能)
|
||||
4. [数据导入功能](#数据导入功能)
|
||||
5. [文件传输协议](#文件传输协议)
|
||||
6. [数据完整性与事务处理](#数据完整性与事务处理)
|
||||
7. [应用场景分析](#应用场景分析)
|
||||
8. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
数据导入导出模块是Geomative Studio系统中的核心功能组件,负责实现项目数据在不同环境间的迁移与共享。该模块主要通过CIOManager类实现,支持将项目、测区、脚本、测试数据等关键信息导出为Access数据库(.accdb)文件,并能从外部文件导入数据。模块采用事务处理机制确保数据一致性,通过Zmodem协议支持串口和网络数据交换,为系统升级、数据迁移等场景提供可靠支持。
|
||||
|
||||
## CIOManager类架构
|
||||
|
||||
CIOManager类是数据导入导出功能的核心实现,其架构设计体现了清晰的职责分离和模块化思想。该类主要负责协调数据导出和导入流程,与数据库交互,并管理相关辅助组件。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CIOManager {
|
||||
+_ConnectionPtr m_pConnection
|
||||
+ADOX : : _CatalogPtr m_pCatalog
|
||||
+CHandleProcessor m_handleProcessor
|
||||
+CStateProcessor m_stateProcessor
|
||||
+UINT Export()
|
||||
+UINT Import()
|
||||
-_ConnectionPtr CreateExpDatabase(CString szFileName)
|
||||
-void ExportDataToAccdbFile(_ConnectionPtr pExpConnection, CTreeCtrl& dmsTree)
|
||||
-void ImportProjectToDB(_ConnectionPtr pImpConnection)
|
||||
}
|
||||
class CHandleProcessor {
|
||||
+DWORD GenerateHandle(DWORD dwID, UINT uStyle)
|
||||
+DWORD GetIDFromHandle(DWORD dwHandle)
|
||||
+UINT GetStyleFromHandle(DWORD dwHandle)
|
||||
+void AnalyseHandle(DWORD dwHandle, DWORD& dwID, UINT& uStyle)
|
||||
}
|
||||
class CStateProcessor {
|
||||
+UINT ChangeToImageState(UINT uItemState)
|
||||
+UINT ChangeToItemState(UINT uImageState)
|
||||
}
|
||||
CIOManager --> CHandleProcessor : "使用"
|
||||
CIOManager --> CStateProcessor : "使用"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L49)
|
||||
- [HandleProcessor.cpp](file://cpp/Tools/HandleProcessor.cpp#L19-L95)
|
||||
- [StateProcessor.cpp](file://cpp/Tools/StateProcessor.cpp#L19-L40)
|
||||
|
||||
**本节来源**
|
||||
- [IOManager.h](file://h/IOManager.h#L15-L49)
|
||||
- [HandleProcessor.cpp](file://cpp/Tools/HandleProcessor.cpp#L19-L95)
|
||||
- [StateProcessor.cpp](file://cpp/Tools/StateProcessor.cpp#L19-L40)
|
||||
|
||||
## 数据导出功能
|
||||
|
||||
数据导出功能通过CIOManager::Export()方法实现,采用事务处理机制确保数据完整性。导出流程首先创建新的Access数据库文件,然后按层次结构导出项目、测区、测试数据和脚本信息。
|
||||
|
||||
### 导出工作流程
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始导出]) --> CreateDialog["创建导出对话框"]
|
||||
CreateDialog --> ShowDialog["显示导出界面"]
|
||||
ShowDialog --> UserSelect["用户选择导出内容"]
|
||||
UserSelect --> CheckSelection{"选择有效?"}
|
||||
CheckSelection --> |否| ReturnCancel["返回取消"]
|
||||
CheckSelection --> |是| CreateDatabase["创建目标数据库"]
|
||||
CreateDatabase --> BeginTrans["开始事务"]
|
||||
BeginTrans --> ExportProject["导出项目信息"]
|
||||
ExportProject --> ExportTz["导出测区信息"]
|
||||
ExportTz --> ExportTd["导出测试数据"]
|
||||
ExportTd --> ExportSpt["导出脚本信息"]
|
||||
ExportSpt --> CommitTrans["提交事务"]
|
||||
CommitTrans --> CloseDB["关闭数据库连接"]
|
||||
CloseDB --> ReturnSuccess["返回成功"]
|
||||
Exception["异常捕获"] --> RollbackTrans["回滚事务"]
|
||||
RollbackTrans --> DeleteFile["删除目标文件"]
|
||||
DeleteFile --> ReturnFail["返回失败"]
|
||||
CreateDatabase --> |失败| DeleteFile
|
||||
style Exception fill:#f9f,stroke:#333,stroke-width:2px
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L657-L656)
|
||||
|
||||
**本节来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L657-L656)
|
||||
|
||||
### 不同数据类型的导出策略
|
||||
系统针对不同类型的数据采用了差异化的导出策略:
|
||||
|
||||
| 数据类型 | 导出策略 | 相关方法 |
|
||||
|---------|---------|---------|
|
||||
| 项目数据 | 导出项目基本信息、描述、位置等 | ExportProjectToAccdbFile |
|
||||
| 测区数据 | 导出测区名称、描述、位置等,并关联项目 | ExportTzToAccdbFile |
|
||||
| 测试数据 | 根据测试类型(RSP/IPSP)分别导出,包含测试头信息和参数 | ExportRspTdToAccdbFile<br>ExportIpspTdToAccdbFile |
|
||||
| 脚本数据 | 导出脚本定义、通道配置和脚本内容 | ExportSptToAccdbFile |
|
||||
|
||||
**本节来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L894-L1383)
|
||||
|
||||
## 数据导入功能
|
||||
|
||||
数据导入功能通过CIOManager::Import()方法实现,具有严格的文件验证机制和错误处理流程。导入过程首先验证源文件的完整性和版本兼容性,然后按顺序导入各类数据。
|
||||
|
||||
### 导入工作流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as "用户"
|
||||
participant IOManager as "CIOManager"
|
||||
participant Dialog as "文件对话框"
|
||||
participant DB as "目标数据库"
|
||||
participant SourceDB as "源数据库"
|
||||
User->>IOManager : 调用Import()
|
||||
IOManager->>Dialog : 显示文件选择对话框
|
||||
Dialog-->>IOManager : 返回选择的文件路径
|
||||
IOManager->>SourceDB : 连接源数据库
|
||||
SourceDB-->>IOManager : 连接成功
|
||||
IOManager->>SourceDB : 验证数据库版本
|
||||
alt 版本验证失败
|
||||
SourceDB-->>IOManager : 返回错误
|
||||
IOManager->>User : 显示错误消息
|
||||
IOManager-->>User : 返回取消
|
||||
else 版本验证成功
|
||||
IOManager->>DB : 开始事务
|
||||
IOManager->>DB : 导入项目数据
|
||||
IOManager->>DB : 导入测区数据
|
||||
IOManager->>DB : 导入脚本数据
|
||||
IOManager->>DB : 导入测试数据
|
||||
IOManager->>DB : 提交事务
|
||||
DB-->>IOManager : 提交成功
|
||||
IOManager-->>User : 返回成功
|
||||
end
|
||||
alt 导入过程中发生异常
|
||||
IOManager->>DB : 回滚事务
|
||||
IOManager-->>User : 返回失败
|
||||
end
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L101-L204)
|
||||
|
||||
**本节来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L101-L204)
|
||||
|
||||
### 数据映射与冲突解决机制
|
||||
在导入过程中,系统采用以下机制处理数据映射和潜在冲突:
|
||||
|
||||
1. **主键映射**:使用CHandleProcessor类处理ID映射,确保对象引用关系的正确性
|
||||
2. **外键关联**:在导入测区时,根据项目CN码建立与项目的关联
|
||||
3. **冲突检测**:在导入脚本时,检查是否存在相同CN码的脚本,避免重复
|
||||
4. **数据完整性**:通过事务机制确保所有相关数据的一致性更新
|
||||
|
||||
## 文件传输协议
|
||||
|
||||
系统通过Zmodem协议实现串口和网络环境下的数据交换,提供了可靠的文件传输能力。
|
||||
|
||||
### Zmodem协议实现
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Zmodem {
|
||||
+CSComPort* port
|
||||
+FILE* file
|
||||
+long file_length
|
||||
+int file_count
|
||||
+char file_name[128]
|
||||
+BOOL Send(char* files[])
|
||||
+BOOL Receive(CString Path)
|
||||
-int SendSingleFile(char* name)
|
||||
-int ReceiveSingleFile(CString Path)
|
||||
-int WakeUpSender()
|
||||
}
|
||||
class FileTransfer {
|
||||
+CSComPort* port
|
||||
+FILE* file
|
||||
+long file_length
|
||||
+int file_count
|
||||
+char file_name[128]
|
||||
+virtual BOOL Send(char* files[])
|
||||
+virtual BOOL Receive(CString Path)
|
||||
}
|
||||
class SComPort {
|
||||
+HANDLE m_hCom
|
||||
+DCB m_dcbBlock
|
||||
+char m_aWriteBuffer[WRITEBUFFER_SIZE]
|
||||
+int m_iWriteSize
|
||||
+char m_aReadBuffer[READBUFFER_SIZE]
|
||||
+int m_iReadSize
|
||||
+BOOL OpenComm(CString szComName)
|
||||
+void CloseComm()
|
||||
+BOOL SendDataDirectly(char* pDataBuff, int iDataSize)
|
||||
+BOOL ReceiveDataDirectly(char* pDataBuff, int* iDataSize)
|
||||
+BOOL ZmodemSendDataDirectly(char* pDataBuff, int iDataSize)
|
||||
+BOOL ZmodemReceiveDataDirectly(char* pDataBuff, int* iDataSize)
|
||||
}
|
||||
Zmodem --|> FileTransfer : "继承"
|
||||
Zmodem --> SComPort : "使用"
|
||||
FileTransfer --> SComPort : "使用"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L33-L800)
|
||||
- [FileTransfer.h](file://h/FileTransfer.h#L26-L46)
|
||||
- [SComPort.cpp](file://cpp/Tools/SComPort.cpp#L31-L800)
|
||||
|
||||
**本节来源**
|
||||
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L33-L800)
|
||||
- [FileTransfer.h](file://h/FileTransfer.h#L26-L46)
|
||||
- [SComPort.cpp](file://cpp/Tools/SComPort.cpp#L31-L800)
|
||||
|
||||
### 串口与网络配置
|
||||
系统通过SComPort类实现串口通信,支持以下配置:
|
||||
|
||||
- **波特率**:115200 bps
|
||||
- **数据位**:8位
|
||||
- **停止位**:1位
|
||||
- **校验**:无校验
|
||||
- **流控制**:无
|
||||
|
||||
网络通信通过相同的接口实现,确保了传输层的透明性。
|
||||
|
||||
## 数据完整性与事务处理
|
||||
|
||||
系统采用严格的事务处理机制确保数据导入导出过程中的完整性。
|
||||
|
||||
### 事务处理机制
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[开始事务] --> B[导出项目数据]
|
||||
B --> C[导出测区数据]
|
||||
C --> D[导出测试数据]
|
||||
D --> E[导出脚本数据]
|
||||
E --> F{所有操作成功?}
|
||||
F --> |是| G[提交事务]
|
||||
F --> |否| H[回滚事务]
|
||||
G --> I[关闭连接]
|
||||
H --> J[删除文件]
|
||||
I --> K[返回成功]
|
||||
J --> L[返回失败]
|
||||
```
|
||||
|
||||
**本节来源**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L63-L78)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L177-L188)
|
||||
|
||||
### 错误回滚与文件完整性验证
|
||||
系统在数据处理过程中实施了多重保护机制:
|
||||
|
||||
1. **异常捕获**:使用try-catch块捕获COM异常
|
||||
2. **自动回滚**:发生异常时自动执行RollbackTrans()
|
||||
3. **文件验证**:导入前验证dbversion表确保文件兼容性
|
||||
4. **资源清理**:确保数据库连接和文件句柄的正确释放
|
||||
|
||||
## 应用场景分析
|
||||
|
||||
数据导入导出模块在多种实际场景中发挥重要作用:
|
||||
|
||||
### 系统升级
|
||||
在系统升级过程中,该模块可用于:
|
||||
- 迁移旧版本数据到新系统
|
||||
- 验证数据完整性
|
||||
- 保持项目历史记录
|
||||
|
||||
### 数据迁移
|
||||
支持跨设备的数据迁移:
|
||||
- 从现场设备导出数据到办公室计算机
|
||||
- 在不同项目团队间共享测试数据
|
||||
- 备份关键项目信息
|
||||
|
||||
### 协作与共享
|
||||
促进团队协作:
|
||||
- 共享脚本配置
|
||||
- 交换测试结果
|
||||
- 统一数据标准
|
||||
|
||||
## 结论
|
||||
数据导入导出模块通过CIOManager类实现了完整的数据迁移功能,采用事务处理确保数据一致性,利用Zmodem协议支持多种传输方式。该模块架构清晰,功能完善,为Geomative Studio系统的数据管理提供了可靠保障。通过严格的错误处理和完整性验证机制,确保了数据在迁移过程中的安全性和可靠性。
|
||||
@@ -0,0 +1,400 @@
|
||||
# 数据导出
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
|
||||
- [IOManager.h](file://h/IOManager.h)
|
||||
- [database_modify.xml](file://database_modify.xml)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [数据导出架构](#数据导出架构)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [事务处理与异常恢复](#事务处理与异常恢复)
|
||||
5. [数据库模式与版本控制](#数据库模式与版本控制)
|
||||
6. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文档全面阐述了Geomative Studio软件中数据导出功能的实现机制。该功能通过CIOManager类的Export方法,将项目、测区、测试数据等信息安全地导出到受密码保护的Access数据库(.accdb)文件中。文档详细说明了导出过程中的事务处理、树形结构遍历、数据库创建、异常处理和回滚机制,以及针对不同类型测试数据(如2D电阻率、IP)的导出实现细节。
|
||||
|
||||
## 数据导出架构
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[用户界面] --> B[CIOManager::Export]
|
||||
B --> C[创建加密数据库]
|
||||
C --> D[开始事务]
|
||||
D --> E[遍历树形结构]
|
||||
E --> F[选择导出内容]
|
||||
F --> G[导出项目数据]
|
||||
F --> H[导出测区数据]
|
||||
F --> I[导出测试数据]
|
||||
G --> J[ExportProjectToAccdbFile]
|
||||
H --> K[ExportTzToAccdbFile]
|
||||
I --> L[ExportRspTdToAccdbFile]
|
||||
I --> M[ExportIpspTdToAccdbFile]
|
||||
L --> N[导出电阻率数据]
|
||||
M --> O[导出IP数据]
|
||||
N --> P[提交事务]
|
||||
O --> P
|
||||
P --> Q[完成导出]
|
||||
B --> R[异常处理]
|
||||
R --> S[回滚事务]
|
||||
S --> T[删除文件]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [IOManager.h](file://h/IOManager.h#L19)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### CIOManager类分析
|
||||
CIOManager类是数据导出功能的核心,负责协调整个导出流程。它通过ADOX和ADODB技术与Access数据库进行交互。
|
||||
|
||||
#### 类结构
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CIOManager {
|
||||
+_ConnectionPtr m_pConnection
|
||||
+ADOX : : _CatalogPtr m_pCatalog
|
||||
+CHandleProcessor m_handleProcessor
|
||||
+CStateProcessor m_stateProcessor
|
||||
+UINT Export(void)
|
||||
+UINT Import(void)
|
||||
+CIOManager(_ConnectionPtr&, ADOX : : _CatalogPtr)
|
||||
+~CIOManager()
|
||||
}
|
||||
class CHandleProcessor {
|
||||
+DWORD GenerateHandle(DWORD, UINT)
|
||||
+DWORD GetIDFromHandle(DWORD)
|
||||
+UINT GetStyleFromHandle(DWORD)
|
||||
}
|
||||
class CStateProcessor {
|
||||
+UINT ChangeToImageState(UINT)
|
||||
+UINT ChangeToItemState(UINT)
|
||||
}
|
||||
CIOManager --> CHandleProcessor : "使用"
|
||||
CIOManager --> CStateProcessor : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.h](file://h/IOManager.h#L14-L48)
|
||||
- [HandleProcessor.h](file://h/HandleProcessor.h#L12-L26)
|
||||
- [StateProcessor.h](file://h/StateProcessor.h#L12-L20)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.h](file://h/IOManager.h#L14-L48)
|
||||
|
||||
### 导出流程分析
|
||||
数据导出流程从用户界面触发,通过CIOManager::Export方法启动,整个过程采用事务处理确保数据一致性。
|
||||
|
||||
#### 导出流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as 用户界面
|
||||
participant IO as CIOManager
|
||||
participant DB as Access数据库
|
||||
UI->>IO : Export()
|
||||
IO->>IO : 创建导出对话框
|
||||
IO->>IO : 显示选择树
|
||||
loop 用户选择
|
||||
IO->>IO : 处理用户事件
|
||||
end
|
||||
IO->>IO : 用户确认导出
|
||||
IO->>DB : CreateExpDatabase()
|
||||
DB-->>IO : 返回连接
|
||||
IO->>DB : BeginTrans()
|
||||
IO->>IO : ExportDataToAccdbFile()
|
||||
IO->>IO : ExportSptToAccdbFile()
|
||||
IO->>DB : CommitTrans()
|
||||
DB-->>IO : 提交成功
|
||||
IO-->>UI : 返回成功状态
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
|
||||
### 树形结构遍历
|
||||
ExportDataToAccdbFile函数负责遍历树形结构,根据用户选择导出相应的数据。
|
||||
|
||||
#### 遍历逻辑
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始遍历]) --> CheckProject["检查项目节点是否选中"]
|
||||
CheckProject --> |是| ExportProject["导出项目数据"]
|
||||
CheckProject --> |否| NextProject["下一个项目"]
|
||||
ExportProject --> CheckTz["检查测区节点是否选中"]
|
||||
CheckTz --> |是| ExportTz["导出测区数据"]
|
||||
CheckTz --> |否| NextTz["下一个测区"]
|
||||
ExportTz --> CheckTd["检查测试数据节点是否选中"]
|
||||
CheckTd --> |是| CheckType["检查测试类型"]
|
||||
CheckTd --> |否| NextTd["下一个测试数据"]
|
||||
CheckType --> |2D电阻率| ExportRsp["导出RspTd数据"]
|
||||
CheckType --> |2D IP| ExportIpsp["导出IpspTd数据"]
|
||||
ExportRsp --> NextTd
|
||||
ExportIpsp --> NextTd
|
||||
NextTd --> |有下一个| CheckTd
|
||||
NextTd --> |无下一个| NextTz
|
||||
NextTz --> |有下一个| CheckTz
|
||||
NextTz --> |无下一个| NextProject
|
||||
NextProject --> |有下一个| CheckProject
|
||||
NextProject --> |无下一个| End([遍历完成])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L657-L727)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L657-L727)
|
||||
|
||||
## 事务处理与异常恢复
|
||||
|
||||
### 事务处理机制
|
||||
数据导出采用严格的事务处理机制,确保数据的完整性和一致性。
|
||||
|
||||
#### 事务流程
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CreateDB["创建数据库文件"]
|
||||
CreateDB --> BeginTrans["开始事务"]
|
||||
BeginTrans --> ExportData["导出数据"]
|
||||
ExportData --> |成功| Commit["提交事务"]
|
||||
ExportData --> |失败| Rollback["回滚事务"]
|
||||
Commit --> CloseDB["关闭数据库"]
|
||||
Commit --> ReturnSuccess["返回成功"]
|
||||
Rollback --> CloseDB
|
||||
Rollback --> DeleteFile["删除文件"]
|
||||
Rollback --> ReturnFail["返回失败"]
|
||||
CloseDB --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L59-L78)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L59-L86)
|
||||
|
||||
### 异常处理策略
|
||||
系统实现了完善的异常处理机制,确保在导出过程中出现错误时能够正确恢复。
|
||||
|
||||
#### 异常处理
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([异常发生]) --> CatchException["捕获_com_error异常"]
|
||||
CatchException --> RollbackTrans["回滚事务"]
|
||||
RollbackTrans --> CloseConnection["关闭数据库连接"]
|
||||
CloseConnection --> DeleteFile["删除已创建的文件"]
|
||||
DeleteFile --> SetErrorCode["设置错误代码"]
|
||||
SetErrorCode --> ReturnFail["返回失败状态"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L80-L86)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L80-L86)
|
||||
|
||||
## 数据库模式与版本控制
|
||||
|
||||
### 数据库模式定义
|
||||
CreateExpDatabase函数创建具有完整模式的Access数据库,包含多个数据表。
|
||||
|
||||
#### 数据库模式
|
||||
```mermaid
|
||||
erDiagram
|
||||
project {
|
||||
string CN PK
|
||||
string PRname
|
||||
string PRdesc
|
||||
string location
|
||||
date PRdate
|
||||
smallint duration
|
||||
string PS
|
||||
string CS
|
||||
string PM
|
||||
string QAS
|
||||
string standard
|
||||
}
|
||||
tz {
|
||||
string TZname PK
|
||||
string PRCN FK
|
||||
string TZdesc
|
||||
string location
|
||||
}
|
||||
td {
|
||||
string TDname PK
|
||||
string DESN
|
||||
string PRCN FK
|
||||
string TZname FK
|
||||
string SCCN FK
|
||||
smallint TDtype
|
||||
string HFname
|
||||
string CFname
|
||||
smallint CFRamount
|
||||
string GRFname
|
||||
smallint GRFRamount
|
||||
}
|
||||
tdhead {
|
||||
string TDname PK
|
||||
string DESN
|
||||
date Cdate
|
||||
date Ctime
|
||||
boolean rolling
|
||||
smallint RCamount
|
||||
smallint Rdirection
|
||||
smallint CRtime
|
||||
string CPE
|
||||
string CPN
|
||||
smallint weather
|
||||
smallint temperature
|
||||
smallint height
|
||||
smallint humidity
|
||||
string PM
|
||||
string OP
|
||||
string QA
|
||||
}
|
||||
parameter {
|
||||
string TDname PK
|
||||
string DESN
|
||||
smallint LCHamount
|
||||
smallint RCHamount
|
||||
smallint LCamount
|
||||
smallint RCamount
|
||||
smallint LEamount
|
||||
smallint REamount
|
||||
smallint Felectrode
|
||||
smallint Espacing
|
||||
smallint Clayout
|
||||
smallint CLfun
|
||||
}
|
||||
rspcon {
|
||||
string TDname PK
|
||||
string DESN
|
||||
smallint A
|
||||
smallint B
|
||||
smallint M
|
||||
smallint N
|
||||
single K
|
||||
single SP
|
||||
single Ro
|
||||
single Vp
|
||||
single Ip
|
||||
single SD
|
||||
single RgA
|
||||
single RgB
|
||||
single RgM
|
||||
single RgN
|
||||
date Ttime
|
||||
}
|
||||
ipspcon {
|
||||
string TDname PK
|
||||
string DESN
|
||||
single SP
|
||||
single Ro
|
||||
single VP
|
||||
single IP
|
||||
single M1
|
||||
single M2
|
||||
single M3
|
||||
single M4
|
||||
single M5
|
||||
single M6
|
||||
single M7
|
||||
single TH
|
||||
single D
|
||||
single Zp
|
||||
single FG
|
||||
single Am
|
||||
single Bm
|
||||
single Cm
|
||||
single Dm
|
||||
single r
|
||||
}
|
||||
gr {
|
||||
string TDname PK
|
||||
string DESN
|
||||
string electrode
|
||||
string CableH
|
||||
string CableT
|
||||
single P1GR
|
||||
single P2GR
|
||||
}
|
||||
scon {
|
||||
string CN PK
|
||||
string Sname
|
||||
smallint Eamount
|
||||
smallint CHamount
|
||||
smallint TPamount
|
||||
string definer
|
||||
date DEdate
|
||||
string SCdesc
|
||||
}
|
||||
channel {
|
||||
string CN PK
|
||||
smallint CHnumber
|
||||
smallint AR
|
||||
}
|
||||
script {
|
||||
string CN PK
|
||||
smallint CHnumber
|
||||
smallint TSN
|
||||
smallint C1
|
||||
smallint C2
|
||||
smallint P1
|
||||
smallint P2
|
||||
single K
|
||||
smallint N
|
||||
}
|
||||
dbversion {
|
||||
string VK PK
|
||||
}
|
||||
project ||--o{ tz : "包含"
|
||||
tz ||--o{ td : "包含"
|
||||
td ||--|| tdhead : "关联"
|
||||
td ||--|| parameter : "关联"
|
||||
td ||--o{ rspcon : "包含"
|
||||
td ||--o{ ipspcon : "包含"
|
||||
td ||--o{ gr : "包含"
|
||||
scon ||--o{ channel : "包含"
|
||||
scon ||--o{ script : "包含"
|
||||
td }|--|| scon : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L206-L656)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L206-L656)
|
||||
|
||||
### 版本控制机制
|
||||
系统通过dbversion表实现数据库版本控制,确保导入导出的兼容性。
|
||||
|
||||
#### 版本控制流程
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([导入文件]) --> ReadVersion["读取dbversion表"]
|
||||
ReadVersion --> |版本匹配| Continue["继续导入"]
|
||||
ReadVersion --> |版本不匹配| ShowError["显示文件错误"]
|
||||
Continue --> ImportData["导入数据"]
|
||||
ImportData --> UpdateVersion["更新版本信息"]
|
||||
UpdateVersion --> End([完成])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L133-L158)
|
||||
- [database_modify.xml](file://database_modify.xml#L2)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp#L847-L872)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L133-L158)
|
||||
- [database_modify.xml](file://database_modify.xml#L2)
|
||||
- [UpdateDataBase.cpp](file://cpp/Operator/UpdateDataBase.cpp#L847-L872)
|
||||
|
||||
## 结论
|
||||
Geomative Studio的数据导出功能通过CIOManager类实现了安全、可靠的数据导出机制。系统采用事务处理确保数据一致性,通过密码保护的Access数据库文件保证数据安全。导出过程支持树形结构选择,允许用户灵活选择要导出的内容。异常处理和回滚机制确保了在导出失败时系统能够正确恢复。数据库模式设计完整,涵盖了项目、测区、测试数据等所有必要信息,并通过版本控制机制保证了数据的兼容性。该实现为地质勘探数据的管理和共享提供了可靠的技术支持。
|
||||
@@ -0,0 +1,314 @@
|
||||
# 文件传输协议
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp)
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h)
|
||||
- [checkupdate.cpp](file://cpp/Tools/checkupdate.cpp)
|
||||
- [LicenseUpgrade.cpp](file://cpp/Operator/LicenseUpgrade.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目结构](#项目结构)
|
||||
2. [核心组件](#核心组件)
|
||||
3. [架构概述](#架构概述)
|
||||
4. [详细组件分析](#详细组件分析)
|
||||
5. [依赖分析](#依赖分析)
|
||||
6. [性能考虑](#性能考虑)
|
||||
7. [故障排除指南](#故障排除指南)
|
||||
8. [结论](#结论)
|
||||
|
||||
## 项目结构
|
||||
|
||||
该项目包含多个模块,其中文件传输功能主要位于`cpp/Tools/`目录下。关键文件包括`FileTransfer_crul.cpp`和`FileTransfer_crul.h`,它们实现了基于libcurl的HTTP/HTTPS文件下载功能。日志文件存储在`LOG/`目录下的`filetrans_crul_log.txt`中。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[文件传输系统] --> B[FileTransfer_crul.h]
|
||||
A --> C[FileTransfer_crul.cpp]
|
||||
B --> D[CFileTransfer_crul类]
|
||||
C --> D
|
||||
D --> E[DownloadFile方法]
|
||||
D --> F[WriteToFile回调]
|
||||
D --> G[GetUrlResConValild方法]
|
||||
H[日志系统] --> I[LOG\\filetrans_crul_log.txt]
|
||||
D --> I
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L55-L108)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L24-L62)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L1-L111)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L1-L493)
|
||||
|
||||
## 核心组件
|
||||
|
||||
`CFileTransfer_crul`类封装了libcurl库的功能,提供了一个高层接口用于HTTP/HTTPS文件下载。该类支持连接超时设置、进度回调、错误处理等特性,并实现了安全的HTTPS传输(不验证SSL证书)。
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L55-L108)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L24-L62)
|
||||
|
||||
## 架构概述
|
||||
|
||||
该文件传输系统采用面向对象的设计模式,通过`CFileTransfer_crul`类封装libcurl的所有功能。系统支持同步文件下载,具有完整的错误处理机制和日志记录功能。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CFileTransfer_crul {
|
||||
+m_strUrl : CString
|
||||
+m_strSavePath : CString
|
||||
+m_strSaveName : CString
|
||||
+m_nTimeOut : int
|
||||
+m_bIsNeedProgress : bool
|
||||
+m_bIsHttpsFlag : bool
|
||||
+m_bIsSSLCertify : bool
|
||||
+DownloadFile() : bool
|
||||
+SetOption() : void
|
||||
+GetUrlResConValild() : bool
|
||||
+WriteToFile() : size_t
|
||||
+PrintLog() : void
|
||||
+InitalLogInfo() : void
|
||||
}
|
||||
CFileTransfer_crul --> "1" "curl_easy_init" : 使用
|
||||
CFileTransfer_crul --> "1" "LOG\\filetrans_crul_log.txt" : 写入日志
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L55-L108)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L24-L62)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### CFileTransfer_crul类分析
|
||||
|
||||
`CFileTransfer_crul`类是整个文件传输系统的核心,它封装了libcurl的所有功能,提供了简洁易用的接口。
|
||||
|
||||
#### 类结构分析
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CFileTransfer_crul {
|
||||
<<class>>
|
||||
+m_pCrEasyHandl : CURL*
|
||||
+m_strUrl : CString
|
||||
+m_strSavePath : CString
|
||||
+m_strSaveName : CString
|
||||
+m_nTimeOut : int
|
||||
+m_bIsNeedProgress : bool
|
||||
+m_bIsNeedErrInfo : bool
|
||||
+m_bIsHttpsFlag : bool
|
||||
+m_bIsSSLCertify : bool
|
||||
+m_pLog : FILE*
|
||||
+m_lTotalRecvFileSize : curl_off_t
|
||||
+m_lCurRecvSize : curl_off_t
|
||||
+m_nWriteFileSize : static int
|
||||
+m_RecvFileSize : static DOUBLE
|
||||
+CFileTransfer_crul()
|
||||
+~CFileTransfer_crul()
|
||||
+Inital() : bool
|
||||
+UnInital() : void
|
||||
+SetOption() : void
|
||||
+DownloadFile() : bool
|
||||
+GetUrlResConValild() : bool
|
||||
+WriteToFile() : static size_t
|
||||
+xferinfo() : static int
|
||||
+PrintLog() : void
|
||||
+InitalLogInfo() : void
|
||||
}
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L55-L108)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L24-L62)
|
||||
|
||||
#### 下载流程分析
|
||||
|
||||
`DownloadFile`方法执行完整的文件下载流程,从URL验证到文件写入:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant FileTransfer as "CFileTransfer_crul"
|
||||
participant Curl as "libcurl"
|
||||
participant File as "目标文件"
|
||||
Client->>FileTransfer : 调用DownloadFile()
|
||||
FileTransfer->>FileTransfer : 验证参数
|
||||
FileTransfer->>FileTransfer : 检查HTTPS设置
|
||||
FileTransfer->>FileTransfer : 调用GetUrlResConValild()
|
||||
FileTransfer->>Curl : curl_easy_init()
|
||||
FileTransfer->>Curl : 设置各种选项
|
||||
FileTransfer->>Curl : CURLOPT_URL
|
||||
FileTransfer->>Curl : CURLOPT_TIMEOUT
|
||||
FileTransfer->>Curl : CURLOPT_WRITEFUNCTION
|
||||
FileTransfer->>Curl : CURLOPT_SSL_VERIFYPEER
|
||||
FileTransfer->>File : fopen()
|
||||
FileTransfer->>Curl : curl_easy_perform()
|
||||
Curl->>FileTransfer : 数据块
|
||||
FileTransfer->>FileTransfer : WriteToFile回调
|
||||
FileTransfer->>File : fwrite()
|
||||
FileTransfer->>FileTransfer : 更新进度
|
||||
Curl->>FileTransfer : 下载完成
|
||||
FileTransfer->>File : fclose()
|
||||
FileTransfer->>Curl : curl_easy_cleanup()
|
||||
FileTransfer->>Client : 返回结果
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L150-L280)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L150-L280)
|
||||
|
||||
### 数据写入与完整性校验
|
||||
|
||||
`WriteToFile`回调函数负责将接收到的数据流式写入文件,并进行完整性校验。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始写入]) --> ValidateInput["验证输入参数"]
|
||||
ValidateInput --> WriteData["调用fwrite写入数据"]
|
||||
WriteData --> CheckResult{"写入结果检查"}
|
||||
CheckResult --> |成功| UpdateCounter["更新写入计数器"]
|
||||
CheckResult --> |失败| LogError["记录错误日志"]
|
||||
UpdateCounter --> ReturnResult["返回写入大小"]
|
||||
LogError --> ReturnResult
|
||||
ReturnResult --> End([结束])
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L283-L309)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L283-L309)
|
||||
|
||||
### HTTPS安全策略
|
||||
|
||||
系统支持HTTPS但不支持SSL证书验证的安全策略,这在特定环境下提供了灵活性。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CheckHTTPS{"是否HTTPS?"}
|
||||
CheckHTTPS --> |是| CheckCertify{"是否需要SSL验证?"}
|
||||
CheckCertify --> |否| DisableVerify["设置CURLOPT_SSL_VERIFYPEER=0"]
|
||||
DisableVerify --> Continue["继续下载流程"]
|
||||
CheckCertify --> |是| ShowError["显示不支持SSL验证错误"]
|
||||
ShowError --> End["结束"]
|
||||
CheckHTTPS --> |否| Continue
|
||||
Continue --> End
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L161-L169)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L230-L233)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L161-L169)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L230-L233)
|
||||
|
||||
### 传输日志记录机制
|
||||
|
||||
系统实现了详细的日志记录机制,所有操作都会被记录到`LOG\filetrans_crul_log.txt`文件中。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CFileTransfer_crul {
|
||||
+m_pLog : FILE*
|
||||
+InitalLogInfo() : void
|
||||
+PrintLog() : void
|
||||
}
|
||||
CFileTransfer_crul --> "1" "LOG\\filetrans_crul_log.txt" : 写入日志
|
||||
CFileTransfer_crul --> "1" "SYSTEMTIME g_sysCurTime" : 获取时间
|
||||
```
|
||||
|
||||
日志格式包含时间戳和详细信息:
|
||||
```
|
||||
YYYY-MM-DD HH:MM:SS.MMM [行号] 日志内容
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L64-L77)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L474-L487)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L64-L77)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L474-L487)
|
||||
|
||||
### 资源可用性验证
|
||||
|
||||
`GetUrlResConValild`函数通过HEAD请求验证资源可用性,确保下载前资源存在。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FileTransfer as "CFileTransfer_crul"
|
||||
participant Curl as "libcurl"
|
||||
FileTransfer->>Curl : curl_easy_init()
|
||||
FileTransfer->>Curl : 设置CURLOPT_URL
|
||||
FileTransfer->>Curl : 设置CURLOPT_TIMEOUT
|
||||
FileTransfer->>Curl : 设置CURLOPT_NOBODY=1
|
||||
FileTransfer->>Curl : 设置CURLOPT_HEADER=1
|
||||
FileTransfer->>Curl : 设置WriteFuncForUrlTest
|
||||
FileTransfer->>Curl : 执行3次curl_easy_perform
|
||||
loop 重试机制
|
||||
Curl->>FileTransfer : 返回结果
|
||||
FileTransfer->>FileTransfer : 检查是否CURLE_OK
|
||||
end
|
||||
FileTransfer->>Curl : curl_easy_getinfo获取响应码
|
||||
FileTransfer->>FileTransfer : 检查响应码是否为200
|
||||
FileTransfer->>Curl : curl_easy_cleanup()
|
||||
FileTransfer->>调用者 : 返回验证结果
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L354-L427)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L354-L427)
|
||||
|
||||
## 依赖分析
|
||||
|
||||
该文件传输系统依赖于libcurl库和Windows API,与其他模块通过清晰的接口进行交互。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[CFileTransfer_crul] --> B[libcurl]
|
||||
A --> C[Windows API]
|
||||
A --> D[LOG\\filetrans_crul_log.txt]
|
||||
B --> E[SSL/TLS]
|
||||
B --> F[HTTP/HTTPS协议]
|
||||
C --> G[文件系统]
|
||||
C --> H[网络接口]
|
||||
I[checkupdate.cpp] --> A
|
||||
J[LicenseUpgrade.cpp] --> A
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L7-L21)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L21-L493)
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.h](file://h/FileTransfer_crul.h#L7-L21)
|
||||
- [checkupdate.cpp](file://cpp/Tools/checkupdate.cpp#L735-L741)
|
||||
- [LicenseUpgrade.cpp](file://cpp/Operator/LicenseUpgrade.cpp#L246-L247)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
该实现采用了流式写入方式,避免了内存中缓存整个文件,从而提高了大文件下载的性能。同时,通过设置合理的超时值和重试机制,增强了网络不稳定环境下的可靠性。
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
当文件下载出现问题时,可以检查以下方面:
|
||||
1. 查看`LOG\filetrans_crul_log.txt`中的详细日志
|
||||
2. 确认URL格式正确且资源可用
|
||||
3. 检查保存路径是否有写入权限
|
||||
4. 验证网络连接是否正常
|
||||
5. 检查超时设置是否合理
|
||||
|
||||
**本节来源**
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L244-L263)
|
||||
- [FileTransfer_crul.cpp](file://cpp/Tools/FileTransfer_crul.cpp#L400-L408)
|
||||
|
||||
## 结论
|
||||
|
||||
`CFileTransfer_crul`类提供了一个完整、可靠的基于libcurl的文件传输解决方案。它封装了复杂的libcurl API,提供了简洁易用的接口,同时具备完善的错误处理和日志记录功能。该实现支持HTTP/HTTPS协议,采用流式写入方式,适合大文件下载场景。通过HEAD请求预验证资源可用性,提高了下载成功率。日志系统详细记录了所有操作,便于问题排查和系统维护。
|
||||
Reference in New Issue
Block a user