diff --git a/config/database.go b/config/database.go index 9c1f8fa..96186c8 100644 --- a/config/database.go +++ b/config/database.go @@ -1,127 +1,127 @@ package config import ( - "errors" - "sort" - "strings" + "errors" + "sort" + "strings" - "github.com/safing/portbase/log" "github.com/safing/portbase/database" - "github.com/safing/portbase/database/storage" - "github.com/safing/portbase/database/record" - "github.com/safing/portbase/database/query" "github.com/safing/portbase/database/iterator" + "github.com/safing/portbase/database/query" + "github.com/safing/portbase/database/record" + "github.com/safing/portbase/database/storage" + "github.com/safing/portbase/log" ) var ( - dbController *database.Controller + dbController *database.Controller ) -// ConfigStorageInterface provices a storage.Interface to the configuration manager. -type ConfigStorageInterface struct { +// StorageInterface provices a storage.Interface to the configuration manager. +type StorageInterface struct { storage.InjectBase } // Get returns a database record. -func (s *ConfigStorageInterface) Get(key string) (record.Record, error) { - optionsLock.Lock() - defer optionsLock.Unlock() +func (s *StorageInterface) Get(key string) (record.Record, error) { + optionsLock.Lock() + defer optionsLock.Unlock() - opt, ok := options[key] - if !ok { - return nil, storage.ErrNotFound - } + opt, ok := options[key] + if !ok { + return nil, storage.ErrNotFound + } - return opt.Export() + return opt.Export() } // Put stores a record in the database. -func (s *ConfigStorageInterface) Put(r record.Record) error { - if r.Meta().Deleted > 0 { - return setConfigOption(r.DatabaseKey(), nil, false) - } +func (s *StorageInterface) Put(r record.Record) error { + if r.Meta().Deleted > 0 { + return setConfigOption(r.DatabaseKey(), nil, false) + } - acc := r.GetAccessor(r) - if acc == nil { - return errors.New("invalid data") - } + acc := r.GetAccessor(r) + if acc == nil { + return errors.New("invalid data") + } - val, ok := acc.Get("Value") - if !ok || val == nil { - return setConfigOption(r.DatabaseKey(), nil, false) - } + val, ok := acc.Get("Value") + if !ok || val == nil { + return setConfigOption(r.DatabaseKey(), nil, false) + } - optionsLock.RLock() - option, ok := options[r.DatabaseKey()] + optionsLock.RLock() + option, ok := options[r.DatabaseKey()] optionsLock.RUnlock() - if !ok { - return errors.New("config option does not exist") - } + if !ok { + return errors.New("config option does not exist") + } - var value interface{} - switch option.OptType { - case OptTypeString : - value, ok = acc.GetString("Value") - case OptTypeStringArray : - value, ok = acc.GetStringArray("Value") - case OptTypeInt : - value, ok = acc.GetInt("Value") - case OptTypeBool : - value, ok = acc.GetBool("Value") - } - if !ok { - return errors.New("received invalid value in \"Value\"") - } + var value interface{} + switch option.OptType { + case OptTypeString: + value, ok = acc.GetString("Value") + case OptTypeStringArray: + value, ok = acc.GetStringArray("Value") + case OptTypeInt: + value, ok = acc.GetInt("Value") + case OptTypeBool: + value, ok = acc.GetBool("Value") + } + if !ok { + return errors.New("received invalid value in \"Value\"") + } - err := setConfigOption(r.DatabaseKey(), value, false) - if err != nil { - return err - } - return nil + err := setConfigOption(r.DatabaseKey(), value, false) + if err != nil { + return err + } + return nil } // Delete deletes a record from the database. -func (s *ConfigStorageInterface) Delete(key string) error { - return setConfigOption(key, nil, false) +func (s *StorageInterface) Delete(key string) error { + return setConfigOption(key, nil, false) } // Query returns a an iterator for the supplied query. -func (s *ConfigStorageInterface) Query(q *query.Query, local, internal bool) (*iterator.Iterator, error) { +func (s *StorageInterface) Query(q *query.Query, local, internal bool) (*iterator.Iterator, error) { - optionsLock.Lock() - defer optionsLock.Unlock() + optionsLock.Lock() + defer optionsLock.Unlock() - it := iterator.New() - var opts []*Option - for _, opt := range options { - if strings.HasPrefix(opt.Key, q.DatabaseKeyPrefix()) { - opts = append(opts, opt) - } - } + it := iterator.New() + var opts []*Option + for _, opt := range options { + if strings.HasPrefix(opt.Key, q.DatabaseKeyPrefix()) { + opts = append(opts, opt) + } + } - go s.processQuery(q, it, opts) + go s.processQuery(q, it, opts) - return it, nil + return it, nil } -func (s *ConfigStorageInterface) processQuery(q *query.Query, it *iterator.Iterator, opts []*Option) { +func (s *StorageInterface) processQuery(q *query.Query, it *iterator.Iterator, opts []*Option) { - sort.Sort(sortableOptions(opts)) + sort.Sort(sortableOptions(opts)) - for _, opt := range opts { - r, err := opt.Export() - if err != nil { - it.Finish(err) - return - } - it.Next <- r - } + for _, opt := range opts { + r, err := opt.Export() + if err != nil { + it.Finish(err) + return + } + it.Next <- r + } - it.Finish(nil) + it.Finish(nil) } // ReadOnly returns whether the database is read only. -func (s *ConfigStorageInterface) ReadOnly() bool { +func (s *StorageInterface) ReadOnly() bool { return false } @@ -132,33 +132,33 @@ func registerAsDatabase() error { StorageType: "injected", PrimaryAPI: "", }) - if err != nil { - return err - } + if err != nil { + return err + } - controller, err := database.InjectDatabase("config", &ConfigStorageInterface{}) - if err != nil { - return err - } + controller, err := database.InjectDatabase("config", &StorageInterface{}) + if err != nil { + return err + } - dbController = controller + dbController = controller return nil } func pushFullUpdate() { - optionsLock.RLock() - defer optionsLock.RUnlock() + optionsLock.RLock() + defer optionsLock.RUnlock() - for _, option := range options { - pushUpdate(option) - } + for _, option := range options { + pushUpdate(option) + } } func pushUpdate(option *Option) { - r, err := option.Export() - if err != nil { - log.Errorf("failed to export option to push update: %s", err) - } else { - dbController.PushUpdate(r) - } + r, err := option.Export() + if err != nil { + log.Errorf("failed to export option to push update: %s", err) + } else { + dbController.PushUpdate(r) + } } diff --git a/config/option.go b/config/option.go index 92d7a76..90f0295 100644 --- a/config/option.go +++ b/config/option.go @@ -1,9 +1,9 @@ package config import ( + "encoding/json" "fmt" "regexp" - "encoding/json" "github.com/tidwall/sjson" @@ -47,6 +47,7 @@ type Option struct { DefaultValue interface{} ExternalOptType string ValidationRegex string + RequiresRestart bool compiledRegex *regexp.Regexp }