emspara.go 2.2 KB

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