From 74fa432ad79330fa628246a58c1f870514f55ce2 Mon Sep 17 00:00:00 2001 From: zijiren233 Date: Mon, 20 Nov 2023 12:14:51 +0800 Subject: [PATCH] Feat: db update --- cmd/setting/set.go | 11 +---- internal/bootstrap/setting.go | 48 +++++++++++++++++++- internal/db/db.go | 5 ++- internal/db/update.go | 56 ++++++++++++++++++++++++ internal/model/setting.go | 9 ++-- internal/settings/bool.go | 51 ++++++++++++++++------ internal/settings/floate64.go | 74 ++++++++++++++++++++++++------- internal/settings/int64.go | 78 +++++++++++++++++++++++++-------- internal/settings/setting.go | 82 ++--------------------------------- internal/settings/string.go | 70 +++++++++++++++++++++++------- internal/settings/var.go | 50 +++++++++++++++------ 11 files changed, 367 insertions(+), 167 deletions(-) create mode 100644 internal/db/update.go diff --git a/cmd/setting/set.go b/cmd/setting/set.go index 82b6578..456b323 100644 --- a/cmd/setting/set.go +++ b/cmd/setting/set.go @@ -29,18 +29,11 @@ var SetCmd = &cobra.Command{ if !ok { return errors.New("setting not found") } - current := s.Raw() - err := s.SetRaw(args[1]) + err := s.SetString(args[1]) if err != nil { - s.SetRaw(current) fmt.Printf("set setting %s error: %v\n", args[0], err) } - if v := s.Interface(); err != nil { - s.SetRaw(current) - fmt.Printf("set setting %s error: %v\n", args[0], err) - } else { - fmt.Printf("set setting success:\n%s: %v\n", args[0], v) - } + fmt.Printf("set setting success:\n%s: %v\n", args[0], s.Interface()) return nil }, } diff --git a/internal/bootstrap/setting.go b/internal/bootstrap/setting.go index aa0c24e..9722642 100644 --- a/internal/bootstrap/setting.go +++ b/internal/bootstrap/setting.go @@ -3,9 +3,55 @@ package bootstrap import ( "context" + "github.com/synctv-org/synctv/internal/db" + "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/settings" ) func InitSetting(ctx context.Context) error { - return settings.Init() + return initAndFixSettings(settings.Settings) +} + +func initSettings(s map[string]settings.Setting) error { + for _, b := range s { + s := &model.Setting{ + Name: b.Name(), + Value: b.DefaultString(), + Type: b.Type(), + Group: b.Group(), + } + err := db.FirstOrCreateSettingItemValue(s) + if err != nil { + return err + } + err = b.Init(s.Value) + if err != nil { + return err + } + } + return nil +} + +func initAndFixSettings(s map[string]settings.Setting) error { + for _, b := range s { + s := &model.Setting{ + Name: b.Name(), + Value: b.DefaultString(), + Type: b.Type(), + Group: b.Group(), + } + err := db.FirstOrCreateSettingItemValue(s) + if err != nil { + return err + } + err = b.Init(s.Value) + if err != nil { + // auto fix + err = b.SetString(b.DefaultString()) + if err != nil { + return err + } + } + } + return nil } diff --git a/internal/db/db.go b/internal/db/db.go index 476ab0a..dbd68b6 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -32,7 +32,10 @@ func AutoMigrate(dst ...any) error { default: log.Fatalf("unknown database type: %s", conf.Conf.Database.Type) } - return err + if err != nil { + return err + } + return upgradeDatabase() } func DB() *gorm.DB { diff --git a/internal/db/update.go b/internal/db/update.go new file mode 100644 index 0000000..24ba499 --- /dev/null +++ b/internal/db/update.go @@ -0,0 +1,56 @@ +package db + +import ( + log "github.com/sirupsen/logrus" + "github.com/synctv-org/synctv/internal/model" +) + +type dbVersion struct { + NextVersion string + Upgrade func() error +} + +var dbVersions = map[string]dbVersion{ + "0.0.1": { + NextVersion: "", + Upgrade: nil, + }, +} + +func upgradeDatabase() error { + setting := model.Setting{ + Name: "database_version", + Type: model.SettingTypeString, + Group: model.SettingGroupDatabase, + Value: "0.0.1", + } + err := FirstOrCreateSettingItemValue(&setting) + if err != nil { + return err + } + currentVersion := setting.Value + version, ok := dbVersions[currentVersion] + if !ok { + return nil + } + currentVersion = version.NextVersion + for currentVersion != "" { + version, ok := dbVersions[currentVersion] + if !ok { + break + } + log.Infof("Upgrading database to version %s", currentVersion) + if version.Upgrade != nil { + err = version.Upgrade() + if err != nil { + return err + } + } + err = UpdateSettingItemValue("database_version", currentVersion) + if err != nil { + return err + } + currentVersion = version.NextVersion + } + return nil +} diff --git a/internal/model/setting.go b/internal/model/setting.go index 9a96428..37e66e7 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -16,10 +16,11 @@ func (s SettingGroup) String() string { } const ( - SettingGroupRoom SettingGroup = "room" - SettingGroupUser SettingGroup = "user" - SettingGroupProxy SettingGroup = "proxy" - SettingGroupRtmp SettingGroup = "rtmp" + SettingGroupRoom SettingGroup = "room" + SettingGroupUser SettingGroup = "user" + SettingGroupProxy SettingGroup = "proxy" + SettingGroupRtmp SettingGroup = "rtmp" + SettingGroupDatabase SettingGroup = "database" ) type Setting struct { diff --git a/internal/settings/bool.go b/internal/settings/bool.go index 81de6b5..c2e6fa8 100644 --- a/internal/settings/bool.go +++ b/internal/settings/bool.go @@ -5,7 +5,6 @@ import ( "strconv" "sync/atomic" - "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) @@ -24,9 +23,18 @@ type Bool struct { setting defaultValue bool value uint32 + beforeSet func(BoolSetting, bool) error } -func NewBool(name string, value bool, group model.SettingGroup) *Bool { +type BoolSettingOption func(*Bool) + +func WithBeforeSetBool(beforeSet func(BoolSetting, bool) error) BoolSettingOption { + return func(s *Bool) { + s.beforeSet = beforeSet + } +} + +func newBool(name string, value bool, group model.SettingGroup, options ...BoolSettingOption) *Bool { b := &Bool{ setting: setting{ name: name, @@ -35,6 +43,9 @@ func NewBool(name string, value bool, group model.SettingGroup) *Bool { }, defaultValue: value, } + for _, option := range options { + option(b) + } b.set(value) return b } @@ -72,11 +83,11 @@ func (b *Bool) Default() bool { return b.defaultValue } -func (b *Bool) DefaultRaw() string { +func (b *Bool) DefaultString() string { return b.Stringify(b.defaultValue) } -func (b *Bool) Raw() string { +func (b *Bool) String() string { return b.Stringify(b.Get()) } @@ -84,33 +95,45 @@ func (b *Bool) DefaultInterface() any { return b.Default() } -func (b *Bool) SetRaw(value string) error { - err := b.Init(value) +func (b *Bool) SetString(value string) error { + v, err := b.Parse(value) if err != nil { return err } - return db.UpdateSettingItemValue(b.Name(), b.Raw()) + + if b.beforeSet != nil { + err = b.beforeSet(b, v) + if err != nil { + return err + } + } + + b.set(v) + return nil } -func (b *Bool) Set(value bool) error { - err := db.UpdateSettingItemValue(b.Name(), b.Stringify(value)) - if err != nil { - return err +func (b *Bool) Set(value bool) (err error) { + if b.beforeSet != nil { + err = b.beforeSet(b, value) + if err != nil { + return err + } } + b.set(value) - return nil + return } func (b *Bool) Interface() any { return b.Get() } -func newBoolSetting(k string, v bool, g model.SettingGroup) BoolSetting { +func NewBoolSetting(k string, v bool, g model.SettingGroup, options ...BoolSettingOption) BoolSetting { _, loaded := Settings[k] if loaded { panic(fmt.Sprintf("setting %s already exists", k)) } - b := NewBool(k, v, g) + b := newBool(k, v, g, options...) Settings[k] = b GroupSettings[g] = append(GroupSettings[g], b) return b diff --git a/internal/settings/floate64.go b/internal/settings/floate64.go index 7a0c24c..64f0cff 100644 --- a/internal/settings/floate64.go +++ b/internal/settings/floate64.go @@ -6,7 +6,6 @@ import ( "strconv" "sync/atomic" - "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) @@ -25,9 +24,25 @@ type Float64 struct { setting defaultValue float64 value uint64 + validator func(float64) error + beforeSet func(Float64Setting, float64) error } -func NewFloat64(name string, value float64, group model.SettingGroup) *Float64 { +type Float64SettingOption func(*Float64) + +func WithValidatorFloat64(validator func(float64) error) Float64SettingOption { + return func(s *Float64) { + s.validator = validator + } +} + +func WithBeforeSetFloat64(beforeSet func(Float64Setting, float64) error) Float64SettingOption { + return func(s *Float64) { + s.beforeSet = beforeSet + } +} + +func newFloat64(name string, value float64, group model.SettingGroup, options ...Float64SettingOption) *Float64 { f := &Float64{ setting: setting{ name: name, @@ -36,12 +51,22 @@ func NewFloat64(name string, value float64, group model.SettingGroup) *Float64 { }, defaultValue: value, } + for _, option := range options { + option(f) + } f.set(value) return f } func (f *Float64) Parse(value string) (float64, error) { - return strconv.ParseFloat(value, 64) + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return 0, err + } + if f.validator != nil { + return v, f.validator(v) + } + return v, nil } func (f *Float64) Stringify(value float64) string { @@ -57,7 +82,7 @@ func (f *Float64) Init(value string) error { return nil } -func (f *Float64) Raw() string { +func (f *Float64) String() string { return f.Stringify(f.Get()) } @@ -65,7 +90,7 @@ func (f *Float64) Default() float64 { return f.defaultValue } -func (f *Float64) DefaultRaw() string { +func (f *Float64) DefaultString() string { return f.Stringify(f.defaultValue) } @@ -73,25 +98,44 @@ func (f *Float64) DefaultInterface() any { return f.Default() } -func (f *Float64) SetRaw(value string) error { - err := f.Init(value) +func (f *Float64) SetString(value string) error { + v, err := f.Parse(value) if err != nil { return err } - return db.UpdateSettingItemValue(f.Name(), f.Raw()) + + if f.beforeSet != nil { + err = f.beforeSet(f, v) + if err != nil { + return err + } + } + + f.set(v) + return nil } func (f *Float64) set(value float64) { atomic.StoreUint64(&f.value, math.Float64bits(value)) } -func (f *Float64) Set(value float64) error { - err := db.UpdateSettingItemValue(f.Name(), f.Stringify(value)) - if err != nil { - return err +func (f *Float64) Set(value float64) (err error) { + if f.validator != nil { + err = f.validator(value) + if err != nil { + return err + } + } + + if f.beforeSet != nil { + err = f.beforeSet(f, value) + if err != nil { + return err + } } + f.set(value) - return nil + return } func (f *Float64) Get() float64 { @@ -102,12 +146,12 @@ func (f *Float64) Interface() any { return f.Get() } -func newFloat64Setting(k string, v float64, g model.SettingGroup) *Float64 { +func NewFloat64Setting(k string, v float64, g model.SettingGroup, options ...Float64SettingOption) *Float64 { _, loaded := Settings[k] if loaded { panic(fmt.Sprintf("setting %s already exists", k)) } - f := NewFloat64(k, v, g) + f := newFloat64(k, v, g, options...) Settings[k] = f GroupSettings[g] = append(GroupSettings[g], f) return f diff --git a/internal/settings/int64.go b/internal/settings/int64.go index 8fa1ada..5cc4740 100644 --- a/internal/settings/int64.go +++ b/internal/settings/int64.go @@ -5,7 +5,6 @@ import ( "strconv" "sync/atomic" - "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) @@ -24,9 +23,25 @@ type Int64 struct { setting defaultValue int64 value int64 + validator func(int64) error + beforeSet func(Int64Setting, int64) error } -func NewInt64(name string, value int64, group model.SettingGroup) *Int64 { +type Int64SettingOption func(*Int64) + +func WithValidatorInt64(validator func(int64) error) Int64SettingOption { + return func(s *Int64) { + s.validator = validator + } +} + +func WithBeforeSetInt64(beforeSet func(Int64Setting, int64) error) Int64SettingOption { + return func(s *Int64) { + s.beforeSet = beforeSet + } +} + +func newInt64(name string, value int64, group model.SettingGroup, options ...Int64SettingOption) *Int64 { i := &Int64{ setting: setting{ name: name, @@ -36,11 +51,21 @@ func NewInt64(name string, value int64, group model.SettingGroup) *Int64 { defaultValue: value, value: value, } + for _, option := range options { + option(i) + } return i } func (i *Int64) Parse(value string) (int64, error) { - return strconv.ParseInt(value, 10, 64) + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return 0, err + } + if i.validator != nil { + return v, i.validator(v) + } + return v, nil } func (i *Int64) Stringify(value int64) string { @@ -60,37 +85,56 @@ func (i *Int64) Default() int64 { return i.defaultValue } -func (i *Int64) DefaultRaw() string { - return strconv.FormatInt(i.defaultValue, 10) +func (i *Int64) DefaultString() string { + return i.Stringify(i.defaultValue) } func (i *Int64) DefaultInterface() any { - return i.defaultValue + return i.Default() } -func (i *Int64) Raw() string { +func (i *Int64) String() string { return i.Stringify(i.Get()) } -func (i *Int64) SetRaw(value string) error { - err := i.Init(value) +func (i *Int64) SetString(value string) error { + v, err := i.Parse(value) if err != nil { return err } - return db.UpdateSettingItemValue(i.Name(), i.Raw()) + + if i.beforeSet != nil { + err = i.beforeSet(i, v) + if err != nil { + return err + } + } + + i.set(v) + return nil } func (i *Int64) set(value int64) { atomic.StoreInt64(&i.value, value) } -func (i *Int64) Set(value int64) error { - err := db.UpdateSettingItemValue(i.Name(), i.Stringify(value)) - if err != nil { - return err +func (i *Int64) Set(value int64) (err error) { + if i.validator != nil { + err = i.validator(value) + if err != nil { + return err + } + } + + if i.beforeSet != nil { + err = i.beforeSet(i, value) + if err != nil { + return err + } } + i.set(value) - return nil + return } func (i *Int64) Get() int64 { @@ -101,12 +145,12 @@ func (i *Int64) Interface() any { return i.Get() } -func newInt64Setting(k string, v int64, g model.SettingGroup) *Int64 { +func NewInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64SettingOption) *Int64 { _, loaded := Settings[k] if loaded { panic(fmt.Sprintf("setting %s already exists", k)) } - i := NewInt64(k, v, g) + i := newInt64(k, v, g, options...) Settings[k] = i GroupSettings[g] = append(GroupSettings[g], i) return i diff --git a/internal/settings/setting.go b/internal/settings/setting.go index 1304487..0a8ec0f 100644 --- a/internal/settings/setting.go +++ b/internal/settings/setting.go @@ -4,8 +4,6 @@ import ( "fmt" json "github.com/json-iterator/go" - log "github.com/sirupsen/logrus" - "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) @@ -19,9 +17,9 @@ type Setting interface { Type() model.SettingType Group() model.SettingGroup Init(string) error - Raw() string - SetRaw(string) error - DefaultRaw() string + String() string + SetString(string) error + DefaultString() string DefaultInterface() any Interface() any } @@ -31,79 +29,7 @@ func SetValue(name string, value any) error { if !ok { return fmt.Errorf("setting %s not found", name) } - return SetSettingValue(s, value) -} - -func SetSettingValue(s Setting, value any) error { - switch s := s.(type) { - case BoolSetting: - return s.Set(json.Wrap(value).ToBool()) - case Int64Setting: - return s.Set(json.Wrap(value).ToInt64()) - case Float64Setting: - return s.Set(json.Wrap(value).ToFloat64()) - case StringSetting: - return s.Set(json.Wrap(value).ToString()) - default: - log.Fatalf("unknown setting %s type: %s", s.Name(), s.Type()) - } - return nil -} - -func ToSettings[s Setting](settings map[string]s) []Setting { - var ss []Setting = make([]Setting, 0, len(settings)) - for _, v := range settings { - ss = append(ss, v) - } - return ss -} - -func Init() error { - return initAndFixSettings(ToSettings(Settings)...) -} - -func initSettings(i ...Setting) error { - for _, b := range i { - s := &model.Setting{ - Name: b.Name(), - Value: b.Raw(), - Type: b.Type(), - Group: b.Group(), - } - err := db.FirstOrCreateSettingItemValue(s) - if err != nil { - return err - } - err = b.Init(s.Value) - if err != nil { - return err - } - } - return nil -} - -func initAndFixSettings(i ...Setting) error { - for _, b := range i { - s := &model.Setting{ - Name: b.Name(), - Value: b.Raw(), - Type: b.Type(), - Group: b.Group(), - } - err := db.FirstOrCreateSettingItemValue(s) - if err != nil { - return err - } - err = b.Init(s.Value) - if err != nil { - // auto fix - err = b.SetRaw(b.DefaultRaw()) - if err != nil { - return err - } - } - } - return nil + return s.SetString(json.Wrap(value).ToString()) } type setting struct { diff --git a/internal/settings/string.go b/internal/settings/string.go index 93a9476..9a6d6e2 100644 --- a/internal/settings/string.go +++ b/internal/settings/string.go @@ -4,7 +4,6 @@ import ( "fmt" "sync" - "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) @@ -24,9 +23,25 @@ type String struct { defaultValue string lock sync.RWMutex value string + validator func(string) error + beforeSet func(StringSetting, string) error } -func NewString(name string, value string, group model.SettingGroup) *String { +type StringSettingOption func(*String) + +func WithValidatorString(validator func(string) error) StringSettingOption { + return func(s *String) { + s.validator = validator + } +} + +func WithBeforeSetString(beforeSet func(StringSetting, string) error) StringSettingOption { + return func(s *String) { + s.beforeSet = beforeSet + } +} + +func newString(name string, value string, group model.SettingGroup, options ...StringSettingOption) *String { s := &String{ setting: setting{ name: name, @@ -36,10 +51,16 @@ func NewString(name string, value string, group model.SettingGroup) *String { defaultValue: value, value: value, } + for _, option := range options { + option(s) + } return s } func (s *String) Parse(value string) (string, error) { + if s.validator != nil { + return value, s.validator(value) + } return value, nil } @@ -60,24 +81,33 @@ func (s *String) Default() string { return s.defaultValue } -func (s *String) DefaultRaw() string { - return s.defaultValue +func (s *String) DefaultString() string { + return s.Stringify(s.defaultValue) } func (s *String) DefaultInterface() any { return s.Default() } -func (s *String) Raw() string { +func (s *String) String() string { return s.Stringify(s.Get()) } -func (s *String) SetRaw(value string) error { - err := s.Init(value) +func (s *String) SetString(value string) error { + v, err := s.Parse(value) if err != nil { return err } - return db.UpdateSettingItemValue(s.Name(), s.Raw()) + + if s.beforeSet != nil { + err = s.beforeSet(s, v) + if err != nil { + return err + } + } + + s.set(v) + return nil } func (s *String) set(value string) { @@ -86,13 +116,23 @@ func (s *String) set(value string) { s.value = value } -func (s *String) Set(value string) error { - err := db.UpdateSettingItemValue(s.Name(), s.Stringify(value)) - if err != nil { - return err +func (s *String) Set(value string) (err error) { + if s.validator != nil { + err = s.validator(value) + if err != nil { + return err + } + } + + if s.beforeSet != nil { + err = s.beforeSet(s, value) + if err != nil { + return err + } } + s.set(value) - return nil + return } func (s *String) Get() string { @@ -105,12 +145,12 @@ func (s *String) Interface() any { return s.Get() } -func newStringSetting(k string, v string, g model.SettingGroup) *String { +func NewStringSetting(k string, v string, g model.SettingGroup, options ...StringSettingOption) *String { _, loaded := Settings[k] if loaded { panic(fmt.Sprintf("setting %s already exists", k)) } - s := NewString(k, v, g) + s := newString(k, v, g, options...) Settings[k] = s GroupSettings[g] = append(GroupSettings[g], s) return s diff --git a/internal/settings/var.go b/internal/settings/var.go index be1682b..879cf77 100644 --- a/internal/settings/var.go +++ b/internal/settings/var.go @@ -1,35 +1,59 @@ package settings import ( + "errors" "time" + "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" ) +func BeforeSetBoolFunc(s BoolSetting, v bool) error { + return db.UpdateSettingItemValue(s.Name(), s.Stringify(v)) +} + +func BeforeSetStringFunc(s StringSetting, v string) error { + return db.UpdateSettingItemValue(s.Name(), s.Stringify(v)) +} + +func BeforeSetInt64Func(s Int64Setting, v int64) error { + return db.UpdateSettingItemValue(s.Name(), s.Stringify(v)) +} + +func BeforeSetFloat64Func(s Float64Setting, v float64) error { + return db.UpdateSettingItemValue(s.Name(), s.Stringify(v)) +} + var ( - DisableCreateRoom = newBoolSetting("disable_create_room", false, model.SettingGroupRoom) - RoomMustNeedPwd = newBoolSetting("room_must_need_pwd", false, model.SettingGroupRoom) - CreateRoomNeedReview = newBoolSetting("create_room_need_review", false, model.SettingGroupRoom) - RoomTTL = newInt64Setting("room_ttl", int64(time.Hour*48), model.SettingGroupRoom) - UserMaxRoomCount = newInt64Setting("user_max_room_count", 3, model.SettingGroupRoom) + DisableCreateRoom = NewBoolSetting("disable_create_room", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) + RoomMustNeedPwd = NewBoolSetting("room_must_need_pwd", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) + CreateRoomNeedReview = NewBoolSetting("create_room_need_review", false, model.SettingGroupRoom, WithBeforeSetBool(BeforeSetBoolFunc)) + RoomTTL = NewInt64Setting("room_ttl", int64(time.Hour*48), model.SettingGroupRoom, WithBeforeSetInt64(BeforeSetInt64Func)) + UserMaxRoomCount = NewInt64Setting("user_max_room_count", 3, model.SettingGroupRoom, WithBeforeSetInt64(BeforeSetInt64Func)) ) var ( - DisableUserSignup = newBoolSetting("disable_user_signup", false, model.SettingGroupUser) - SignupNeedReview = newBoolSetting("signup_need_review", false, model.SettingGroupUser) + DisableUserSignup = NewBoolSetting("disable_user_signup", false, model.SettingGroupUser, WithBeforeSetBool(BeforeSetBoolFunc)) + SignupNeedReview = NewBoolSetting("signup_need_review", false, model.SettingGroupUser, WithBeforeSetBool(BeforeSetBoolFunc)) ) var ( - MovieProxy = newBoolSetting("movie_proxy", true, model.SettingGroupProxy) - LiveProxy = newBoolSetting("live_proxy", true, model.SettingGroupProxy) - AllowProxyToLocal = newBoolSetting("allow_proxy_to_local", false, model.SettingGroupProxy) + MovieProxy = NewBoolSetting("movie_proxy", true, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) + LiveProxy = NewBoolSetting("live_proxy", true, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) + AllowProxyToLocal = NewBoolSetting("allow_proxy_to_local", false, model.SettingGroupProxy, WithBeforeSetBool(BeforeSetBoolFunc)) ) var ( // can watch live streams through the RTMP protocol (without authentication, insecure). - RtmpPlayer = newBoolSetting("rtmp_player", false, model.SettingGroupRtmp) + RtmpPlayer = NewBoolSetting("rtmp_player", false, model.SettingGroupRtmp, WithBeforeSetBool(BeforeSetBoolFunc)) // default use http header host - CustomPublishHost = newStringSetting("custom_publish_host", "", model.SettingGroupRtmp) + CustomPublishHost = NewStringSetting("custom_publish_host", "", model.SettingGroupRtmp, WithBeforeSetString(BeforeSetStringFunc)) // disguise the .ts file as a .png file - TsDisguisedAsPng = newBoolSetting("ts_disguised_as_png", true, model.SettingGroupRtmp) + TsDisguisedAsPng = NewBoolSetting("ts_disguised_as_png", true, model.SettingGroupRtmp, WithBeforeSetBool(BeforeSetBoolFunc)) +) + +var ( + DatabaseVersion = NewStringSetting("database_version", "0.0.1", model.SettingGroupDatabase, WithBeforeSetString(func(ss StringSetting, s string) error { + return errors.New("not support change database version") + })) )