mirror of
https://github.com/astaxie/beego.git
synced 2024-11-21 23:50: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 {
|
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 {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type fakeConfigContainer struct {
|
type fakeConfigContainer struct {
|
||||||
|
BaseConfiger
|
||||||
data map[string]string
|
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.
|
// 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.
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ func TestFilterOrmDecorator_Delete(t *testing.T) {
|
|||||||
register()
|
register()
|
||||||
o := &filterMockOrm{}
|
o := &filterMockOrm{}
|
||||||
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
return func(ctx context.Context, inv *Invocation) []interface{} {
|
return func(ctx context.Context, inv *Invocation) []interface{} {
|
||||||
assert.Equal(t, "DeleteWithCtx", inv.Method)
|
assert.Equal(t, "DeleteWithCtx", inv.Method)
|
||||||
assert.Equal(t, 2, len(inv.Args))
|
assert.Equal(t, 2, len(inv.Args))
|
||||||
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
assert.Equal(t, "FILTER_TEST", inv.GetTableName())
|
||||||
@ -311,7 +311,7 @@ func TestFilterOrmDecorator_Raw(t *testing.T) {
|
|||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterOrmDecorator_ReadForUpdate(t *testing.T) {
|
func TestFilterOrmDecorator_ReadForUpdate(t *testing.T) {
|
||||||
register()
|
register()
|
||||||
o := &filterMockOrm{}
|
o := &filterMockOrm{}
|
||||||
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
od := NewFilterOrmDecorator(o, func(next Filter) Filter {
|
||||||
|
Loading…
Reference in New Issue
Block a user