1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 04:00:55 +00:00

Merge pull request #4175 from flycash/ftr/config

Add more methods to Configer
This commit is contained in:
Ming Deng 2020-08-19 22:44:43 +08:00 committed by GitHub
commit e6ea307549
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 208 additions and 10 deletions

View File

@ -411,6 +411,7 @@ func LoadAppConfig(adapterName, configPath string) error {
} }
type beegoAppConfig struct { type beegoAppConfig struct {
config.BaseConfiger
innerConfig config.Configer innerConfig config.Configer
} }
@ -419,7 +420,7 @@ func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &beegoAppConfig{ac}, nil return &beegoAppConfig{innerConfig: ac}, nil
} }
func (b *beegoAppConfig) Set(key, val string) error { func (b *beegoAppConfig) Set(key, val string) error {

View 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")
}
},
}
}

View File

@ -15,7 +15,7 @@
// Package config is used to parse config. // Package config is used to parse config.
// Usage: // Usage:
// import "github.com/astaxie/beego/config" // import "github.com/astaxie/beego/config"
//Examples. // Examples.
// //
// cnf, err := config.NewConfig("ini", "config.conf") // cnf, err := config.NewConfig("ini", "config.conf")
// //
@ -37,36 +37,157 @@
// cnf.DIY(key string) (interface{}, error) // cnf.DIY(key string) (interface{}, error)
// cnf.GetSection(section string) (map[string]string, error) // cnf.GetSection(section string) (map[string]string, error)
// cnf.SaveConfigFile(filename string) error // cnf.SaveConfigFile(filename string) error
//More docs http://beego.me/docs/module/config.md // More docs http://beego.me/docs/module/config.md
package config package config
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"reflect" "reflect"
"strconv"
"strings"
"time" "time"
) )
// Configer defines how to get and set value from configuration raw data. // Configer defines how to get and set value from configuration raw data.
type Configer interface { type Configer interface {
Set(key, val string) error //support section::key type in given key when using ini type. // 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. Set(key, val string) error
Strings(key 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.
String(key string) string
// get string slice
Strings(key string) []string
Int(key string) (int, error) Int(key string) (int, error)
Int64(key string) (int64, error) Int64(key string) (int64, error)
Bool(key string) (bool, error) Bool(key string) (bool, error)
Float(key string) (float64, 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. // 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 DefaultString(key string, defaultVal string) string
// get string slice
DefaultStrings(key string, defaultVal []string) []string
DefaultInt(key string, defaultVal int) int DefaultInt(key string, defaultVal int) int
DefaultInt64(key string, defaultVal int64) int64 DefaultInt64(key string, defaultVal int64) int64
DefaultBool(key string, defaultVal bool) bool DefaultBool(key string, defaultVal bool) bool
DefaultFloat(key string, defaultVal float64) float64 DefaultFloat(key string, defaultVal float64) float64
DIY(key string) (interface{}, error) DIY(key string) (interface{}, error)
GetSection(section string) (map[string]string, 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 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. // Config is the adapter interface for parsing config file to get raw data to Configer.
type Config interface { type Config interface {
Parse(key string) (Configer, error) Parse(key string) (Configer, error)

View File

@ -21,6 +21,7 @@ import (
) )
type fakeConfigContainer struct { type fakeConfigContainer struct {
BaseConfiger
data map[string]string data map[string]string
} }

View File

@ -225,6 +225,7 @@ func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
// IniConfigContainer is a config which represents the ini configuration. // IniConfigContainer is a config which represents the ini configuration.
// When set and get value, support key as section:name type. // When set and get value, support key as section:name type.
type IniConfigContainer struct { type IniConfigContainer struct {
BaseConfiger
data map[string]map[string]string // section=> key:val data map[string]map[string]string // section=> key:val
sectionComment map[string]string // section : comment sectionComment map[string]string // section : comment
keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment. keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment.

View File

@ -69,6 +69,7 @@ func (js *JSONConfig) ParseData(data []byte) (config.Configer, error) {
// JSONConfigContainer is a config which represents the json configuration. // JSONConfigContainer is a config which represents the json configuration.
// Only when get value, support key as section:name type. // Only when get value, support key as section:name type.
type JSONConfigContainer struct { type JSONConfigContainer struct {
config.BaseConfiger
data map[string]interface{} data map[string]interface{}
sync.RWMutex sync.RWMutex
} }

View File

@ -74,6 +74,7 @@ func (xc *Config) ParseData(data []byte) (config.Configer, error) {
// ConfigContainer is a Config which represents the xml configuration. // ConfigContainer is a Config which represents the xml configuration.
type ConfigContainer struct { type ConfigContainer struct {
config.BaseConfiger
data map[string]interface{} data map[string]interface{}
sync.Mutex sync.Mutex
} }

View File

@ -118,6 +118,7 @@ func parseYML(buf []byte) (cnf map[string]interface{}, err error) {
// ConfigContainer is a config which represents the yaml configuration. // ConfigContainer is a config which represents the yaml configuration.
type ConfigContainer struct { type ConfigContainer struct {
config.BaseConfiger
data map[string]interface{} data map[string]interface{}
sync.RWMutex sync.RWMutex
} }