61 lines
1 KiB
Go
61 lines
1 KiB
Go
package system
|
|
|
|
import (
|
|
"wpw-common/internal"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type SystemKV struct {
|
|
gorm.Model
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
type system struct {
|
|
logger *zap.SugaredLogger
|
|
db *gorm.DB
|
|
}
|
|
|
|
var Default system
|
|
|
|
func (s *system) init(appCtx *internal.AppContext) {
|
|
logger := appCtx.Logger.Sugar().Named("system")
|
|
db, exist := appCtx.Data["db"]
|
|
if !exist {
|
|
logger.Fatal("system requires `db` in application context")
|
|
}
|
|
s.logger = logger
|
|
s.db = db.(*gorm.DB)
|
|
s.db.AutoMigrate(&SystemKV{})
|
|
}
|
|
|
|
func (s *system) DoOnce(key string, fn func() error) (err error) {
|
|
var kv SystemKV
|
|
kv.Key = key
|
|
tx := s.db.First(&kv)
|
|
if err = tx.Error; err == gorm.ErrRecordNotFound {
|
|
s.logger.Info("doOnce call",
|
|
"key", key)
|
|
if err = fn(); err != nil {
|
|
|
|
return
|
|
}
|
|
tx = s.db.Create(&kv)
|
|
if err = tx.Error; err != nil {
|
|
return
|
|
}
|
|
} else if err == nil {
|
|
s.logger.Infow("doOnce done",
|
|
"key", key,
|
|
"at", kv.CreatedAt)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func Init(appCtx *internal.AppContext) {
|
|
Default.init(appCtx)
|
|
}
|