| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- // Package emspara EMS 参数(PID / VID)字典:SQLite -> Redis。
- //
- // 字典的生成与使用:
- // 1. 部署时由 updateCmd 从 EMS 头文件 vid_macro.h / pid_macro.h 生成 SQLite,拷贝到部署目录(cmd/deploy_emspara.sh);
- // 2. 进程启动时调用 Init,把 SQLite 整体加载到 Redis(主服务与 fwh-agent-mcp 都会加载,替换是原子的);
- // 3. 查询走 Redis(repositories.GetEmsparaVidInfo / GetEmsparaPidInfo);发现 Redis 中没有字典时自动重新加载。
- package emspara
- import (
- "fmt"
- "fwh-toolbox-server/domain"
- "fwh-toolbox-server/repositories"
- "os"
- "go.uber.org/zap"
- "gorm.io/driver/sqlite"
- "gorm.io/gorm"
- "gorm.io/gorm/logger"
- )
- // DefaultDBPath 字典 SQLite 的默认位置(相对工作目录,即部署目录 /var/www/fwh-toolbox/server)
- const DefaultDBPath = "./emspara.db"
- // Init 启动时加载字典到 Redis,并注册“Redis 中没有字典时重新加载”的回调。
- // 加载失败只记录日志,不影响进程启动:查询时会再次尝试。
- func Init(dbPath string) {
- repositories.SetEmsparaLoader(func() error { return SyncRedis(dbPath) })
- if err := SyncRedis(dbPath); err != nil {
- zap.L().Error("[emspara] 加载 EMS 参数字典到 Redis 失败", zap.String("db", dbPath), zap.Error(err))
- return
- }
- zap.L().Info("[emspara] EMS 参数字典已加载到 Redis", zap.String("db", dbPath))
- }
- // SyncRedis 全量同步 SQLite -> Redis
- func SyncRedis(dbPath string) error {
- // 文件不存在时 SQLite 会新建空库,先检查,给出明确的错误
- if _, err := os.Stat(dbPath); err != nil {
- return fmt.Errorf("字典文件不可用(部署时由 cmd/deploy_emspara.sh 生成): %w", err)
- }
- // 只读打开,不建表、不写入
- db, err := gorm.Open(sqlite.Open("file:"+dbPath+"?mode=ro"), &gorm.Config{Logger: logger.Discard})
- if err != nil {
- return fmt.Errorf("failed to connect database: %w", err)
- }
- if sqlDB, err := db.DB(); err == nil {
- defer sqlDB.Close()
- }
- var vidMacros []domain.ParamsVidMacroModel
- if err := db.Find(&vidMacros).Error; err != nil {
- return err
- }
- var pidMacros []domain.ParamsPidMacroModel
- if err := db.Find(&pidMacros).Error; err != nil {
- return err
- }
- return repositories.UpdateEmspara(vidMacros, pidMacros)
- }
|