mirror of
https://github.com/astaxie/beego.git
synced 2024-11-21 23:20:54 +00:00
Merge pull request #4175 from flycash/ftr/config
Add more methods to Configer
This commit is contained in:
commit
e6ea307549
@ -411,6 +411,7 @@ func LoadAppConfig(adapterName, configPath string) error {
|
||||
}
|
||||
|
||||
type beegoAppConfig struct {
|
||||
config.BaseConfiger
|
||||
innerConfig config.Configer
|
||||
}
|
||||
|
||||
@ -419,7 +420,7 @@ func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &beegoAppConfig{ac}, nil
|
||||
return &beegoAppConfig{innerConfig: ac}, nil
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Set(key, val string) error {
|
||||
|
71
pkg/config/base_config_test.go
Normal file
71
pkg/config/base_config_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBaseConfiger_DefaultBool(t *testing.T) {
|
||||
bc := newBaseConfier("true")
|
||||
assert.True(t, bc.DefaultBool("key1", false))
|
||||
assert.True(t, bc.DefaultBool("key2", true))
|
||||
}
|
||||
|
||||
func TestBaseConfiger_DefaultFloat(t *testing.T) {
|
||||
bc := newBaseConfier("12.3")
|
||||
assert.Equal(t, 12.3, bc.DefaultFloat("key1", 0.1))
|
||||
assert.Equal(t, 0.1, bc.DefaultFloat("key2", 0.1))
|
||||
}
|
||||
|
||||
func TestBaseConfiger_DefaultInt(t *testing.T) {
|
||||
bc := newBaseConfier("10")
|
||||
assert.Equal(t, 10, bc.DefaultInt("key1", 8))
|
||||
assert.Equal(t, 8, bc.DefaultInt("key2", 8))
|
||||
}
|
||||
|
||||
func TestBaseConfiger_DefaultInt64(t *testing.T) {
|
||||
bc := newBaseConfier("64")
|
||||
assert.Equal(t, int64(64), bc.DefaultInt64("key1", int64(8)))
|
||||
assert.Equal(t, int64(8), bc.DefaultInt64("key2", int64(8)))
|
||||
}
|
||||
|
||||
func TestBaseConfiger_DefaultString(t *testing.T) {
|
||||
bc := newBaseConfier("Hello")
|
||||
assert.Equal(t, "Hello", bc.DefaultString("key1", "world"))
|
||||
assert.Equal(t, "world", bc.DefaultString("key2", "world"))
|
||||
}
|
||||
|
||||
func TestBaseConfiger_DefaultStrings(t *testing.T) {
|
||||
bc := newBaseConfier("Hello;world")
|
||||
assert.Equal(t, []string{"Hello", "world"}, bc.DefaultStrings("key1", []string{"world"}))
|
||||
assert.Equal(t, []string{"world"}, bc.DefaultStrings("key2", []string{"world"}))
|
||||
}
|
||||
|
||||
func newBaseConfier(str1 string) *BaseConfiger {
|
||||
return &BaseConfiger{
|
||||
reader: func(key string) (string, error) {
|
||||
if key == "key1" {
|
||||
return str1, nil
|
||||
} else {
|
||||
return "", errors.New("mock error")
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
}
|
@ -41,32 +41,153 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Configer defines how to get and set value from configuration raw data.
|
||||
type Configer interface {
|
||||
Set(key, val string) error //support section::key type in given key when using ini type.
|
||||
String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
Strings(key string) []string //get string slice
|
||||
// support section::key type in given key when using ini type.
|
||||
Set(key, val string) error
|
||||
|
||||
// support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
String(key string) string
|
||||
// get string slice
|
||||
Strings(key string) []string
|
||||
Int(key string) (int, error)
|
||||
Int64(key string) (int64, error)
|
||||
Bool(key string) (bool, error)
|
||||
Float(key string) (float64, error)
|
||||
DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
DefaultStrings(key string, defaultVal []string) []string //get string slice
|
||||
// support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
DefaultString(key string, defaultVal string) string
|
||||
// get string slice
|
||||
DefaultStrings(key string, defaultVal []string) []string
|
||||
DefaultInt(key string, defaultVal int) int
|
||||
DefaultInt64(key string, defaultVal int64) int64
|
||||
DefaultBool(key string, defaultVal bool) bool
|
||||
DefaultFloat(key string, defaultVal float64) float64
|
||||
DIY(key string) (interface{}, error)
|
||||
GetSection(section string) (map[string]string, error)
|
||||
|
||||
Unmarshaler(obj interface{}) error
|
||||
Sub(key string) (Configer, error)
|
||||
OnChange(fn func(cfg Configer))
|
||||
// GetByPrefix(prefix string) ([]byte, error)
|
||||
// GetSerializer() Serializer
|
||||
SaveConfigFile(filename string) error
|
||||
}
|
||||
|
||||
type BaseConfiger struct {
|
||||
// The reader should support key like "a.b.c"
|
||||
reader func(key string) (string, error)
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) Int(key string) (int, error) {
|
||||
res, err := c.reader(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(res)
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) Int64(key string) (int64, error) {
|
||||
res, err := c.reader(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseInt(res, 10, 64)
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) Bool(key string) (bool, error) {
|
||||
res, err := c.reader(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return strconv.ParseBool(res)
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) Float(key string) (float64, error) {
|
||||
res, err := c.reader(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseFloat(res, 64)
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) DefaultString(key string, defaultVal string) string {
|
||||
if res := c.String(key); res != "" {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) DefaultStrings(key string, defaultVal []string) []string {
|
||||
if res := c.Strings(key); len(res) > 0 {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) DefaultInt(key string, defaultVal int) int {
|
||||
if res, err := c.Int(key); err == nil {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
if res, err := c.Int64(key); err == nil {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) DefaultBool(key string, defaultVal bool) bool {
|
||||
if res, err := c.Bool(key); err == nil {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
func (c *BaseConfiger) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
if res, err := c.Float(key); err == nil {
|
||||
return res
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) String(key string) string {
|
||||
res, _ := c.reader(key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *BaseConfiger) Strings(key string) []string {
|
||||
res, err := c.reader(key)
|
||||
if err != nil || res == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(res, ";")
|
||||
}
|
||||
|
||||
// TODO remove this before release v2.0.0
|
||||
func (c *BaseConfiger) Unmarshaler(obj interface{}) error {
|
||||
return errors.New("unsupported operation")
|
||||
}
|
||||
|
||||
// TODO remove this before release v2.0.0
|
||||
func (c *BaseConfiger) Sub(key string) (Configer, error) {
|
||||
return nil, errors.New("unsupported operation")
|
||||
}
|
||||
|
||||
// TODO remove this before release v2.0.0
|
||||
func (c *BaseConfiger) OnChange(fn func(cfg Configer)) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// Config is the adapter interface for parsing config file to get raw data to Configer.
|
||||
type Config interface {
|
||||
Parse(key string) (Configer, error)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
)
|
||||
|
||||
type fakeConfigContainer struct {
|
||||
BaseConfiger
|
||||
data map[string]string
|
||||
}
|
||||
|
||||
|
@ -225,6 +225,7 @@ func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
|
||||
// IniConfigContainer is a config which represents the ini configuration.
|
||||
// When set and get value, support key as section:name type.
|
||||
type IniConfigContainer struct {
|
||||
BaseConfiger
|
||||
data map[string]map[string]string // section=> key:val
|
||||
sectionComment map[string]string // section : comment
|
||||
keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment.
|
||||
|
@ -69,6 +69,7 @@ func (js *JSONConfig) ParseData(data []byte) (config.Configer, error) {
|
||||
// JSONConfigContainer is a config which represents the json configuration.
|
||||
// Only when get value, support key as section:name type.
|
||||
type JSONConfigContainer struct {
|
||||
config.BaseConfiger
|
||||
data map[string]interface{}
|
||||
sync.RWMutex
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ func (xc *Config) ParseData(data []byte) (config.Configer, error) {
|
||||
|
||||
// ConfigContainer is a Config which represents the xml configuration.
|
||||
type ConfigContainer struct {
|
||||
config.BaseConfiger
|
||||
data map[string]interface{}
|
||||
sync.Mutex
|
||||
}
|
||||
|
@ -118,6 +118,7 @@ func parseYML(buf []byte) (cnf map[string]interface{}, err error) {
|
||||
|
||||
// ConfigContainer is a config which represents the yaml configuration.
|
||||
type ConfigContainer struct {
|
||||
config.BaseConfiger
|
||||
data map[string]interface{}
|
||||
sync.RWMutex
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user