dragonfly/manager/configsvc/orm_store.go

181 lines
4.9 KiB
Go

package configsvc
import (
"context"
"d7y.io/dragonfly/v2/manager/config"
"d7y.io/dragonfly/v2/pkg/dfcodes"
"d7y.io/dragonfly/v2/pkg/dferrors"
"errors"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"sort"
"time"
)
type ormStore struct {
db *gorm.DB
table string
}
type OrmConfig struct {
ID string `gorm:"primary_key"`
Object string `gorm:"size:255"`
Type string `gorm:"size:255"`
Version uint64 `gorm:"index:order_version"`
Data []byte `gorm:"data"`
CreatedAt time.Time `gorm:"create_at"`
UpdatedAt time.Time `gorm:"update_at"`
Deleted gorm.DeletedAt `gorm:"index"`
}
func ormConfig2InnerConfig(config *OrmConfig) *Config {
return &Config{
ID: config.ID,
Object: config.Object,
Type: config.Type,
Version: config.Version,
Data: config.Data,
CreateAt: config.CreatedAt,
UpdateAt: config.UpdatedAt,
}
}
func innerConfig2OrmConfig(config *Config) *OrmConfig {
now := time.Now()
return &OrmConfig{
ID: config.ID,
Object: config.Object,
Type: config.Type,
Version: config.Version,
Data: config.Data,
CreatedAt: now,
UpdatedAt: now,
}
}
func NewOrmStore(cfg *config.StoreConfig) (Store, error) {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
cfg.Mysql.User, cfg.Mysql.Password, cfg.Mysql.IP, cfg.Mysql.Port, cfg.Mysql.Db)
if db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}); err != nil {
return nil, err
} else {
orm := &ormStore{
db: db,
table: cfg.Mysql.Table,
}
if err := orm.withTable().AutoMigrate(&OrmConfig{}); err != nil {
return nil, err
} else {
return orm, nil
}
}
}
func (orm *ormStore) withTable() (tx *gorm.DB) {
if orm.table != "" {
return orm.db.Table(orm.table)
} else {
return orm.db
}
}
func (orm *ormStore) AddConfig(ctx context.Context, id string, config *Config) (*Config, error) {
cfg := innerConfig2OrmConfig(config)
cfg.ID = id
tx := orm.withTable().Create(cfg)
if tx.Error != nil {
return nil, dferrors.Newf(dfcodes.ManagerStoreError, "add config error: %s", tx.Error.Error())
} else {
return ormConfig2InnerConfig(cfg), nil
}
}
func (orm *ormStore) DeleteConfig(ctx context.Context, id string) (*Config, error) {
cfg := &OrmConfig{
ID: id,
}
tx := orm.withTable().Delete(cfg)
if err := tx.Error; errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
} else if err != nil {
return nil, dferrors.Newf(dfcodes.ManagerStoreError, "delete config error: %s", err.Error())
} else {
return ormConfig2InnerConfig(cfg), nil
}
}
func (orm *ormStore) UpdateConfig(ctx context.Context, id string, config *Config) (*Config, error) {
cfg := innerConfig2OrmConfig(config)
cfg.ID = id
tx := orm.withTable().Updates(cfg)
if err := tx.Error; errors.Is(err, gorm.ErrRecordNotFound) {
return nil, dferrors.Newf(dfcodes.ManagerConfigNotFound, "update config error: %s", err.Error())
} else if err != nil {
return nil, dferrors.Newf(dfcodes.ManagerStoreError, "update config error: %s", err.Error())
} else {
return ormConfig2InnerConfig(cfg), nil
}
}
func (orm *ormStore) GetConfig(ctx context.Context, id string) (*Config, error) {
cfg := &OrmConfig{
ID: id,
}
tx := orm.withTable().Find(cfg)
if err := tx.Error; errors.Is(err, gorm.ErrRecordNotFound) {
return nil, dferrors.Newf(dfcodes.ManagerConfigNotFound, "get config error: %s", err.Error())
} else if err != nil {
return nil, dferrors.Newf(dfcodes.ManagerStoreError, "get config error: %s", err.Error())
} else {
return ormConfig2InnerConfig(cfg), nil
}
}
func (orm *ormStore) ListConfigs(ctx context.Context, object string) ([]*Config, error) {
return orm.listSortedConfig(ctx, object, 0)
}
func (orm *ormStore) LatestConfig(ctx context.Context, object string, objType string) (*Config, error) {
configs, err := orm.listSortedConfig(ctx, object, 1)
if err != nil {
return nil, err
} else {
return configs[0], nil
}
}
func (orm *ormStore) listSortedConfig(ctx context.Context, object string, maxLen uint32) ([]*Config, error) {
var ormConfigs []OrmConfig
configs := make([]*Config, 0)
tx := orm.withTable().Where("object = ?", object).Find(&ormConfigs)
if err := tx.Error; errors.Is(err, gorm.ErrRecordNotFound) {
return nil, dferrors.Newf(dfcodes.ManagerConfigNotFound, "list sorted config error %s, object %s, maxLen %d%s", object, maxLen, err.Error())
} else if err != nil {
return nil, dferrors.Newf(dfcodes.ManagerStoreError, "list sorted config error %s, object %s, maxLen %d", object, maxLen, err.Error())
} else {
for _, cfg := range ormConfigs {
configs = append(configs, ormConfig2InnerConfig(&cfg))
}
}
if len(configs) <= 0 {
return nil, dferrors.Newf(dfcodes.ManagerConfigNotFound, "list sorted config empty, object %s, maxLen %d", object, maxLen)
}
sort.Sort(SortConfig(configs))
len := uint32(len(configs))
if maxLen == 0 || len <= maxLen {
return configs, nil
} else {
return configs[0:maxLen], nil
}
}