From 33b052bc7a8f46302101fe1074ea66a956df7224 Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Mon, 31 Aug 2020 14:14:31 +0000 Subject: [PATCH] support json --- pkg/infrastructure/config/json/json.go | 42 ++++++++++++++++++++- pkg/infrastructure/config/json/json_test.go | 26 +++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pkg/infrastructure/config/json/json.go b/pkg/infrastructure/config/json/json.go index dae55118..c65eff4d 100644 --- a/pkg/infrastructure/config/json/json.go +++ b/pkg/infrastructure/config/json/json.go @@ -25,7 +25,10 @@ import ( "strings" "sync" + "github.com/mitchellh/mapstructure" + "github.com/astaxie/beego/pkg/infrastructure/config" + "github.com/astaxie/beego/pkg/infrastructure/logs" ) // JSONConfig is a json config parser and implements Config interface. @@ -70,11 +73,48 @@ 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 } +func (c *JSONConfigContainer) Unmarshaler(ctx context.Context, prefix string, obj interface{}, opt ...config.DecodeOption) error { + sub, err := c.sub(ctx, prefix) + if err != nil { + return err + } + return mapstructure.Decode(sub, obj) +} + +func (c *JSONConfigContainer) Sub(ctx context.Context, key string) (config.Configer, error) { + sub, err := c.sub(ctx, key) + if err != nil { + return nil, err + } + return &JSONConfigContainer{ + data: sub, + }, nil +} + +func (c *JSONConfigContainer) sub(ctx context.Context, key string) (map[string]interface{}, error) { + if key == "" { + return c.data, nil + } + value, ok := c.data[key] + if !ok { + return nil, errors.New(fmt.Sprintf("key is not found: %s", key)) + } + + res, ok := value.(map[string]interface{}) + if !ok { + return nil, errors.New(fmt.Sprintf("the type of value is invalid, key: %s", key)) + } + return res, nil +} + +func (c *JSONConfigContainer) OnChange(ctx context.Context, key string, fn func(value string)) { + logs.Warn("unsupported operation") +} + // Bool returns the boolean value for a given key. func (c *JSONConfigContainer) Bool(ctx context.Context, key string) (bool, error) { val := c.getData(key) diff --git a/pkg/infrastructure/config/json/json_test.go b/pkg/infrastructure/config/json/json_test.go index 486d2b11..5275ee57 100644 --- a/pkg/infrastructure/config/json/json_test.go +++ b/pkg/infrastructure/config/json/json_test.go @@ -15,10 +15,13 @@ package json import ( + "context" "fmt" "os" "testing" + "github.com/stretchr/testify/assert" + "github.com/astaxie/beego/pkg/infrastructure/config" ) @@ -223,4 +226,27 @@ func TestJson(t *testing.T) { if !jsonconf.DefaultBool(nil, "unknown", true) { t.Error("unknown keys with default value wrong") } + + sub, err := jsonconf.Sub(context.Background(), "database") + assert.Nil(t, err) + assert.NotNil(t, sub) + + sub, err = sub.Sub(context.Background(), "conns") + assert.Nil(t, err) + + maxCon, _ := sub.Int(context.Background(), "maxconnection") + assert.Equal(t, 12, maxCon) + + dbCfg := &DatabaseConfig{} + err = sub.Unmarshaler(context.Background(), "", dbCfg) + assert.Nil(t, err) + assert.Equal(t, 12, dbCfg.MaxConnection) + assert.True(t, dbCfg.Autoconnect) + assert.Equal(t, "info", dbCfg.Connectioninfo) +} + +type DatabaseConfig struct { + MaxConnection int `json:"maxconnection"` + Autoconnect bool `json:"autoconnect"` + Connectioninfo string `json:"connectioninfo"` }