package memorydb import ( "context" "errors" "git.5iot.com/iotlcm-public/iotlcm-app/internal/cmd/inithttp" "git.5iot.com/iotlcm-public/iotlcm-app/internal/model" "git.5iot.com/iotlcm-public/iotlcm-app/internal/service" "time" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" ) var db gdb.DB type memDB interface { Init(ctx context.Context) error EventHandler(ctx context.Context) error TableName(ctx context.Context) string CreateTable(ctx context.Context) error LoadData(ctx context.Context, pk int64) error DeleteData(ctx context.Context, ids []int64) error } var memDBMap = make(map[string]memDB) func RegisterMemDB(name string, memDB memDB) { memDBMap[name] = memDB } type sMemoryDB struct { memDBMap map[string]interface{} } func NewMemoryDB() *sMemoryDB { return &sMemoryDB{} } func init() { service.RegisterMemoryDB(NewMemoryDB()) inithttp.RegisterHttpInitFunc("memorydb", func(ctx context.Context) error { return service.MemoryDB().Init(ctx) }) } func (s *sMemoryDB) Init(ctx context.Context) error { link := g.Cfg().MustGet(ctx, "database.memorydb.link", "").String() debug := g.Cfg().MustGet(ctx, "database.memorydb.debug", "false").Bool() if link == "" { g.Log().Warning(ctx, "sMemoryDB.Init link is empty") return nil } g.Log().Debug(ctx, "sMemoryDB.Init link", link) var err error db, err = gdb.New(gdb.ConfigNode{ Link: link, MaxIdleConnCount: 10, MaxOpenConnCount: 1, MaxConnLifeTime: 24 * 3650 * time.Hour, Debug: debug, }) if err != nil { g.Log().Errorf(ctx, "sMemoryDB.Init get db err: %v", err) return err } if db == nil { g.Log().Errorf(ctx, "sMemoryDB.Init not found memorydb") return errors.New("sMemoryDB.Init get db err") } for _, memDB := range memDBMap { err = memDB.Init(ctx) if err != nil { return err } } g.Log().Debug(ctx, "sMemoryDB.Init end.", db.GetConfig()) return nil } func (s *sMemoryDB) EventHandler(ctx context.Context, chg *model.BroadcastDbChgCache) error { memDB, ok := memDBMap[chg.TableName] if !ok { return nil } if chg.Type == "add" || chg.Type == "edit" { for _, pk := range chg.PK { memDB.LoadData(ctx, pk) } } else if chg.Type == "del" { memDB.DeleteData(ctx, chg.PK) } return nil } func (s *sMemoryDB) DB(ctx context.Context) gdb.DB { link := g.Cfg().MustGet(ctx, "database.memorydb.link", "sqlite::@file(:memory:)").String() if link == "" { return g.DB() } return db } func (s *sMemoryDB) Ctx(ctx context.Context) gdb.DB { return s.DB(ctx).Ctx(ctx) } func entityListToDo[E any, D any](source []*E) ([]*D, error) { target := make([]*D, 0, len(source)) for _, item := range source { if item == nil { continue } value := new(D) if err := gconv.Struct(item, value); err != nil { return nil, err } target = append(target, value) } return target, nil }