572508dd by shuo li

Clean json config. Fix DefaultStrings

1 parent 22671c52
...@@ -17,13 +17,10 @@ package config ...@@ -17,13 +17,10 @@ package config
17 import ( 17 import (
18 "encoding/json" 18 "encoding/json"
19 "errors" 19 "errors"
20 "fmt"
21 "io/ioutil" 20 "io/ioutil"
22 "os" 21 "os"
23 "path"
24 "strings" 22 "strings"
25 "sync" 23 "sync"
26 "time"
27 ) 24 )
28 25
29 // JsonConfig is a json config parser and implements Config interface. 26 // JsonConfig is a json config parser and implements Config interface.
...@@ -41,13 +38,19 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) { ...@@ -41,13 +38,19 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
41 if err != nil { 38 if err != nil {
42 return nil, err 39 return nil, err
43 } 40 }
41
42 return js.ParseData(content)
43 }
44
45 // ParseData returns a ConfigContainer with json string
46 func (js *JsonConfig) ParseData(data []byte) (ConfigContainer, error) {
44 x := &JsonConfigContainer{ 47 x := &JsonConfigContainer{
45 data: make(map[string]interface{}), 48 data: make(map[string]interface{}),
46 } 49 }
47 err = json.Unmarshal(content, &x.data) 50 err := json.Unmarshal(data, &x.data)
48 if err != nil { 51 if err != nil {
49 var wrappingArray []interface{} 52 var wrappingArray []interface{}
50 err2 := json.Unmarshal(content, &wrappingArray) 53 err2 := json.Unmarshal(data, &wrappingArray)
51 if err2 != nil { 54 if err2 != nil {
52 return nil, err 55 return nil, err
53 } 56 }
...@@ -56,16 +59,6 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) { ...@@ -56,16 +59,6 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
56 return x, nil 59 return x, nil
57 } 60 }
58 61
59 func (js *JsonConfig) ParseData(data []byte) (ConfigContainer, error) {
60 // Save memory data to temporary file
61 tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
62 os.MkdirAll(path.Dir(tmpName), os.ModePerm)
63 if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
64 return nil, err
65 }
66 return js.Parse(tmpName)
67 }
68
69 // A Config represents the json configuration. 62 // A Config represents the json configuration.
70 // Only when get value, support key as section:name type. 63 // Only when get value, support key as section:name type.
71 type JsonConfigContainer struct { 64 type JsonConfigContainer struct {
...@@ -88,11 +81,10 @@ func (c *JsonConfigContainer) Bool(key string) (bool, error) { ...@@ -88,11 +81,10 @@ func (c *JsonConfigContainer) Bool(key string) (bool, error) {
88 // DefaultBool return the bool value if has no error 81 // DefaultBool return the bool value if has no error
89 // otherwise return the defaultval 82 // otherwise return the defaultval
90 func (c *JsonConfigContainer) DefaultBool(key string, defaultval bool) bool { 83 func (c *JsonConfigContainer) DefaultBool(key string, defaultval bool) bool {
91 if v, err := c.Bool(key); err != nil { 84 if v, err := c.Bool(key); err == nil {
92 return defaultval
93 } else {
94 return v 85 return v
95 } 86 }
87 return defaultval
96 } 88 }
97 89
98 // Int returns the integer value for a given key. 90 // Int returns the integer value for a given key.
...@@ -110,11 +102,10 @@ func (c *JsonConfigContainer) Int(key string) (int, error) { ...@@ -110,11 +102,10 @@ func (c *JsonConfigContainer) Int(key string) (int, error) {
110 // DefaultInt returns the integer value for a given key. 102 // DefaultInt returns the integer value for a given key.
111 // if err != nil return defaltval 103 // if err != nil return defaltval
112 func (c *JsonConfigContainer) DefaultInt(key string, defaultval int) int { 104 func (c *JsonConfigContainer) DefaultInt(key string, defaultval int) int {
113 if v, err := c.Int(key); err != nil { 105 if v, err := c.Int(key); err == nil {
114 return defaultval
115 } else {
116 return v 106 return v
117 } 107 }
108 return defaultval
118 } 109 }
119 110
120 // Int64 returns the int64 value for a given key. 111 // Int64 returns the int64 value for a given key.
...@@ -132,11 +123,10 @@ func (c *JsonConfigContainer) Int64(key string) (int64, error) { ...@@ -132,11 +123,10 @@ func (c *JsonConfigContainer) Int64(key string) (int64, error) {
132 // DefaultInt64 returns the int64 value for a given key. 123 // DefaultInt64 returns the int64 value for a given key.
133 // if err != nil return defaltval 124 // if err != nil return defaltval
134 func (c *JsonConfigContainer) DefaultInt64(key string, defaultval int64) int64 { 125 func (c *JsonConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
135 if v, err := c.Int64(key); err != nil { 126 if v, err := c.Int64(key); err == nil {
136 return defaultval
137 } else {
138 return v 127 return v
139 } 128 }
129 return defaultval
140 } 130 }
141 131
142 // Float returns the float value for a given key. 132 // Float returns the float value for a given key.
...@@ -154,11 +144,10 @@ func (c *JsonConfigContainer) Float(key string) (float64, error) { ...@@ -154,11 +144,10 @@ func (c *JsonConfigContainer) Float(key string) (float64, error) {
154 // DefaultFloat returns the float64 value for a given key. 144 // DefaultFloat returns the float64 value for a given key.
155 // if err != nil return defaltval 145 // if err != nil return defaltval
156 func (c *JsonConfigContainer) DefaultFloat(key string, defaultval float64) float64 { 146 func (c *JsonConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
157 if v, err := c.Float(key); err != nil { 147 if v, err := c.Float(key); err == nil {
158 return defaultval
159 } else {
160 return v 148 return v
161 } 149 }
150 return defaultval
162 } 151 }
163 152
164 // String returns the string value for a given key. 153 // String returns the string value for a given key.
...@@ -175,35 +164,37 @@ func (c *JsonConfigContainer) String(key string) string { ...@@ -175,35 +164,37 @@ func (c *JsonConfigContainer) String(key string) string {
175 // DefaultString returns the string value for a given key. 164 // DefaultString returns the string value for a given key.
176 // if err != nil return defaltval 165 // if err != nil return defaltval
177 func (c *JsonConfigContainer) DefaultString(key string, defaultval string) string { 166 func (c *JsonConfigContainer) DefaultString(key string, defaultval string) string {
178 if v := c.String(key); v == "" { 167 // TODO FIXME should not use "" to replace non existance
179 return defaultval 168 if v := c.String(key); v != "" {
180 } else {
181 return v 169 return v
182 } 170 }
171 return defaultval
183 } 172 }
184 173
185 // Strings returns the []string value for a given key. 174 // Strings returns the []string value for a given key.
186 func (c *JsonConfigContainer) Strings(key string) []string { 175 func (c *JsonConfigContainer) Strings(key string) []string {
176 stringVal := c.String(key)
177 if stringVal == "" {
178 return []string{}
179 }
187 return strings.Split(c.String(key), ";") 180 return strings.Split(c.String(key), ";")
188 } 181 }
189 182
190 // DefaultStrings returns the []string value for a given key. 183 // DefaultStrings returns the []string value for a given key.
191 // if err != nil return defaltval 184 // if err != nil return defaltval
192 func (c *JsonConfigContainer) DefaultStrings(key string, defaultval []string) []string { 185 func (c *JsonConfigContainer) DefaultStrings(key string, defaultval []string) []string {
193 if v := c.Strings(key); len(v) == 0 { 186 if v := c.Strings(key); len(v) > 0 {
194 return defaultval
195 } else {
196 return v 187 return v
197 } 188 }
189 return defaultval
198 } 190 }
199 191
200 // GetSection returns map for the given section 192 // GetSection returns map for the given section
201 func (c *JsonConfigContainer) GetSection(section string) (map[string]string, error) { 193 func (c *JsonConfigContainer) GetSection(section string) (map[string]string, error) {
202 if v, ok := c.data[section]; ok { 194 if v, ok := c.data[section]; ok {
203 return v.(map[string]string), nil 195 return v.(map[string]string), nil
204 } else {
205 return nil, errors.New("not exist setction")
206 } 196 }
197 return nil, errors.New("nonexist section " + section)
207 } 198 }
208 199
209 // SaveConfigFile save the config into file 200 // SaveConfigFile save the config into file
...@@ -222,7 +213,7 @@ func (c *JsonConfigContainer) SaveConfigFile(filename string) (err error) { ...@@ -222,7 +213,7 @@ func (c *JsonConfigContainer) SaveConfigFile(filename string) (err error) {
222 return err 213 return err
223 } 214 }
224 215
225 // WriteValue writes a new value for key. 216 // Set writes a new value for key.
226 func (c *JsonConfigContainer) Set(key, val string) error { 217 func (c *JsonConfigContainer) Set(key, val string) error {
227 c.Lock() 218 c.Lock()
228 defer c.Unlock() 219 defer c.Unlock()
...@@ -241,18 +232,20 @@ func (c *JsonConfigContainer) DIY(key string) (v interface{}, err error) { ...@@ -241,18 +232,20 @@ func (c *JsonConfigContainer) DIY(key string) (v interface{}, err error) {
241 232
242 // section.key or key 233 // section.key or key
243 func (c *JsonConfigContainer) getData(key string) interface{} { 234 func (c *JsonConfigContainer) getData(key string) interface{} {
244 c.RLock()
245 defer c.RUnlock()
246 if len(key) == 0 { 235 if len(key) == 0 {
247 return nil 236 return nil
248 } 237 }
249 sectionKey := strings.Split(key, "::") 238
250 if len(sectionKey) >= 2 { 239 c.RLock()
251 curValue, ok := c.data[sectionKey[0]] 240 defer c.RUnlock()
241
242 sectionKeys := strings.Split(key, "::")
243 if len(sectionKeys) >= 2 {
244 curValue, ok := c.data[sectionKeys[0]]
252 if !ok { 245 if !ok {
253 return nil 246 return nil
254 } 247 }
255 for _, key := range sectionKey[1:] { 248 for _, key := range sectionKeys[1:] {
256 if v, ok := curValue.(map[string]interface{}); ok { 249 if v, ok := curValue.(map[string]interface{}); ok {
257 if curValue, ok = v[key]; !ok { 250 if curValue, ok = v[key]; !ok {
258 return nil 251 return nil
......
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
21 21
22 var jsoncontext = `{ 22 var jsoncontext = `{
23 "appname": "beeapi", 23 "appname": "beeapi",
24 "testnames": "foo;bar",
24 "httpport": 8080, 25 "httpport": 8080,
25 "mysqlport": 3600, 26 "mysqlport": 3600,
26 "PI": 3.1415976, 27 "PI": 3.1415976,
...@@ -28,8 +29,8 @@ var jsoncontext = `{ ...@@ -28,8 +29,8 @@ var jsoncontext = `{
28 "autorender": false, 29 "autorender": false,
29 "copyrequestbody": true, 30 "copyrequestbody": true,
30 "database": { 31 "database": {
31 "host": "host", 32 "host": "host",
32 "port": "port", 33 "port": "port",
33 "database": "database", 34 "database": "database",
34 "username": "username", 35 "username": "username",
35 "password": "password", 36 "password": "password",
...@@ -122,6 +123,12 @@ func TestJson(t *testing.T) { ...@@ -122,6 +123,12 @@ func TestJson(t *testing.T) {
122 if jsonconf.String("runmode") != "dev" { 123 if jsonconf.String("runmode") != "dev" {
123 t.Fatal("runmode not equal to dev") 124 t.Fatal("runmode not equal to dev")
124 } 125 }
126 if v := jsonconf.Strings("unknown"); len(v) > 0 {
127 t.Fatal("unknown strings, the length should be 0")
128 }
129 if v := jsonconf.Strings("testnames"); len(v) != 2 {
130 t.Fatal("testnames length should be 2")
131 }
125 if v, err := jsonconf.Bool("autorender"); err != nil || v != false { 132 if v, err := jsonconf.Bool("autorender"); err != nil || v != false {
126 t.Error(v) 133 t.Error(v)
127 t.Fatal(err) 134 t.Fatal(err)
...@@ -179,4 +186,8 @@ func TestJson(t *testing.T) { ...@@ -179,4 +186,8 @@ func TestJson(t *testing.T) {
179 if _, err := jsonconf.Bool("unknown"); err == nil { 186 if _, err := jsonconf.Bool("unknown"); err == nil {
180 t.Error("unknown keys should return an error when expecting a Bool") 187 t.Error("unknown keys should return an error when expecting a Bool")
181 } 188 }
189
190 if !jsonconf.DefaultBool("unknow", true) {
191 t.Error("unknown keys with default value wrong")
192 }
182 } 193 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!