baf2c63d by Michael Hatch

Merge branch 'astaxie-master'

2 parents 9c5348f6 7f977a0c
Showing 159 changed files with 2487 additions and 919 deletions
1 .idea
1 .DS_Store 2 .DS_Store
2 *.swp 3 *.swp
3 *.swo 4 *.swo
......
1 {
2 "file_line": 500,
3 "func_line": 80,
4 "params_num":4,
5 "results_num":3,
6 "formated": true,
7 "pkg_name": true,
8 "camel_name":true,
9 "ignore":[
10 "a/*",
11 "b/*/c/*.go"
12 ],
13 "fatal":[
14 "formated"
15 ]
16 }
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
2 2
3 [![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest) 3 [![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest)
4 4
5 beego is a Go Framework inspired by tornado and sinatra. 5 beego is an open-source, high-performance, modularity, full-stack web framework.
6
7 It is a simple & powerful web framework.
8 6
9 More info [beego.me](http://beego.me) 7 More info [beego.me](http://beego.me)
10 8
...@@ -12,20 +10,18 @@ More info [beego.me](http://beego.me) ...@@ -12,20 +10,18 @@ More info [beego.me](http://beego.me)
12 10
13 * RESTful support 11 * RESTful support
14 * MVC architecture 12 * MVC architecture
15 * Session support (store in memory, file, Redis or MySQL) 13 * modularity
16 * Cache support (store in memory, Redis or Memcache) 14 * auto API documents
17 * Global Config 15 * annotation router
18 * Intelligent routing 16 * namespace
19 * Thread-safe map 17 * powerful develop tools
20 * Friendly displaying of errors 18 * full stack for web & API
21 * Useful template functions
22
23 19
24 ## Documentation 20 ## Documentation
25 21
26 [English](http://beego.me/docs/intro/) 22 [English](http://beego.me/docs/intro/)
27 23
28 [API](http://gowalker.org/github.com/astaxie/beego) 24 [API](http://godoc.org/github.com/astaxie/beego)
29 25
30 [中文文档](http://beego.me/docs/intro/) 26 [中文文档](http://beego.me/docs/intro/)
31 27
...@@ -33,7 +29,4 @@ More info [beego.me](http://beego.me) ...@@ -33,7 +29,4 @@ More info [beego.me](http://beego.me)
33 ## LICENSE 29 ## LICENSE
34 30
35 beego is licensed under the Apache Licence, Version 2.0 31 beego is licensed under the Apache Licence, Version 2.0
36 (http://www.apache.org/licenses/LICENSE-2.0.html).
37
38 [![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
39 [koding]: https://koding.com/Teamwork?import=https://github.com/astaxie/beego/archive/master.zip&c=git1
...\ No newline at end of file ...\ No newline at end of file
32 (http://www.apache.org/licenses/LICENSE-2.0.html).
...\ No newline at end of file ...\ No newline at end of file
......
This diff is collapsed. Click to expand it.
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
...@@ -66,6 +74,7 @@ func (app *App) Run() { ...@@ -66,6 +74,7 @@ func (app *App) Run() {
66 74
67 if EnableHttpTLS { 75 if EnableHttpTLS {
68 go func() { 76 go func() {
77 time.Sleep(20 * time.Microsecond)
69 if HttpsPort != 0 { 78 if HttpsPort != 0 {
70 app.Server.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort) 79 app.Server.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort)
71 } 80 }
...@@ -80,6 +89,7 @@ func (app *App) Run() { ...@@ -80,6 +89,7 @@ func (app *App) Run() {
80 89
81 if EnableHttpListen { 90 if EnableHttpListen {
82 go func() { 91 go func() {
92 app.Server.Addr = addr
83 err := app.Server.ListenAndServe() 93 err := app.Server.ListenAndServe()
84 if err != nil { 94 if err != nil {
85 BeeLogger.Critical("ListenAndServe: ", err) 95 BeeLogger.Critical("ListenAndServe: ", err)
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
15 // beego is an open-source, high-performance, modularity, full-stack web framework
16 //
17 // package main
18 //
19 // import "github.com/astaxie/beego"
20 //
21 // func main() {
22 // beego.Run()
23 // }
24 //
25 // more infomation: http://beego.me
7 package beego 26 package beego
8 27
9 import ( 28 import (
...@@ -19,7 +38,7 @@ import ( ...@@ -19,7 +38,7 @@ import (
19 ) 38 )
20 39
21 // beego web framework version. 40 // beego web framework version.
22 const VERSION = "1.3.1" 41 const VERSION = "1.4.0"
23 42
24 type hookfunc func() error //hook function to run 43 type hookfunc func() error //hook function to run
25 var hooks []hookfunc //hook function slice to store the hookfunc 44 var hooks []hookfunc //hook function slice to store the hookfunc
...@@ -359,6 +378,7 @@ func initBeforeHttpRun() { ...@@ -359,6 +378,7 @@ func initBeforeHttpRun() {
359 `"sessionIDHashFunc":"` + SessionHashFunc + `",` + 378 `"sessionIDHashFunc":"` + SessionHashFunc + `",` +
360 `"sessionIDHashKey":"` + SessionHashKey + `",` + 379 `"sessionIDHashKey":"` + SessionHashKey + `",` +
361 `"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` + 380 `"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` +
381 `"domain":"` + SessionDomain + `",` +
362 `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}` 382 `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}`
363 } 383 }
364 GlobalSessions, err = session.NewManager(SessionProvider, 384 GlobalSessions, err = session.NewManager(SessionProvider,
...@@ -380,14 +400,13 @@ func initBeforeHttpRun() { ...@@ -380,14 +400,13 @@ func initBeforeHttpRun() {
380 middleware.AppName = AppName 400 middleware.AppName = AppName
381 middleware.RegisterErrorHandler() 401 middleware.RegisterErrorHandler()
382 402
383 for u, _ := range StaticDir {
384 Get(u, serverStaticRouter)
385 Get(u+"/*", serverStaticRouter)
386 }
387 if EnableDocs { 403 if EnableDocs {
388 Get("/docs", serverDocs) 404 Get("/docs", serverDocs)
389 Get("/docs/*", serverDocs) 405 Get("/docs/*", serverDocs)
390 } 406 }
407
408 //init mime
409 AddAPPStartHook(initMime)
391 } 410 }
392 411
393 // this function is for test package init 412 // this function is for test package init
...@@ -406,6 +425,4 @@ func TestBeegoInit(apppath string) { ...@@ -406,6 +425,4 @@ func TestBeegoInit(apppath string) {
406 425
407 func init() { 426 func init() {
408 hooks = make([]hookfunc, 0) 427 hooks = make([]hookfunc, 0)
409 //init mime
410 AddAPPStartHook(initMime)
411 } 428 }
......
...@@ -22,7 +22,7 @@ First you must import it ...@@ -22,7 +22,7 @@ First you must import it
22 22
23 Then init a Cache (example with memory adapter) 23 Then init a Cache (example with memory adapter)
24 24
25 bm, err := NewCache("memory", `{"interval":60}`) 25 bm, err := cache.NewCache("memory", `{"interval":60}`)
26 26
27 Use it like this: 27 Use it like this:
28 28
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
15 // Usage:
16 //
17 // import(
18 // "github.com/astaxie/beego/cache"
19 // )
20 //
21 // bm, err := cache.NewCache("memory", `{"interval":60}`)
22 //
23 // Use it like this:
24 //
25 // bm.Put("astaxie", 1, 10)
26 // bm.Get("astaxie")
27 // bm.IsExist("astaxie")
28 // bm.Delete("astaxie")
29 //
30 // more docs http://beego.me/docs/module/cache.md
7 package cache 31 package cache
8 32
9 import ( 33 import (
...@@ -13,7 +37,7 @@ import ( ...@@ -13,7 +37,7 @@ import (
13 // Cache interface contains all behaviors for cache adapter. 37 // Cache interface contains all behaviors for cache adapter.
14 // usage: 38 // usage:
15 // cache.Register("file",cache.NewFileCache()) // this operation is run in init method of file.go. 39 // cache.Register("file",cache.NewFileCache()) // this operation is run in init method of file.go.
16 // c := cache.NewCache("file","{....}") 40 // c,err := cache.NewCache("file","{....}")
17 // c.Put("key",value,3600) 41 // c.Put("key",value,3600)
18 // v := c.Get("key") 42 // v := c.Get("key")
19 // 43 //
...@@ -31,11 +55,11 @@ type Cache interface { ...@@ -31,11 +55,11 @@ type Cache interface {
31 Incr(key string) error 55 Incr(key string) error
32 // decrease cached int value by key, as a counter. 56 // decrease cached int value by key, as a counter.
33 Decr(key string) error 57 Decr(key string) error
34 // check cached value is existed or not. 58 // check if cached value exists or not.
35 IsExist(key string) bool 59 IsExist(key string) bool
36 // clear all cache. 60 // clear all cache.
37 ClearAll() error 61 ClearAll() error
38 // start gc routine via config string setting. 62 // start gc routine based on config string settings.
39 StartAndGC(config string) error 63 StartAndGC(config string) error
40 } 64 }
41 65
...@@ -48,23 +72,24 @@ func Register(name string, adapter Cache) { ...@@ -48,23 +72,24 @@ func Register(name string, adapter Cache) {
48 if adapter == nil { 72 if adapter == nil {
49 panic("cache: Register adapter is nil") 73 panic("cache: Register adapter is nil")
50 } 74 }
51 if _, dup := adapters[name]; dup { 75 if _, ok := adapters[name]; ok {
52 panic("cache: Register called twice for adapter " + name) 76 panic("cache: Register called twice for adapter " + name)
53 } 77 }
54 adapters[name] = adapter 78 adapters[name] = adapter
55 } 79 }
56 80
57 // Create a new cache driver by adapter and config string. 81 // Create a new cache driver by adapter name and config string.
58 // config need to be correct JSON as string: {"interval":360}. 82 // config need to be correct JSON as string: {"interval":360}.
59 // it will start gc automatically. 83 // it will start gc automatically.
60 func NewCache(adapterName, config string) (Cache, error) { 84 func NewCache(adapterName, config string) (adapter Cache, e error) {
61 adapter, ok := adapters[adapterName] 85 adapter, ok := adapters[adapterName]
62 if !ok { 86 if !ok {
63 return nil, fmt.Errorf("cache: unknown adaptername %q (forgotten import?)", adapterName) 87 e = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName)
88 return
64 } 89 }
65 err := adapter.StartAndGC(config) 90 err := adapter.StartAndGC(config)
66 if err != nil { 91 if err != nil {
67 return nil, err 92 adapter = nil
68 } 93 }
69 return adapter, nil 94 return
70 } 95 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package cache 15 package cache
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package cache 15 package cache
8 16
...@@ -19,12 +27,11 @@ func GetString(v interface{}) string { ...@@ -19,12 +27,11 @@ func GetString(v interface{}) string {
19 case []byte: 27 case []byte:
20 return string(result) 28 return string(result)
21 default: 29 default:
22 if v == nil { 30 if v != nil {
23 return ""
24 } else {
25 return fmt.Sprintf("%v", result) 31 return fmt.Sprintf("%v", result)
26 } 32 }
27 } 33 }
34 return ""
28 } 35 }
29 36
30 // convert interface to int. 37 // convert interface to int.
...@@ -37,12 +44,9 @@ func GetInt(v interface{}) int { ...@@ -37,12 +44,9 @@ func GetInt(v interface{}) int {
37 case int64: 44 case int64:
38 return int(result) 45 return int(result)
39 default: 46 default:
40 d := GetString(v) 47 if d := GetString(v); d != "" {
41 if d != "" { 48 value, _ := strconv.Atoi(d)
42 value, err := strconv.Atoi(d) 49 return value
43 if err == nil {
44 return value
45 }
46 } 50 }
47 } 51 }
48 return 0 52 return 0
...@@ -58,12 +62,10 @@ func GetInt64(v interface{}) int64 { ...@@ -58,12 +62,10 @@ func GetInt64(v interface{}) int64 {
58 case int64: 62 case int64:
59 return result 63 return result
60 default: 64 default:
61 d := GetString(v) 65
62 if d != "" { 66 if d := GetString(v); d != "" {
63 result, err := strconv.ParseInt(d, 10, 64) 67 value, _ := strconv.ParseInt(d, 10, 64)
64 if err == nil { 68 return value
65 return result
66 }
67 } 69 }
68 } 70 }
69 return 0 71 return 0
...@@ -75,12 +77,9 @@ func GetFloat64(v interface{}) float64 { ...@@ -75,12 +77,9 @@ func GetFloat64(v interface{}) float64 {
75 case float64: 77 case float64:
76 return result 78 return result
77 default: 79 default:
78 d := GetString(v) 80 if d := GetString(v); d != "" {
79 if d != "" { 81 value, _ := strconv.ParseFloat(d, 64)
80 value, err := strconv.ParseFloat(d, 64) 82 return value
81 if err == nil {
82 return value
83 }
84 } 83 }
85 } 84 }
86 return 0 85 return 0
...@@ -92,12 +91,9 @@ func GetBool(v interface{}) bool { ...@@ -92,12 +91,9 @@ func GetBool(v interface{}) bool {
92 case bool: 91 case bool:
93 return result 92 return result
94 default: 93 default:
95 d := GetString(v) 94 if d := GetString(v); d != "" {
96 if d != "" { 95 value, _ := strconv.ParseBool(d)
97 result, err := strconv.ParseBool(d) 96 return value
98 if err == nil {
99 return result
100 }
101 } 97 }
102 } 98 }
103 return false 99 return false
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package cache 15 package cache
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package cache 15 package cache
8 16
...@@ -57,12 +65,10 @@ func NewFileCache() *FileCache { ...@@ -57,12 +65,10 @@ func NewFileCache() *FileCache {
57 65
58 // Start and begin gc for file cache. 66 // Start and begin gc for file cache.
59 // the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0} 67 // the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}
60 func (this *FileCache) StartAndGC(config string) error { 68 func (fc *FileCache) StartAndGC(config string) error {
61 69
62 var cfg map[string]string 70 var cfg map[string]string
63 json.Unmarshal([]byte(config), &cfg) 71 json.Unmarshal([]byte(config), &cfg)
64 //fmt.Println(cfg)
65 //fmt.Println(config)
66 if _, ok := cfg["CachePath"]; !ok { 72 if _, ok := cfg["CachePath"]; !ok {
67 cfg["CachePath"] = FileCachePath 73 cfg["CachePath"] = FileCachePath
68 } 74 }
...@@ -75,69 +81,53 @@ func (this *FileCache) StartAndGC(config string) error { ...@@ -75,69 +81,53 @@ func (this *FileCache) StartAndGC(config string) error {
75 if _, ok := cfg["EmbedExpiry"]; !ok { 81 if _, ok := cfg["EmbedExpiry"]; !ok {
76 cfg["EmbedExpiry"] = strconv.FormatInt(FileCacheEmbedExpiry, 10) 82 cfg["EmbedExpiry"] = strconv.FormatInt(FileCacheEmbedExpiry, 10)
77 } 83 }
78 this.CachePath = cfg["CachePath"] 84 fc.CachePath = cfg["CachePath"]
79 this.FileSuffix = cfg["FileSuffix"] 85 fc.FileSuffix = cfg["FileSuffix"]
80 this.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"]) 86 fc.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
81 this.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"]) 87 fc.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])
82 88
83 this.Init() 89 fc.Init()
84 return nil 90 return nil
85 } 91 }
86 92
87 // Init will make new dir for file cache if not exist. 93 // Init will make new dir for file cache if not exist.
88 func (this *FileCache) Init() { 94 func (fc *FileCache) Init() {
89 app := filepath.Dir(os.Args[0]) 95 app := filepath.Dir(os.Args[0])
90 this.CachePath = filepath.Join(app, this.CachePath) 96 fc.CachePath = filepath.Join(app, fc.CachePath)
91 ok, err := exists(this.CachePath) 97 if ok, _ := exists(fc.CachePath); !ok { // todo : error handle
92 if err != nil { // print error 98 _ = os.MkdirAll(fc.CachePath, os.ModePerm) // todo : error handle
93 //fmt.Println(err)
94 } 99 }
95 if !ok {
96 if err = os.Mkdir(this.CachePath, os.ModePerm); err != nil {
97 //fmt.Println(err);
98 }
99 }
100 //fmt.Println(this.getCacheFileName("123456"));
101 } 100 }
102 101
103 // get cached file name. it's md5 encoded. 102 // get cached file name. it's md5 encoded.
104 func (this *FileCache) getCacheFileName(key string) string { 103 func (fc *FileCache) getCacheFileName(key string) string {
105 m := md5.New() 104 m := md5.New()
106 io.WriteString(m, key) 105 io.WriteString(m, key)
107 keyMd5 := hex.EncodeToString(m.Sum(nil)) 106 keyMd5 := hex.EncodeToString(m.Sum(nil))
108 cachePath := this.CachePath 107 cachePath := fc.CachePath
109 //fmt.Println("cachepath : " , cachePath) 108 switch fc.DirectoryLevel {
110 //fmt.Println("md5" , keyMd5);
111 switch this.DirectoryLevel {
112 case 2: 109 case 2:
113 cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4]) 110 cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
114 case 1: 111 case 1:
115 cachePath = filepath.Join(cachePath, keyMd5[0:2]) 112 cachePath = filepath.Join(cachePath, keyMd5[0:2])
116 } 113 }
117 114
118 ok, err := exists(cachePath) 115 if ok, _ := exists(cachePath); !ok { // todo : error handle
119 if err != nil { 116 _ = os.MkdirAll(cachePath, os.ModePerm) // todo : error handle
120 //fmt.Println(err)
121 } 117 }
122 if !ok { 118
123 if err = os.MkdirAll(cachePath, os.ModePerm); err != nil { 119 return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix))
124 //fmt.Println(err);
125 }
126 }
127 return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, this.FileSuffix))
128 } 120 }
129 121
130 // Get value from file cache. 122 // Get value from file cache.
131 // if non-exist or expired, return empty string. 123 // if non-exist or expired, return empty string.
132 func (this *FileCache) Get(key string) interface{} { 124 func (fc *FileCache) Get(key string) interface{} {
133 filename := this.getCacheFileName(key) 125 fileData, err := File_get_contents(fc.getCacheFileName(key))
134 filedata, err := File_get_contents(filename)
135 //fmt.Println("get length:" , len(filedata));
136 if err != nil { 126 if err != nil {
137 return "" 127 return ""
138 } 128 }
139 var to FileCacheItem 129 var to FileCacheItem
140 Gob_decode(filedata, &to) 130 Gob_decode(fileData, &to)
141 if to.Expired < time.Now().Unix() { 131 if to.Expired < time.Now().Unix() {
142 return "" 132 return ""
143 } 133 }
...@@ -147,12 +137,10 @@ func (this *FileCache) Get(key string) interface{} { ...@@ -147,12 +137,10 @@ func (this *FileCache) Get(key string) interface{} {
147 // Put value into file cache. 137 // Put value into file cache.
148 // timeout means how long to keep this file, unit of ms. 138 // timeout means how long to keep this file, unit of ms.
149 // if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever. 139 // if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever.
150 func (this *FileCache) Put(key string, val interface{}, timeout int64) error { 140 func (fc *FileCache) Put(key string, val interface{}, timeout int64) error {
151 gob.Register(val) 141 gob.Register(val)
152 142
153 filename := this.getCacheFileName(key) 143 item := FileCacheItem{Data: val}
154 var item FileCacheItem
155 item.Data = val
156 if timeout == FileCacheEmbedExpiry { 144 if timeout == FileCacheEmbedExpiry {
157 item.Expired = time.Now().Unix() + (86400 * 365 * 10) // ten years 145 item.Expired = time.Now().Unix() + (86400 * 365 * 10) // ten years
158 } else { 146 } else {
...@@ -163,13 +151,12 @@ func (this *FileCache) Put(key string, val interface{}, timeout int64) error { ...@@ -163,13 +151,12 @@ func (this *FileCache) Put(key string, val interface{}, timeout int64) error {
163 if err != nil { 151 if err != nil {
164 return err 152 return err
165 } 153 }
166 err = File_put_contents(filename, data) 154 return File_put_contents(fc.getCacheFileName(key), data)
167 return err
168 } 155 }
169 156
170 // Delete file cache value. 157 // Delete file cache value.
171 func (this *FileCache) Delete(key string) error { 158 func (fc *FileCache) Delete(key string) error {
172 filename := this.getCacheFileName(key) 159 filename := fc.getCacheFileName(key)
173 if ok, _ := exists(filename); ok { 160 if ok, _ := exists(filename); ok {
174 return os.Remove(filename) 161 return os.Remove(filename)
175 } 162 }
...@@ -177,44 +164,41 @@ func (this *FileCache) Delete(key string) error { ...@@ -177,44 +164,41 @@ func (this *FileCache) Delete(key string) error {
177 } 164 }
178 165
179 // Increase cached int value. 166 // Increase cached int value.
180 // this value is saving forever unless Delete. 167 // fc value is saving forever unless Delete.
181 func (this *FileCache) Incr(key string) error { 168 func (fc *FileCache) Incr(key string) error {
182 data := this.Get(key) 169 data := fc.Get(key)
183 var incr int 170 var incr int
184 //fmt.Println(reflect.TypeOf(data).Name())
185 if reflect.TypeOf(data).Name() != "int" { 171 if reflect.TypeOf(data).Name() != "int" {
186 incr = 0 172 incr = 0
187 } else { 173 } else {
188 incr = data.(int) + 1 174 incr = data.(int) + 1
189 } 175 }
190 this.Put(key, incr, FileCacheEmbedExpiry) 176 fc.Put(key, incr, FileCacheEmbedExpiry)
191 return nil 177 return nil
192 } 178 }
193 179
194 // Decrease cached int value. 180 // Decrease cached int value.
195 func (this *FileCache) Decr(key string) error { 181 func (fc *FileCache) Decr(key string) error {
196 data := this.Get(key) 182 data := fc.Get(key)
197 var decr int 183 var decr int
198 if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 { 184 if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
199 decr = 0 185 decr = 0
200 } else { 186 } else {
201 decr = data.(int) - 1 187 decr = data.(int) - 1
202 } 188 }
203 this.Put(key, decr, FileCacheEmbedExpiry) 189 fc.Put(key, decr, FileCacheEmbedExpiry)
204 return nil 190 return nil
205 } 191 }
206 192
207 // Check value is exist. 193 // Check value is exist.
208 func (this *FileCache) IsExist(key string) bool { 194 func (fc *FileCache) IsExist(key string) bool {
209 filename := this.getCacheFileName(key) 195 ret, _ := exists(fc.getCacheFileName(key))
210 ret, _ := exists(filename)
211 return ret 196 return ret
212 } 197 }
213 198
214 // Clean cached files. 199 // Clean cached files.
215 // not implemented. 200 // not implemented.
216 func (this *FileCache) ClearAll() error { 201 func (fc *FileCache) ClearAll() error {
217 //this.CachePath
218 return nil 202 return nil
219 } 203 }
220 204
...@@ -232,22 +216,22 @@ func exists(path string) (bool, error) { ...@@ -232,22 +216,22 @@ func exists(path string) (bool, error) {
232 216
233 // Get bytes to file. 217 // Get bytes to file.
234 // if non-exist, create this file. 218 // if non-exist, create this file.
235 func File_get_contents(filename string) ([]byte, error) { 219 func File_get_contents(filename string) (data []byte, e error) {
236 f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm) 220 f, e := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
237 if err != nil { 221 if e != nil {
238 return []byte(""), err 222 return
239 } 223 }
240 defer f.Close() 224 defer f.Close()
241 stat, err := f.Stat() 225 stat, e := f.Stat()
242 if err != nil { 226 if e != nil {
243 return []byte(""), err 227 return
244 } 228 }
245 data := make([]byte, stat.Size()) 229 data = make([]byte, stat.Size())
246 result, err := f.Read(data) 230 result, e := f.Read(data)
247 if int64(result) == stat.Size() { 231 if e != nil || int64(result) != stat.Size() {
248 return data, err 232 return nil, e
249 } 233 }
250 return []byte(""), err 234 return
251 } 235 }
252 236
253 // Put bytes to file. 237 // Put bytes to file.
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 6 //
7 package cache 7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // package memcahe for cache provider
16 //
17 // depend on github.com/bradfitz/gomemcache/memcache
18 //
19 // go install github.com/bradfitz/gomemcache/memcache
20 //
21 // Usage:
22 // import(
23 // _ "github.com/astaxie/beego/cache/memcache"
24 // "github.com/astaxie/beego/cache"
25 // )
26 //
27 // bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
28 //
29 // more docs http://beego.me/docs/module/cache.md
30 package memcache
8 31
9 import ( 32 import (
10 "encoding/json" 33 "encoding/json"
11 "errors" 34 "errors"
35 "strings"
12 36
13 "github.com/beego/memcache" 37 "github.com/bradfitz/gomemcache/memcache"
14 38
15 "github.com/astaxie/beego/cache" 39 "github.com/astaxie/beego/cache"
16 ) 40 )
17 41
18 // Memcache adapter. 42 // Memcache adapter.
19 type MemcacheCache struct { 43 type MemcacheCache struct {
20 c *memcache.Connection 44 conn *memcache.Client
21 conninfo string 45 conninfo []string
22 } 46 }
23 47
24 // create new memcache adapter. 48 // create new memcache adapter.
...@@ -28,32 +52,21 @@ func NewMemCache() *MemcacheCache { ...@@ -28,32 +52,21 @@ func NewMemCache() *MemcacheCache {
28 52
29 // get value from memcache. 53 // get value from memcache.
30 func (rc *MemcacheCache) Get(key string) interface{} { 54 func (rc *MemcacheCache) Get(key string) interface{} {
31 if rc.c == nil { 55 if rc.conn == nil {
32 var err error 56 if err := rc.connectInit(); err != nil {
33 rc.c, err = rc.connectInit()
34 if err != nil {
35 return err 57 return err
36 } 58 }
37 } 59 }
38 v, err := rc.c.Get(key) 60 if item, err := rc.conn.Get(key); err == nil {
39 if err != nil { 61 return string(item.Value)
40 return nil
41 }
42 var contain interface{}
43 if len(v) > 0 {
44 contain = string(v[0].Value)
45 } else {
46 contain = nil
47 } 62 }
48 return contain 63 return nil
49 } 64 }
50 65
51 // put value to memcache. only support string. 66 // put value to memcache. only support string.
52 func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error { 67 func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error {
53 if rc.c == nil { 68 if rc.conn == nil {
54 var err error 69 if err := rc.connectInit(); err != nil {
55 rc.c, err = rc.connectInit()
56 if err != nil {
57 return err 70 return err
58 } 71 }
59 } 72 }
...@@ -61,69 +74,64 @@ func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error { ...@@ -61,69 +74,64 @@ func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error {
61 if !ok { 74 if !ok {
62 return errors.New("val must string") 75 return errors.New("val must string")
63 } 76 }
64 stored, err := rc.c.Set(key, 0, uint64(timeout), []byte(v)) 77 item := memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout)}
65 if err == nil && stored == false { 78 return rc.conn.Set(&item)
66 return errors.New("stored fail")
67 }
68 return err
69 } 79 }
70 80
71 // delete value in memcache. 81 // delete value in memcache.
72 func (rc *MemcacheCache) Delete(key string) error { 82 func (rc *MemcacheCache) Delete(key string) error {
73 if rc.c == nil { 83 if rc.conn == nil {
74 var err error 84 if err := rc.connectInit(); err != nil {
75 rc.c, err = rc.connectInit()
76 if err != nil {
77 return err 85 return err
78 } 86 }
79 } 87 }
80 _, err := rc.c.Delete(key) 88 return rc.conn.Delete(key)
81 return err
82 } 89 }
83 90
84 // [Not Support]
85 // increase counter. 91 // increase counter.
86 func (rc *MemcacheCache) Incr(key string) error { 92 func (rc *MemcacheCache) Incr(key string) error {
87 return errors.New("not support in memcache") 93 if rc.conn == nil {
94 if err := rc.connectInit(); err != nil {
95 return err
96 }
97 }
98 _, err := rc.conn.Increment(key, 1)
99 return err
88 } 100 }
89 101
90 // [Not Support]
91 // decrease counter. 102 // decrease counter.
92 func (rc *MemcacheCache) Decr(key string) error { 103 func (rc *MemcacheCache) Decr(key string) error {
93 return errors.New("not support in memcache") 104 if rc.conn == nil {
105 if err := rc.connectInit(); err != nil {
106 return err
107 }
108 }
109 _, err := rc.conn.Decrement(key, 1)
110 return err
94 } 111 }
95 112
96 // check value exists in memcache. 113 // check value exists in memcache.
97 func (rc *MemcacheCache) IsExist(key string) bool { 114 func (rc *MemcacheCache) IsExist(key string) bool {
98 if rc.c == nil { 115 if rc.conn == nil {
99 var err error 116 if err := rc.connectInit(); err != nil {
100 rc.c, err = rc.connectInit()
101 if err != nil {
102 return false 117 return false
103 } 118 }
104 } 119 }
105 v, err := rc.c.Get(key) 120 _, err := rc.conn.Get(key)
106 if err != nil { 121 if err != nil {
107 return false 122 return false
108 } 123 }
109 if len(v) == 0 { 124 return true
110 return false
111 } else {
112 return true
113 }
114 } 125 }
115 126
116 // clear all cached in memcache. 127 // clear all cached in memcache.
117 func (rc *MemcacheCache) ClearAll() error { 128 func (rc *MemcacheCache) ClearAll() error {
118 if rc.c == nil { 129 if rc.conn == nil {
119 var err error 130 if err := rc.connectInit(); err != nil {
120 rc.c, err = rc.connectInit()
121 if err != nil {
122 return err 131 return err
123 } 132 }
124 } 133 }
125 err := rc.c.FlushAll() 134 return rc.conn.FlushAll()
126 return err
127 } 135 }
128 136
129 // start memcache adapter. 137 // start memcache adapter.
...@@ -135,24 +143,19 @@ func (rc *MemcacheCache) StartAndGC(config string) error { ...@@ -135,24 +143,19 @@ func (rc *MemcacheCache) StartAndGC(config string) error {
135 if _, ok := cf["conn"]; !ok { 143 if _, ok := cf["conn"]; !ok {
136 return errors.New("config has no conn key") 144 return errors.New("config has no conn key")
137 } 145 }
138 rc.conninfo = cf["conn"] 146 rc.conninfo = strings.Split(cf["conn"], ";")
139 var err error 147 if rc.conn == nil {
140 if rc.c != nil { 148 if err := rc.connectInit(); err != nil {
141 rc.c, err = rc.connectInit() 149 return err
142 if err != nil {
143 return errors.New("dial tcp conn error")
144 } 150 }
145 } 151 }
146 return nil 152 return nil
147 } 153 }
148 154
149 // connect to memcache and keep the connection. 155 // connect to memcache and keep the connection.
150 func (rc *MemcacheCache) connectInit() (*memcache.Connection, error) { 156 func (rc *MemcacheCache) connectInit() error {
151 c, err := memcache.Connect(rc.conninfo) 157 rc.conn = memcache.New(rc.conninfo...)
152 if err != nil { 158 return nil
153 return nil, err
154 }
155 return c, nil
156 } 159 }
157 160
158 func init() { 161 func init() {
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package cache 15 package cache
8 16
...@@ -46,15 +54,14 @@ func NewMemoryCache() *MemoryCache { ...@@ -46,15 +54,14 @@ func NewMemoryCache() *MemoryCache {
46 func (bc *MemoryCache) Get(name string) interface{} { 54 func (bc *MemoryCache) Get(name string) interface{} {
47 bc.lock.RLock() 55 bc.lock.RLock()
48 defer bc.lock.RUnlock() 56 defer bc.lock.RUnlock()
49 itm, ok := bc.items[name] 57 if itm, ok := bc.items[name]; ok {
50 if !ok { 58 if (time.Now().Unix() - itm.Lastaccess.Unix()) > itm.expired {
51 return nil 59 go bc.Delete(name)
52 } 60 return nil
53 if (time.Now().Unix() - itm.Lastaccess.Unix()) > itm.expired { 61 }
54 go bc.Delete(name) 62 return itm.val
55 return nil
56 } 63 }
57 return itm.val 64 return nil
58 } 65 }
59 66
60 // Put cache to memory. 67 // Put cache to memory.
...@@ -62,12 +69,11 @@ func (bc *MemoryCache) Get(name string) interface{} { ...@@ -62,12 +69,11 @@ func (bc *MemoryCache) Get(name string) interface{} {
62 func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error { 69 func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error {
63 bc.lock.Lock() 70 bc.lock.Lock()
64 defer bc.lock.Unlock() 71 defer bc.lock.Unlock()
65 t := MemoryItem{ 72 bc.items[name] = &MemoryItem{
66 val: value, 73 val: value,
67 Lastaccess: time.Now(), 74 Lastaccess: time.Now(),
68 expired: expired, 75 expired: expired,
69 } 76 }
70 bc.items[name] = &t
71 return nil 77 return nil
72 } 78 }
73 79
...@@ -79,8 +85,7 @@ func (bc *MemoryCache) Delete(name string) error { ...@@ -79,8 +85,7 @@ func (bc *MemoryCache) Delete(name string) error {
79 return errors.New("key not exist") 85 return errors.New("key not exist")
80 } 86 }
81 delete(bc.items, name) 87 delete(bc.items, name)
82 _, valid := bc.items[name] 88 if _, ok := bc.items[name]; ok {
83 if valid {
84 return errors.New("delete key error") 89 return errors.New("delete key error")
85 } 90 }
86 return nil 91 return nil
...@@ -211,8 +216,7 @@ func (bc *MemoryCache) item_expired(name string) bool { ...@@ -211,8 +216,7 @@ func (bc *MemoryCache) item_expired(name string) bool {
211 if !ok { 216 if !ok {
212 return true 217 return true
213 } 218 }
214 sec := time.Now().Unix() - itm.Lastaccess.Unix() 219 if time.Now().Unix()-itm.Lastaccess.Unix() >= itm.expired {
215 if sec >= itm.expired {
216 delete(bc.items, name) 220 delete(bc.items, name)
217 return true 221 return true
218 } 222 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 6 //
7 package cache 7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // package redis for cache provider
16 //
17 // depend on github.com/garyburd/redigo/redis
18 //
19 // go install github.com/garyburd/redigo/redis
20 //
21 // Usage:
22 // import(
23 // _ "github.com/astaxie/beego/cache/redis"
24 // "github.com/astaxie/beego/cache"
25 // )
26 //
27 // bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
28 //
29 // more docs http://beego.me/docs/module/cache.md
30 package redis
8 31
9 import ( 32 import (
10 "encoding/json" 33 "encoding/json"
11 "errors" 34 "errors"
12 "time" 35 "time"
13 36
14 "github.com/beego/redigo/redis" 37 "github.com/garyburd/redigo/redis"
15 38
16 "github.com/astaxie/beego/cache" 39 "github.com/astaxie/beego/cache"
17 ) 40 )
...@@ -43,52 +66,74 @@ func (rc *RedisCache) do(commandName string, args ...interface{}) (reply interfa ...@@ -43,52 +66,74 @@ func (rc *RedisCache) do(commandName string, args ...interface{}) (reply interfa
43 66
44 // Get cache from redis. 67 // Get cache from redis.
45 func (rc *RedisCache) Get(key string) interface{} { 68 func (rc *RedisCache) Get(key string) interface{} {
46 v, err := rc.do("HGET", rc.key, key) 69 if v, err := rc.do("GET", key); err == nil {
47 if err != nil { 70 return v
48 return nil
49 } 71 }
50 72 return nil
51 return v
52 } 73 }
53 74
54 // put cache to redis. 75 // put cache to redis.
55 // timeout is ignored.
56 func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error { 76 func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error {
57 _, err := rc.do("HSET", rc.key, key, val) 77 var err error
78 if _, err = rc.do("SET", key, val); err != nil {
79 return err
80 }
81
82 if _, err = rc.do("HSET", rc.key, key, true); err != nil {
83 return err
84 }
85 _, err = rc.do("EXPIRE", key, timeout)
58 return err 86 return err
59 } 87 }
60 88
61 // delete cache in redis. 89 // delete cache in redis.
62 func (rc *RedisCache) Delete(key string) error { 90 func (rc *RedisCache) Delete(key string) error {
63 _, err := rc.do("HDEL", rc.key, key) 91 var err error
92 if _, err = rc.do("DEL", key); err != nil {
93 return err
94 }
95 _, err = rc.do("HDEL", rc.key, key)
64 return err 96 return err
65 } 97 }
66 98
67 // check cache exist in redis. 99 // check cache's existence in redis.
68 func (rc *RedisCache) IsExist(key string) bool { 100 func (rc *RedisCache) IsExist(key string) bool {
69 v, err := redis.Bool(rc.do("HEXISTS", rc.key, key)) 101 v, err := redis.Bool(rc.do("EXISTS", key))
70 if err != nil { 102 if err != nil {
71 return false 103 return false
72 } 104 }
73 105 if v == false {
106 if _, err = rc.do("HDEL", rc.key, key); err != nil {
107 return false
108 }
109 }
74 return v 110 return v
75 } 111 }
76 112
77 // increase counter in redis. 113 // increase counter in redis.
78 func (rc *RedisCache) Incr(key string) error { 114 func (rc *RedisCache) Incr(key string) error {
79 _, err := redis.Bool(rc.do("HINCRBY", rc.key, key, 1)) 115 _, err := redis.Bool(rc.do("INCRBY", key, 1))
80 return err 116 return err
81 } 117 }
82 118
83 // decrease counter in redis. 119 // decrease counter in redis.
84 func (rc *RedisCache) Decr(key string) error { 120 func (rc *RedisCache) Decr(key string) error {
85 _, err := redis.Bool(rc.do("HINCRBY", rc.key, key, -1)) 121 _, err := redis.Bool(rc.do("INCRBY", key, -1))
86 return err 122 return err
87 } 123 }
88 124
89 // clean all cache in redis. delete this redis collection. 125 // clean all cache in redis. delete this redis collection.
90 func (rc *RedisCache) ClearAll() error { 126 func (rc *RedisCache) ClearAll() error {
91 _, err := rc.do("DEL", rc.key) 127 cachedKeys, err := redis.Strings(rc.do("HKEYS", rc.key))
128 if err != nil {
129 return err
130 }
131 for _, str := range cachedKeys {
132 if _, err = rc.do("DEL", str); err != nil {
133 return err
134 }
135 }
136 _, err = rc.do("DEL", rc.key)
92 return err 137 return err
93 } 138 }
94 139
...@@ -114,26 +159,21 @@ func (rc *RedisCache) StartAndGC(config string) error { ...@@ -114,26 +159,21 @@ func (rc *RedisCache) StartAndGC(config string) error {
114 159
115 c := rc.p.Get() 160 c := rc.p.Get()
116 defer c.Close() 161 defer c.Close()
117 if err := c.Err(); err != nil {
118 return err
119 }
120 162
121 return nil 163 return c.Err()
122 } 164 }
123 165
124 // connect to redis. 166 // connect to redis.
125 func (rc *RedisCache) connectInit() { 167 func (rc *RedisCache) connectInit() {
168 dialFunc := func() (c redis.Conn, err error) {
169 c, err = redis.Dial("tcp", rc.conninfo)
170 return
171 }
126 // initialize a new pool 172 // initialize a new pool
127 rc.p = &redis.Pool{ 173 rc.p = &redis.Pool{
128 MaxIdle: 3, 174 MaxIdle: 3,
129 IdleTimeout: 180 * time.Second, 175 IdleTimeout: 180 * time.Second,
130 Dial: func() (redis.Conn, error) { 176 Dial: dialFunc,
131 c, err := redis.Dial("tcp", rc.conninfo)
132 if err != nil {
133 return nil, err
134 }
135 return c, nil
136 },
137 } 177 }
138 } 178 }
139 179
......
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package redis
16
17 import (
18 "testing"
19 "time"
20
21 "github.com/garyburd/redigo/redis"
22
23 "github.com/astaxie/beego/cache"
24 )
25
26 func TestRedisCache(t *testing.T) {
27 bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
28 if err != nil {
29 t.Error("init err")
30 }
31 if err = bm.Put("astaxie", 1, 10); err != nil {
32 t.Error("set Error", err)
33 }
34 if !bm.IsExist("astaxie") {
35 t.Error("check err")
36 }
37
38 time.Sleep(10 * time.Second)
39
40 if bm.IsExist("astaxie") {
41 t.Error("check err")
42 }
43 if err = bm.Put("astaxie", 1, 10); err != nil {
44 t.Error("set Error", err)
45 }
46
47 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
48 t.Error("get err")
49 }
50
51 if err = bm.Incr("astaxie"); err != nil {
52 t.Error("Incr Error", err)
53 }
54
55 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 2 {
56 t.Error("get err")
57 }
58
59 if err = bm.Decr("astaxie"); err != nil {
60 t.Error("Decr Error", err)
61 }
62
63 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
64 t.Error("get err")
65 }
66 bm.Delete("astaxie")
67 if bm.IsExist("astaxie") {
68 t.Error("delete err")
69 }
70 //test string
71 if err = bm.Put("astaxie", "author", 10); err != nil {
72 t.Error("set Error", err)
73 }
74 if !bm.IsExist("astaxie") {
75 t.Error("check err")
76 }
77
78 if v, _ := redis.String(bm.Get("astaxie"), err); v != "author" {
79 t.Error("get err")
80 }
81 // test clear all
82 if err = bm.ClearAll(); err != nil {
83 t.Error("clear all err")
84 }
85 }
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
...@@ -52,6 +60,7 @@ var ( ...@@ -52,6 +60,7 @@ var (
52 SessionHashKey string // session hash salt string. 60 SessionHashKey string // session hash salt string.
53 SessionCookieLifeTime int // the life time of session id in cookie. 61 SessionCookieLifeTime int // the life time of session id in cookie.
54 SessionAutoSetCookie bool // auto setcookie 62 SessionAutoSetCookie bool // auto setcookie
63 SessionDomain string // the cookie domain default is empty
55 UseFcgi bool 64 UseFcgi bool
56 MaxMemory int64 65 MaxMemory int64
57 EnableGzip bool // flag of enable gzip 66 EnableGzip bool // flag of enable gzip
...@@ -180,147 +189,147 @@ func ParseConfig() (err error) { ...@@ -180,147 +189,147 @@ func ParseConfig() (err error) {
180 return err 189 return err
181 } else { 190 } else {
182 191
183 if v, err := getConfig("string", "HttpAddr"); err == nil { 192 if v, err := GetConfig("string", "HttpAddr"); err == nil {
184 HttpAddr = v.(string) 193 HttpAddr = v.(string)
185 } 194 }
186 195
187 if v, err := getConfig("int", "HttpPort"); err == nil { 196 if v, err := GetConfig("int", "HttpPort"); err == nil {
188 HttpPort = v.(int) 197 HttpPort = v.(int)
189 } 198 }
190 199
191 if v, err := getConfig("bool", "EnableHttpListen"); err == nil { 200 if v, err := GetConfig("bool", "EnableHttpListen"); err == nil {
192 EnableHttpListen = v.(bool) 201 EnableHttpListen = v.(bool)
193 } 202 }
194 203
195 if maxmemory, err := getConfig("int64", "MaxMemory"); err == nil { 204 if maxmemory, err := GetConfig("int64", "MaxMemory"); err == nil {
196 MaxMemory = maxmemory.(int64) 205 MaxMemory = maxmemory.(int64)
197 } 206 }
198 207
199 if appname, _ := getConfig("string", "AppName"); appname != "" { 208 if appname, _ := GetConfig("string", "AppName"); appname != "" {
200 AppName = appname.(string) 209 AppName = appname.(string)
201 } 210 }
202 211
203 if runmode, _ := getConfig("string", "RunMode"); runmode != "" { 212 if runmode, _ := GetConfig("string", "RunMode"); runmode != "" {
204 RunMode = runmode.(string) 213 RunMode = runmode.(string)
205 } 214 }
206 215
207 if autorender, err := getConfig("bool", "AutoRender"); err == nil { 216 if autorender, err := GetConfig("bool", "AutoRender"); err == nil {
208 AutoRender = autorender.(bool) 217 AutoRender = autorender.(bool)
209 } 218 }
210 219
211 if autorecover, err := getConfig("bool", "RecoverPanic"); err == nil { 220 if autorecover, err := GetConfig("bool", "RecoverPanic"); err == nil {
212 RecoverPanic = autorecover.(bool) 221 RecoverPanic = autorecover.(bool)
213 } 222 }
214 223
215 if views, _ := getConfig("string", "ViewsPath"); views != "" { 224 if views, _ := GetConfig("string", "ViewsPath"); views != "" {
216 ViewsPath = views.(string) 225 ViewsPath = views.(string)
217 } 226 }
218 227
219 if sessionon, err := getConfig("bool", "SessionOn"); err == nil { 228 if sessionon, err := GetConfig("bool", "SessionOn"); err == nil {
220 SessionOn = sessionon.(bool) 229 SessionOn = sessionon.(bool)
221 } 230 }
222 231
223 if sessProvider, _ := getConfig("string", "SessionProvider"); sessProvider != "" { 232 if sessProvider, _ := GetConfig("string", "SessionProvider"); sessProvider != "" {
224 SessionProvider = sessProvider.(string) 233 SessionProvider = sessProvider.(string)
225 } 234 }
226 235
227 if sessName, _ := getConfig("string", "SessionName"); sessName != "" { 236 if sessName, _ := GetConfig("string", "SessionName"); sessName != "" {
228 SessionName = sessName.(string) 237 SessionName = sessName.(string)
229 } 238 }
230 239
231 if sesssavepath, _ := getConfig("string", "SessionSavePath"); sesssavepath != "" { 240 if sesssavepath, _ := GetConfig("string", "SessionSavePath"); sesssavepath != "" {
232 SessionSavePath = sesssavepath.(string) 241 SessionSavePath = sesssavepath.(string)
233 } 242 }
234 243
235 if sesshashfunc, _ := getConfig("string", "SessionHashFunc"); sesshashfunc != "" { 244 if sesshashfunc, _ := GetConfig("string", "SessionHashFunc"); sesshashfunc != "" {
236 SessionHashFunc = sesshashfunc.(string) 245 SessionHashFunc = sesshashfunc.(string)
237 } 246 }
238 247
239 if sesshashkey, _ := getConfig("string", "SessionHashKey"); sesshashkey != "" { 248 if sesshashkey, _ := GetConfig("string", "SessionHashKey"); sesshashkey != "" {
240 SessionHashKey = sesshashkey.(string) 249 SessionHashKey = sesshashkey.(string)
241 } 250 }
242 251
243 if sessMaxLifeTime, err := getConfig("int64", "SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 { 252 if sessMaxLifeTime, err := GetConfig("int64", "SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 {
244 SessionGCMaxLifetime = sessMaxLifeTime.(int64) 253 SessionGCMaxLifetime = sessMaxLifeTime.(int64)
245 } 254 }
246 255
247 if sesscookielifetime, err := getConfig("int", "SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 { 256 if sesscookielifetime, err := GetConfig("int", "SessionCookieLifeTime"); err == nil && sesscookielifetime != 0 {
248 SessionCookieLifeTime = sesscookielifetime.(int) 257 SessionCookieLifeTime = sesscookielifetime.(int)
249 } 258 }
250 259
251 if usefcgi, err := getConfig("bool", "UseFcgi"); err == nil { 260 if usefcgi, err := GetConfig("bool", "UseFcgi"); err == nil {
252 UseFcgi = usefcgi.(bool) 261 UseFcgi = usefcgi.(bool)
253 } 262 }
254 263
255 if enablegzip, err := getConfig("bool", "EnableGzip"); err == nil { 264 if enablegzip, err := GetConfig("bool", "EnableGzip"); err == nil {
256 EnableGzip = enablegzip.(bool) 265 EnableGzip = enablegzip.(bool)
257 } 266 }
258 267
259 if directoryindex, err := getConfig("bool", "DirectoryIndex"); err == nil { 268 if directoryindex, err := GetConfig("bool", "DirectoryIndex"); err == nil {
260 DirectoryIndex = directoryindex.(bool) 269 DirectoryIndex = directoryindex.(bool)
261 } 270 }
262 271
263 if timeout, err := getConfig("int64", "HttpServerTimeOut"); err == nil { 272 if timeout, err := GetConfig("int64", "HttpServerTimeOut"); err == nil {
264 HttpServerTimeOut = timeout.(int64) 273 HttpServerTimeOut = timeout.(int64)
265 } 274 }
266 275
267 if errorsshow, err := getConfig("bool", "ErrorsShow"); err == nil { 276 if errorsshow, err := GetConfig("bool", "ErrorsShow"); err == nil {
268 ErrorsShow = errorsshow.(bool) 277 ErrorsShow = errorsshow.(bool)
269 } 278 }
270 279
271 if copyrequestbody, err := getConfig("bool", "CopyRequestBody"); err == nil { 280 if copyrequestbody, err := GetConfig("bool", "CopyRequestBody"); err == nil {
272 CopyRequestBody = copyrequestbody.(bool) 281 CopyRequestBody = copyrequestbody.(bool)
273 } 282 }
274 283
275 if xsrfkey, _ := getConfig("string", "XSRFKEY"); xsrfkey != "" { 284 if xsrfkey, _ := GetConfig("string", "XSRFKEY"); xsrfkey != "" {
276 XSRFKEY = xsrfkey.(string) 285 XSRFKEY = xsrfkey.(string)
277 } 286 }
278 287
279 if enablexsrf, err := getConfig("bool", "EnableXSRF"); err == nil { 288 if enablexsrf, err := GetConfig("bool", "EnableXSRF"); err == nil {
280 EnableXSRF = enablexsrf.(bool) 289 EnableXSRF = enablexsrf.(bool)
281 } 290 }
282 291
283 if expire, err := getConfig("int", "XSRFExpire"); err == nil { 292 if expire, err := GetConfig("int", "XSRFExpire"); err == nil {
284 XSRFExpire = expire.(int) 293 XSRFExpire = expire.(int)
285 } 294 }
286 295
287 if tplleft, _ := getConfig("string", "TemplateLeft"); tplleft != "" { 296 if tplleft, _ := GetConfig("string", "TemplateLeft"); tplleft != "" {
288 TemplateLeft = tplleft.(string) 297 TemplateLeft = tplleft.(string)
289 } 298 }
290 299
291 if tplright, _ := getConfig("string", "TemplateRight"); tplright != "" { 300 if tplright, _ := GetConfig("string", "TemplateRight"); tplright != "" {
292 TemplateRight = tplright.(string) 301 TemplateRight = tplright.(string)
293 } 302 }
294 303
295 if httptls, err := getConfig("bool", "EnableHttpTLS"); err == nil { 304 if httptls, err := GetConfig("bool", "EnableHttpTLS"); err == nil {
296 EnableHttpTLS = httptls.(bool) 305 EnableHttpTLS = httptls.(bool)
297 } 306 }
298 307
299 if httpsport, err := getConfig("int", "HttpsPort"); err == nil { 308 if httpsport, err := GetConfig("int", "HttpsPort"); err == nil {
300 HttpsPort = httpsport.(int) 309 HttpsPort = httpsport.(int)
301 } 310 }
302 311
303 if certfile, _ := getConfig("string", "HttpCertFile"); certfile != "" { 312 if certfile, _ := GetConfig("string", "HttpCertFile"); certfile != "" {
304 HttpCertFile = certfile.(string) 313 HttpCertFile = certfile.(string)
305 } 314 }
306 315
307 if keyfile, _ := getConfig("string", "HttpKeyFile"); keyfile != "" { 316 if keyfile, _ := GetConfig("string", "HttpKeyFile"); keyfile != "" {
308 HttpKeyFile = keyfile.(string) 317 HttpKeyFile = keyfile.(string)
309 } 318 }
310 319
311 if serverName, _ := getConfig("string", "BeegoServerName"); serverName != "" { 320 if serverName, _ := GetConfig("string", "BeegoServerName"); serverName != "" {
312 BeegoServerName = serverName.(string) 321 BeegoServerName = serverName.(string)
313 } 322 }
314 323
315 if flashname, _ := getConfig("string", "FlashName"); flashname != "" { 324 if flashname, _ := GetConfig("string", "FlashName"); flashname != "" {
316 FlashName = flashname.(string) 325 FlashName = flashname.(string)
317 } 326 }
318 327
319 if flashseperator, _ := getConfig("string", "FlashSeperator"); flashseperator != "" { 328 if flashseperator, _ := GetConfig("string", "FlashSeperator"); flashseperator != "" {
320 FlashSeperator = flashseperator.(string) 329 FlashSeperator = flashseperator.(string)
321 } 330 }
322 331
323 if sd, _ := getConfig("string", "StaticDir"); sd != "" { 332 if sd, _ := GetConfig("string", "StaticDir"); sd != "" {
324 for k := range StaticDir { 333 for k := range StaticDir {
325 delete(StaticDir, k) 334 delete(StaticDir, k)
326 } 335 }
...@@ -334,7 +343,7 @@ func ParseConfig() (err error) { ...@@ -334,7 +343,7 @@ func ParseConfig() (err error) {
334 } 343 }
335 } 344 }
336 345
337 if sgz, _ := getConfig("string", "StaticExtensionsToGzip"); sgz != "" { 346 if sgz, _ := GetConfig("string", "StaticExtensionsToGzip"); sgz != "" {
338 extensions := strings.Split(sgz.(string), ",") 347 extensions := strings.Split(sgz.(string), ",")
339 if len(extensions) > 0 { 348 if len(extensions) > 0 {
340 StaticExtensionsToGzip = []string{} 349 StaticExtensionsToGzip = []string{}
...@@ -351,26 +360,37 @@ func ParseConfig() (err error) { ...@@ -351,26 +360,37 @@ func ParseConfig() (err error) {
351 } 360 }
352 } 361 }
353 362
354 if enableadmin, err := getConfig("bool", "EnableAdmin"); err == nil { 363 if enableadmin, err := GetConfig("bool", "EnableAdmin"); err == nil {
355 EnableAdmin = enableadmin.(bool) 364 EnableAdmin = enableadmin.(bool)
356 } 365 }
357 366
358 if adminhttpaddr, _ := getConfig("string", "AdminHttpAddr"); adminhttpaddr != "" { 367 if adminhttpaddr, _ := GetConfig("string", "AdminHttpAddr"); adminhttpaddr != "" {
359 AdminHttpAddr = adminhttpaddr.(string) 368 AdminHttpAddr = adminhttpaddr.(string)
360 } 369 }
361 370
362 if adminhttpport, err := getConfig("int", "AdminHttpPort"); err == nil { 371 if adminhttpport, err := GetConfig("int", "AdminHttpPort"); err == nil {
363 AdminHttpPort = adminhttpport.(int) 372 AdminHttpPort = adminhttpport.(int)
364 } 373 }
365 374
366 if enabledocs, err := getConfig("bool", "EnableDocs"); err == nil { 375 if enabledocs, err := GetConfig("bool", "EnableDocs"); err == nil {
367 EnableDocs = enabledocs.(bool) 376 EnableDocs = enabledocs.(bool)
368 } 377 }
369 } 378 }
370 return nil 379 return nil
371 } 380 }
372 381
373 func getConfig(typ, key string) (interface{}, error) { 382 // Getconfig throw the Runmode
383 // [dev]
384 // name = astaixe
385 // IsEnable = false
386 // [prod]
387 // name = slene
388 // IsEnable = true
389 //
390 // usage:
391 // GetConfig("string", "name")
392 // GetConfig("bool", "IsEnable")
393 func GetConfig(typ, key string) (interface{}, error) {
374 switch typ { 394 switch typ {
375 case "string": 395 case "string":
376 v := AppConfig.String(RunMode + "::" + key) 396 v := AppConfig.String(RunMode + "::" + key)
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
15 // Usage:
16 // import(
17 // "github.com/astaxie/beego/config"
18 // )
19 //
20 // cnf, err := config.NewConfig("ini", "config.conf")
21 //
22 // cnf APIS:
23 //
24 // cnf.Set(key, val string) error
25 // cnf.String(key string) string
26 // cnf.Strings(key string) []string
27 // cnf.Int(key string) (int, error)
28 // cnf.Int64(key string) (int64, error)
29 // cnf.Bool(key string) (bool, error)
30 // cnf.Float(key string) (float64, error)
31 // cnf.DefaultString(key string, defaultval string) string
32 // cnf.DefaultStrings(key string, defaultval []string) []string
33 // cnf.DefaultInt(key string, defaultval int) int
34 // cnf.DefaultInt64(key string, defaultval int64) int64
35 // cnf.DefaultBool(key string, defaultval bool) bool
36 // cnf.DefaultFloat(key string, defaultval float64) float64
37 // cnf.DIY(key string) (interface{}, error)
38 // cnf.GetSection(section string) (map[string]string, error)
39 // cnf.SaveConfigFile(filename string) error
40 //
41 // more docs http://beego.me/docs/module/config.md
7 package config 42 package config
8 43
9 import ( 44 import (
...@@ -19,12 +54,21 @@ type ConfigContainer interface { ...@@ -19,12 +54,21 @@ type ConfigContainer interface {
19 Int64(key string) (int64, error) 54 Int64(key string) (int64, error)
20 Bool(key string) (bool, error) 55 Bool(key string) (bool, error)
21 Float(key string) (float64, error) 56 Float(key string) (float64, error)
57 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.
58 DefaultStrings(key string, defaultval []string) []string //get string slice
59 DefaultInt(key string, defaultval int) int
60 DefaultInt64(key string, defaultval int64) int64
61 DefaultBool(key string, defaultval bool) bool
62 DefaultFloat(key string, defaultval float64) float64
22 DIY(key string) (interface{}, error) 63 DIY(key string) (interface{}, error)
64 GetSection(section string) (map[string]string, error)
65 SaveConfigFile(filename string) error
23 } 66 }
24 67
25 // Config is the adapter interface for parsing config file to get raw data to ConfigContainer. 68 // Config is the adapter interface for parsing config file to get raw data to ConfigContainer.
26 type Config interface { 69 type Config interface {
27 Parse(key string) (ConfigContainer, error) 70 Parse(key string) (ConfigContainer, error)
71 ParseData(data []byte) (ConfigContainer, error)
28 } 72 }
29 73
30 var adapters = make(map[string]Config) 74 var adapters = make(map[string]Config)
...@@ -36,7 +80,7 @@ func Register(name string, adapter Config) { ...@@ -36,7 +80,7 @@ func Register(name string, adapter Config) {
36 if adapter == nil { 80 if adapter == nil {
37 panic("config: Register adapter is nil") 81 panic("config: Register adapter is nil")
38 } 82 }
39 if _, dup := adapters[name]; dup { 83 if _, ok := adapters[name]; ok {
40 panic("config: Register called twice for adapter " + name) 84 panic("config: Register called twice for adapter " + name)
41 } 85 }
42 adapters[name] = adapter 86 adapters[name] = adapter
...@@ -51,3 +95,13 @@ func NewConfig(adapterName, fileaname string) (ConfigContainer, error) { ...@@ -51,3 +95,13 @@ func NewConfig(adapterName, fileaname string) (ConfigContainer, error) {
51 } 95 }
52 return adapter.Parse(fileaname) 96 return adapter.Parse(fileaname)
53 } 97 }
98
99 // adapterName is ini/json/xml/yaml.
100 // data is the config data.
101 func NewConfigData(adapterName string, data []byte) (ConfigContainer, error) {
102 adapter, ok := adapters[adapterName]
103 if !ok {
104 return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
105 }
106 return adapter.ParseData(data)
107 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package config
8 16
...@@ -17,13 +25,11 @@ type fakeConfigContainer struct { ...@@ -17,13 +25,11 @@ type fakeConfigContainer struct {
17 } 25 }
18 26
19 func (c *fakeConfigContainer) getData(key string) string { 27 func (c *fakeConfigContainer) getData(key string) string {
20 key = strings.ToLower(key) 28 return c.data[strings.ToLower(key)]
21 return c.data[key]
22 } 29 }
23 30
24 func (c *fakeConfigContainer) Set(key, val string) error { 31 func (c *fakeConfigContainer) Set(key, val string) error {
25 key = strings.ToLower(key) 32 c.data[strings.ToLower(key)] = val
26 c.data[key] = val
27 return nil 33 return nil
28 } 34 }
29 35
...@@ -31,34 +37,89 @@ func (c *fakeConfigContainer) String(key string) string { ...@@ -31,34 +37,89 @@ func (c *fakeConfigContainer) String(key string) string {
31 return c.getData(key) 37 return c.getData(key)
32 } 38 }
33 39
40 func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string {
41 if v := c.getData(key); v == "" {
42 return defaultval
43 } else {
44 return v
45 }
46 }
47
34 func (c *fakeConfigContainer) Strings(key string) []string { 48 func (c *fakeConfigContainer) Strings(key string) []string {
35 return strings.Split(c.getData(key), ";") 49 return strings.Split(c.getData(key), ";")
36 } 50 }
37 51
52 func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
53 if v := c.Strings(key); len(v) == 0 {
54 return defaultval
55 } else {
56 return v
57 }
58 }
59
38 func (c *fakeConfigContainer) Int(key string) (int, error) { 60 func (c *fakeConfigContainer) Int(key string) (int, error) {
39 return strconv.Atoi(c.getData(key)) 61 return strconv.Atoi(c.getData(key))
40 } 62 }
41 63
64 func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
65 if v, err := c.Int(key); err != nil {
66 return defaultval
67 } else {
68 return v
69 }
70 }
71
42 func (c *fakeConfigContainer) Int64(key string) (int64, error) { 72 func (c *fakeConfigContainer) Int64(key string) (int64, error) {
43 return strconv.ParseInt(c.getData(key), 10, 64) 73 return strconv.ParseInt(c.getData(key), 10, 64)
44 } 74 }
45 75
76 func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
77 if v, err := c.Int64(key); err != nil {
78 return defaultval
79 } else {
80 return v
81 }
82 }
83
46 func (c *fakeConfigContainer) Bool(key string) (bool, error) { 84 func (c *fakeConfigContainer) Bool(key string) (bool, error) {
47 return strconv.ParseBool(c.getData(key)) 85 return strconv.ParseBool(c.getData(key))
48 } 86 }
49 87
88 func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
89 if v, err := c.Bool(key); err != nil {
90 return defaultval
91 } else {
92 return v
93 }
94 }
95
50 func (c *fakeConfigContainer) Float(key string) (float64, error) { 96 func (c *fakeConfigContainer) Float(key string) (float64, error) {
51 return strconv.ParseFloat(c.getData(key), 64) 97 return strconv.ParseFloat(c.getData(key), 64)
52 } 98 }
53 99
100 func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
101 if v, err := c.Float(key); err != nil {
102 return defaultval
103 } else {
104 return v
105 }
106 }
107
54 func (c *fakeConfigContainer) DIY(key string) (interface{}, error) { 108 func (c *fakeConfigContainer) DIY(key string) (interface{}, error) {
55 key = strings.ToLower(key) 109 if v, ok := c.data[strings.ToLower(key)]; ok {
56 if v, ok := c.data[key]; ok {
57 return v, nil 110 return v, nil
58 } 111 }
59 return nil, errors.New("key not find") 112 return nil, errors.New("key not find")
60 } 113 }
61 114
115 func (c *fakeConfigContainer) GetSection(section string) (map[string]string, error) {
116 return nil, errors.New("not implement in the fakeConfigContainer")
117 }
118
119 func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
120 return errors.New("not implement in the fakeConfigContainer")
121 }
122
62 var _ ConfigContainer = new(fakeConfigContainer) 123 var _ ConfigContainer = new(fakeConfigContainer)
63 124
64 func NewFakeConfig() ConfigContainer { 125 func NewFakeConfig() ConfigContainer {
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package config
8 16
...@@ -10,11 +18,15 @@ import ( ...@@ -10,11 +18,15 @@ import (
10 "bufio" 18 "bufio"
11 "bytes" 19 "bytes"
12 "errors" 20 "errors"
21 "fmt"
13 "io" 22 "io"
23 "io/ioutil"
14 "os" 24 "os"
25 "path"
15 "strconv" 26 "strconv"
16 "strings" 27 "strings"
17 "sync" 28 "sync"
29 "time"
18 "unicode" 30 "unicode"
19 ) 31 )
20 32
...@@ -27,6 +39,7 @@ var ( ...@@ -27,6 +39,7 @@ var (
27 bDQuote = []byte{'"'} // quote signal 39 bDQuote = []byte{'"'} // quote signal
28 sectionStart = []byte{'['} // section start signal 40 sectionStart = []byte{'['} // section start signal
29 sectionEnd = []byte{']'} // section end signal 41 sectionEnd = []byte{']'} // section end signal
42 lineBreak = "\n"
30 ) 43 )
31 44
32 // IniConfig implements Config to parse ini file. 45 // IniConfig implements Config to parse ini file.
...@@ -80,8 +93,7 @@ func (ini *IniConfig) Parse(name string) (ConfigContainer, error) { ...@@ -80,8 +93,7 @@ func (ini *IniConfig) Parse(name string) (ConfigContainer, error) {
80 } 93 }
81 94
82 if bytes.HasPrefix(line, sectionStart) && bytes.HasSuffix(line, sectionEnd) { 95 if bytes.HasPrefix(line, sectionStart) && bytes.HasSuffix(line, sectionEnd) {
83 section = string(line[1 : len(line)-1]) 96 section = strings.ToLower(string(line[1 : len(line)-1])) // section name case insensitive
84 section = strings.ToLower(section) // section name case insensitive
85 if comment.Len() > 0 { 97 if comment.Len() > 0 {
86 cfg.sectionComment[section] = comment.String() 98 cfg.sectionComment[section] = comment.String()
87 comment.Reset() 99 comment.Reset()
...@@ -89,67 +101,124 @@ func (ini *IniConfig) Parse(name string) (ConfigContainer, error) { ...@@ -89,67 +101,124 @@ func (ini *IniConfig) Parse(name string) (ConfigContainer, error) {
89 if _, ok := cfg.data[section]; !ok { 101 if _, ok := cfg.data[section]; !ok {
90 cfg.data[section] = make(map[string]string) 102 cfg.data[section] = make(map[string]string)
91 } 103 }
92 } else { 104 continue
93 if _, ok := cfg.data[section]; !ok { 105 }
94 cfg.data[section] = make(map[string]string)
95 }
96 keyval := bytes.SplitN(line, bEqual, 2)
97 val := bytes.TrimSpace(keyval[1])
98 if bytes.HasPrefix(val, bDQuote) {
99 val = bytes.Trim(val, `"`)
100 }
101 106
102 key := string(bytes.TrimSpace(keyval[0])) // key name case insensitive 107 if _, ok := cfg.data[section]; !ok {
103 key = strings.ToLower(key) 108 cfg.data[section] = make(map[string]string)
104 cfg.data[section][key] = string(val) 109 }
105 if comment.Len() > 0 { 110 keyValue := bytes.SplitN(line, bEqual, 2)
106 cfg.keycomment[section+"."+key] = comment.String() 111 val := bytes.TrimSpace(keyValue[1])
107 comment.Reset() 112 if bytes.HasPrefix(val, bDQuote) {
108 } 113 val = bytes.Trim(val, `"`)
114 }
115
116 key := string(bytes.TrimSpace(keyValue[0])) // key name case insensitive
117 key = strings.ToLower(key)
118 cfg.data[section][key] = string(val)
119 if comment.Len() > 0 {
120 cfg.keyComment[section+"."+key] = comment.String()
121 comment.Reset()
109 } 122 }
110 123
111 } 124 }
112 return cfg, nil 125 return cfg, nil
113 } 126 }
114 127
128 func (ini *IniConfig) ParseData(data []byte) (ConfigContainer, error) {
129 // Save memory data to temporary file
130 tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
131 os.MkdirAll(path.Dir(tmpName), os.ModePerm)
132 if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
133 return nil, err
134 }
135 return ini.Parse(tmpName)
136 }
137
115 // A Config represents the ini configuration. 138 // A Config represents the ini configuration.
116 // When set and get value, support key as section:name type. 139 // When set and get value, support key as section:name type.
117 type IniConfigContainer struct { 140 type IniConfigContainer struct {
118 filename string 141 filename string
119 data map[string]map[string]string // section=> key:val 142 data map[string]map[string]string // section=> key:val
120 sectionComment map[string]string // section : comment 143 sectionComment map[string]string // section : comment
121 keycomment map[string]string // id: []{comment, key...}; id 1 is for main comment. 144 keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment.
122 sync.RWMutex 145 sync.RWMutex
123 } 146 }
124 147
125 // Bool returns the boolean value for a given key. 148 // Bool returns the boolean value for a given key.
126 func (c *IniConfigContainer) Bool(key string) (bool, error) { 149 func (c *IniConfigContainer) Bool(key string) (bool, error) {
127 key = strings.ToLower(key) 150 return strconv.ParseBool(c.getdata(strings.ToLower(key)))
128 return strconv.ParseBool(c.getdata(key)) 151 }
152
153 // DefaultBool returns the boolean value for a given key.
154 // if err != nil return defaltval
155 func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
156 if v, err := c.Bool(key); err != nil {
157 return defaultval
158 } else {
159 return v
160 }
129 } 161 }
130 162
131 // Int returns the integer value for a given key. 163 // Int returns the integer value for a given key.
132 func (c *IniConfigContainer) Int(key string) (int, error) { 164 func (c *IniConfigContainer) Int(key string) (int, error) {
133 key = strings.ToLower(key) 165 return strconv.Atoi(c.getdata(strings.ToLower(key)))
134 return strconv.Atoi(c.getdata(key)) 166 }
167
168 // DefaultInt returns the integer value for a given key.
169 // if err != nil return defaltval
170 func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
171 if v, err := c.Int(key); err != nil {
172 return defaultval
173 } else {
174 return v
175 }
135 } 176 }
136 177
137 // Int64 returns the int64 value for a given key. 178 // Int64 returns the int64 value for a given key.
138 func (c *IniConfigContainer) Int64(key string) (int64, error) { 179 func (c *IniConfigContainer) Int64(key string) (int64, error) {
139 key = strings.ToLower(key) 180 return strconv.ParseInt(c.getdata(strings.ToLower(key)), 10, 64)
140 return strconv.ParseInt(c.getdata(key), 10, 64) 181 }
182
183 // DefaultInt64 returns the int64 value for a given key.
184 // if err != nil return defaltval
185 func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
186 if v, err := c.Int64(key); err != nil {
187 return defaultval
188 } else {
189 return v
190 }
141 } 191 }
142 192
143 // Float returns the float value for a given key. 193 // Float returns the float value for a given key.
144 func (c *IniConfigContainer) Float(key string) (float64, error) { 194 func (c *IniConfigContainer) Float(key string) (float64, error) {
145 key = strings.ToLower(key) 195 return strconv.ParseFloat(c.getdata(strings.ToLower(key)), 64)
146 return strconv.ParseFloat(c.getdata(key), 64) 196 }
197
198 // DefaultFloat returns the float64 value for a given key.
199 // if err != nil return defaltval
200 func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
201 if v, err := c.Float(key); err != nil {
202 return defaultval
203 } else {
204 return v
205 }
147 } 206 }
148 207
149 // String returns the string value for a given key. 208 // String returns the string value for a given key.
150 func (c *IniConfigContainer) String(key string) string { 209 func (c *IniConfigContainer) String(key string) string {
151 key = strings.ToLower(key) 210 key = strings.ToLower(key)
152 return c.getdata(key) 211 return c.getdata(strings.ToLower(key))
212 }
213
214 // DefaultString returns the string value for a given key.
215 // if err != nil return defaltval
216 func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
217 if v := c.String(key); v == "" {
218 return defaultval
219 } else {
220 return v
221 }
153 } 222 }
154 223
155 // Strings returns the []string value for a given key. 224 // Strings returns the []string value for a given key.
...@@ -157,6 +226,78 @@ func (c *IniConfigContainer) Strings(key string) []string { ...@@ -157,6 +226,78 @@ func (c *IniConfigContainer) Strings(key string) []string {
157 return strings.Split(c.String(key), ";") 226 return strings.Split(c.String(key), ";")
158 } 227 }
159 228
229 // DefaultStrings returns the []string value for a given key.
230 // if err != nil return defaltval
231 func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
232 if v := c.Strings(key); len(v) == 0 {
233 return defaultval
234 } else {
235 return v
236 }
237 }
238
239 // GetSection returns map for the given section
240 func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) {
241 if v, ok := c.data[section]; ok {
242 return v, nil
243 } else {
244 return nil, errors.New("not exist setction")
245 }
246 }
247
248 // SaveConfigFile save the config into file
249 func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
250 // Write configuration file by filename.
251 f, err := os.Create(filename)
252 if err != nil {
253 return err
254 }
255 defer f.Close()
256
257 buf := bytes.NewBuffer(nil)
258 for section, dt := range c.data {
259 // Write section comments.
260 if v, ok := c.sectionComment[section]; ok {
261 if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil {
262 return err
263 }
264 }
265
266 if section != DEFAULT_SECTION {
267 // Write section name.
268 if _, err = buf.WriteString(string(sectionStart) + section + string(sectionEnd) + lineBreak); err != nil {
269 return err
270 }
271 }
272
273 for key, val := range dt {
274 if key != " " {
275 // Write key comments.
276 if v, ok := c.keyComment[key]; ok {
277 if _, err = buf.WriteString(string(bNumComment) + v + lineBreak); err != nil {
278 return err
279 }
280 }
281
282 // Write key and value.
283 if _, err = buf.WriteString(key + string(bEqual) + val + lineBreak); err != nil {
284 return err
285 }
286 }
287 }
288
289 // Put a line between sections.
290 if _, err = buf.WriteString(lineBreak); err != nil {
291 return err
292 }
293 }
294
295 if _, err = buf.WriteTo(f); err != nil {
296 return err
297 }
298 return nil
299 }
300
160 // WriteValue writes a new value for key. 301 // WriteValue writes a new value for key.
161 // if write to one section, the key need be "section::key". 302 // if write to one section, the key need be "section::key".
162 // if the section is not existed, it panics. 303 // if the section is not existed, it panics.
...@@ -167,16 +308,19 @@ func (c *IniConfigContainer) Set(key, value string) error { ...@@ -167,16 +308,19 @@ func (c *IniConfigContainer) Set(key, value string) error {
167 return errors.New("key is empty") 308 return errors.New("key is empty")
168 } 309 }
169 310
170 var section, k string 311 var (
171 key = strings.ToLower(key) 312 section, k string
172 sectionkey := strings.Split(key, "::") 313 sectionKey []string = strings.Split(key, "::")
173 if len(sectionkey) >= 2 { 314 )
174 section = sectionkey[0] 315
175 k = sectionkey[1] 316 if len(sectionKey) >= 2 {
317 section = sectionKey[0]
318 k = sectionKey[1]
176 } else { 319 } else {
177 section = DEFAULT_SECTION 320 section = DEFAULT_SECTION
178 k = sectionkey[0] 321 k = sectionKey[0]
179 } 322 }
323
180 if _, ok := c.data[section]; !ok { 324 if _, ok := c.data[section]; !ok {
181 c.data[section] = make(map[string]string) 325 c.data[section] = make(map[string]string)
182 } 326 }
...@@ -186,8 +330,7 @@ func (c *IniConfigContainer) Set(key, value string) error { ...@@ -186,8 +330,7 @@ func (c *IniConfigContainer) Set(key, value string) error {
186 330
187 // DIY returns the raw value by a given key. 331 // DIY returns the raw value by a given key.
188 func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) { 332 func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
189 key = strings.ToLower(key) 333 if v, ok := c.data[strings.ToLower(key)]; ok {
190 if v, ok := c.data[key]; ok {
191 return v, nil 334 return v, nil
192 } 335 }
193 return v, errors.New("key not find") 336 return v, errors.New("key not find")
...@@ -201,18 +344,19 @@ func (c *IniConfigContainer) getdata(key string) string { ...@@ -201,18 +344,19 @@ func (c *IniConfigContainer) getdata(key string) string {
201 return "" 344 return ""
202 } 345 }
203 346
204 var section, k string 347 var (
205 key = strings.ToLower(key) 348 section, k string
206 sectionkey := strings.Split(key, "::") 349 sectionKey []string = strings.Split(key, "::")
207 if len(sectionkey) >= 2 { 350 )
208 section = sectionkey[0] 351 if len(sectionKey) >= 2 {
209 k = sectionkey[1] 352 section = sectionKey[0]
353 k = sectionKey[1]
210 } else { 354 } else {
211 section = DEFAULT_SECTION 355 section = DEFAULT_SECTION
212 k = sectionkey[0] 356 k = sectionKey[0]
213 } 357 }
214 if v, ok := c.data[section]; ok { 358 if v, ok := c.data[section]; ok {
215 if vv, o := v[k]; o { 359 if vv, ok := v[k]; ok {
216 return vv 360 return vv
217 } 361 }
218 } 362 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package config
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package config
8 16
9 import ( 17 import (
10 "encoding/json" 18 "encoding/json"
11 "errors" 19 "errors"
20 "fmt"
12 "io/ioutil" 21 "io/ioutil"
13 "os" 22 "os"
23 "path"
14 "strings" 24 "strings"
15 "sync" 25 "sync"
26 "time"
16 ) 27 )
17 28
18 // JsonConfig is a json config parser and implements Config interface. 29 // JsonConfig is a json config parser and implements Config interface.
...@@ -26,13 +37,13 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) { ...@@ -26,13 +37,13 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
26 return nil, err 37 return nil, err
27 } 38 }
28 defer file.Close() 39 defer file.Close()
29 x := &JsonConfigContainer{
30 data: make(map[string]interface{}),
31 }
32 content, err := ioutil.ReadAll(file) 40 content, err := ioutil.ReadAll(file)
33 if err != nil { 41 if err != nil {
34 return nil, err 42 return nil, err
35 } 43 }
44 x := &JsonConfigContainer{
45 data: make(map[string]interface{}),
46 }
36 err = json.Unmarshal(content, &x.data) 47 err = json.Unmarshal(content, &x.data)
37 if err != nil { 48 if err != nil {
38 var wrappingArray []interface{} 49 var wrappingArray []interface{}
...@@ -45,6 +56,16 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) { ...@@ -45,6 +56,16 @@ func (js *JsonConfig) Parse(filename string) (ConfigContainer, error) {
45 return x, nil 56 return x, nil
46 } 57 }
47 58
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
48 // A Config represents the json configuration. 69 // A Config represents the json configuration.
49 // Only when get value, support key as section:name type. 70 // Only when get value, support key as section:name type.
50 type JsonConfigContainer struct { 71 type JsonConfigContainer struct {
...@@ -54,71 +75,110 @@ type JsonConfigContainer struct { ...@@ -54,71 +75,110 @@ type JsonConfigContainer struct {
54 75
55 // Bool returns the boolean value for a given key. 76 // Bool returns the boolean value for a given key.
56 func (c *JsonConfigContainer) Bool(key string) (bool, error) { 77 func (c *JsonConfigContainer) Bool(key string) (bool, error) {
57 val := c.getdata(key) 78 val := c.getData(key)
58 if val != nil { 79 if val != nil {
59 if v, ok := val.(bool); ok { 80 if v, ok := val.(bool); ok {
60 return v, nil 81 return v, nil
61 } else {
62 return false, errors.New("not bool value")
63 } 82 }
83 return false, errors.New("not bool value")
84 }
85 return false, errors.New("not exist key:" + key)
86 }
87
88 // DefaultBool return the bool value if has no error
89 // otherwise return the defaultval
90 func (c *JsonConfigContainer) DefaultBool(key string, defaultval bool) bool {
91 if v, err := c.Bool(key); err != nil {
92 return defaultval
64 } else { 93 } else {
65 return false, errors.New("not exist key:" + key) 94 return v
66 } 95 }
67 } 96 }
68 97
69 // Int returns the integer value for a given key. 98 // Int returns the integer value for a given key.
70 func (c *JsonConfigContainer) Int(key string) (int, error) { 99 func (c *JsonConfigContainer) Int(key string) (int, error) {
71 val := c.getdata(key) 100 val := c.getData(key)
72 if val != nil { 101 if val != nil {
73 if v, ok := val.(float64); ok { 102 if v, ok := val.(float64); ok {
74 return int(v), nil 103 return int(v), nil
75 } else {
76 return 0, errors.New("not int value")
77 } 104 }
105 return 0, errors.New("not int value")
106 }
107 return 0, errors.New("not exist key:" + key)
108 }
109
110 // DefaultInt returns the integer value for a given key.
111 // if err != nil return defaltval
112 func (c *JsonConfigContainer) DefaultInt(key string, defaultval int) int {
113 if v, err := c.Int(key); err != nil {
114 return defaultval
78 } else { 115 } else {
79 return 0, errors.New("not exist key:" + key) 116 return v
80 } 117 }
81 } 118 }
82 119
83 // Int64 returns the int64 value for a given key. 120 // Int64 returns the int64 value for a given key.
84 func (c *JsonConfigContainer) Int64(key string) (int64, error) { 121 func (c *JsonConfigContainer) Int64(key string) (int64, error) {
85 val := c.getdata(key) 122 val := c.getData(key)
86 if val != nil { 123 if val != nil {
87 if v, ok := val.(float64); ok { 124 if v, ok := val.(float64); ok {
88 return int64(v), nil 125 return int64(v), nil
89 } else {
90 return 0, errors.New("not int64 value")
91 } 126 }
127 return 0, errors.New("not int64 value")
128 }
129 return 0, errors.New("not exist key:" + key)
130 }
131
132 // DefaultInt64 returns the int64 value for a given key.
133 // if err != nil return defaltval
134 func (c *JsonConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
135 if v, err := c.Int64(key); err != nil {
136 return defaultval
92 } else { 137 } else {
93 return 0, errors.New("not exist key:" + key) 138 return v
94 } 139 }
95 } 140 }
96 141
97 // Float returns the float value for a given key. 142 // Float returns the float value for a given key.
98 func (c *JsonConfigContainer) Float(key string) (float64, error) { 143 func (c *JsonConfigContainer) Float(key string) (float64, error) {
99 val := c.getdata(key) 144 val := c.getData(key)
100 if val != nil { 145 if val != nil {
101 if v, ok := val.(float64); ok { 146 if v, ok := val.(float64); ok {
102 return v, nil 147 return v, nil
103 } else {
104 return 0.0, errors.New("not float64 value")
105 } 148 }
149 return 0.0, errors.New("not float64 value")
150 }
151 return 0.0, errors.New("not exist key:" + key)
152 }
153
154 // DefaultFloat returns the float64 value for a given key.
155 // if err != nil return defaltval
156 func (c *JsonConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
157 if v, err := c.Float(key); err != nil {
158 return defaultval
106 } else { 159 } else {
107 return 0.0, errors.New("not exist key:" + key) 160 return v
108 } 161 }
109 } 162 }
110 163
111 // String returns the string value for a given key. 164 // String returns the string value for a given key.
112 func (c *JsonConfigContainer) String(key string) string { 165 func (c *JsonConfigContainer) String(key string) string {
113 val := c.getdata(key) 166 val := c.getData(key)
114 if val != nil { 167 if val != nil {
115 if v, ok := val.(string); ok { 168 if v, ok := val.(string); ok {
116 return v 169 return v
117 } else {
118 return ""
119 } 170 }
171 }
172 return ""
173 }
174
175 // DefaultString returns the string value for a given key.
176 // if err != nil return defaltval
177 func (c *JsonConfigContainer) DefaultString(key string, defaultval string) string {
178 if v := c.String(key); v == "" {
179 return defaultval
120 } else { 180 } else {
121 return "" 181 return v
122 } 182 }
123 } 183 }
124 184
...@@ -127,6 +187,41 @@ func (c *JsonConfigContainer) Strings(key string) []string { ...@@ -127,6 +187,41 @@ func (c *JsonConfigContainer) Strings(key string) []string {
127 return strings.Split(c.String(key), ";") 187 return strings.Split(c.String(key), ";")
128 } 188 }
129 189
190 // DefaultStrings returns the []string value for a given key.
191 // if err != nil return defaltval
192 func (c *JsonConfigContainer) DefaultStrings(key string, defaultval []string) []string {
193 if v := c.Strings(key); len(v) == 0 {
194 return defaultval
195 } else {
196 return v
197 }
198 }
199
200 // GetSection returns map for the given section
201 func (c *JsonConfigContainer) GetSection(section string) (map[string]string, error) {
202 if v, ok := c.data[section]; ok {
203 return v.(map[string]string), nil
204 } else {
205 return nil, errors.New("not exist setction")
206 }
207 }
208
209 // SaveConfigFile save the config into file
210 func (c *JsonConfigContainer) SaveConfigFile(filename string) (err error) {
211 // Write configuration file by filename.
212 f, err := os.Create(filename)
213 if err != nil {
214 return err
215 }
216 defer f.Close()
217 b, err := json.MarshalIndent(c.data, "", " ")
218 if err != nil {
219 return err
220 }
221 _, err = f.Write(b)
222 return err
223 }
224
130 // WriteValue writes a new value for key. 225 // WriteValue writes a new value for key.
131 func (c *JsonConfigContainer) Set(key, val string) error { 226 func (c *JsonConfigContainer) Set(key, val string) error {
132 c.Lock() 227 c.Lock()
...@@ -137,39 +232,37 @@ func (c *JsonConfigContainer) Set(key, val string) error { ...@@ -137,39 +232,37 @@ func (c *JsonConfigContainer) Set(key, val string) error {
137 232
138 // DIY returns the raw value by a given key. 233 // DIY returns the raw value by a given key.
139 func (c *JsonConfigContainer) DIY(key string) (v interface{}, err error) { 234 func (c *JsonConfigContainer) DIY(key string) (v interface{}, err error) {
140 val := c.getdata(key) 235 val := c.getData(key)
141 if val != nil { 236 if val != nil {
142 return val, nil 237 return val, nil
143 } else {
144 return nil, errors.New("not exist key")
145 } 238 }
239 return nil, errors.New("not exist key")
146 } 240 }
147 241
148 // section.key or key 242 // section.key or key
149 func (c *JsonConfigContainer) getdata(key string) interface{} { 243 func (c *JsonConfigContainer) getData(key string) interface{} {
150 c.RLock() 244 c.RLock()
151 defer c.RUnlock() 245 defer c.RUnlock()
152 if len(key) == 0 { 246 if len(key) == 0 {
153 return nil 247 return nil
154 } 248 }
155 sectionkey := strings.Split(key, "::") 249 sectionKey := strings.Split(key, "::")
156 if len(sectionkey) >= 2 { 250 if len(sectionKey) >= 2 {
157 cruval, ok := c.data[sectionkey[0]] 251 curValue, ok := c.data[sectionKey[0]]
158 if !ok { 252 if !ok {
159 return nil 253 return nil
160 } 254 }
161 for _, key := range sectionkey[1:] { 255 for _, key := range sectionKey[1:] {
162 if v, ok := cruval.(map[string]interface{}); !ok { 256 if v, ok := curValue.(map[string]interface{}); ok {
163 return nil 257 if curValue, ok = v[key]; !ok {
164 } else if cruval, ok = v[key]; !ok { 258 return nil
165 return nil 259 }
166 } 260 }
167 } 261 }
168 return cruval 262 return curValue
169 } else { 263 }
170 if v, ok := c.data[key]; ok { 264 if v, ok := c.data[key]; ok {
171 return v 265 return v
172 }
173 } 266 }
174 return nil 267 return nil
175 } 268 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package config
8 16
...@@ -61,13 +69,13 @@ func TestJsonStartsWithArray(t *testing.T) { ...@@ -61,13 +69,13 @@ func TestJsonStartsWithArray(t *testing.T) {
61 t.Fatal(err) 69 t.Fatal(err)
62 } 70 }
63 rootArray, err := jsonconf.DIY("rootArray") 71 rootArray, err := jsonconf.DIY("rootArray")
64 if (err != nil) { 72 if err != nil {
65 t.Error("array does not exist as element") 73 t.Error("array does not exist as element")
66 } 74 }
67 rootArrayCasted := rootArray.([]interface{}) 75 rootArrayCasted := rootArray.([]interface{})
68 if (rootArrayCasted == nil) { 76 if rootArrayCasted == nil {
69 t.Error("array from root is nil") 77 t.Error("array from root is nil")
70 }else { 78 } else {
71 elem := rootArrayCasted[0].(map[string]interface{}) 79 elem := rootArrayCasted[0].(map[string]interface{})
72 if elem["url"] != "user" || elem["serviceAPI"] != "http://www.test.com/user" { 80 if elem["url"] != "user" || elem["serviceAPI"] != "http://www.test.com/user" {
73 t.Error("array[0] values are not valid") 81 t.Error("array[0] values are not valid")
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 // package xml for config provider
16 //
17 // depend on github.com/beego/x2j
18 //
19 // go install github.com/beego/x2j
20 //
21 // Usage:
22 // import(
23 // _ "github.com/astaxie/beego/config/xml"
24 // "github.com/astaxie/beego/config"
25 // )
26 //
27 // cnf, err := config.NewConfig("xml", "config.xml")
28 //
29 // more docs http://beego.me/docs/module/config.md
30 package xml
8 31
9 import ( 32 import (
33 "encoding/xml"
10 "errors" 34 "errors"
35 "fmt"
11 "io/ioutil" 36 "io/ioutil"
12 "os" 37 "os"
38 "path"
13 "strconv" 39 "strconv"
14 "strings" 40 "strings"
15 "sync" 41 "sync"
42 "time"
16 43
17 "github.com/astaxie/beego/config" 44 "github.com/astaxie/beego/config"
18 "github.com/beego/x2j" 45 "github.com/beego/x2j"
...@@ -21,31 +48,41 @@ import ( ...@@ -21,31 +48,41 @@ import (
21 // XmlConfig is a xml config parser and implements Config interface. 48 // XmlConfig is a xml config parser and implements Config interface.
22 // xml configurations should be included in <config></config> tag. 49 // xml configurations should be included in <config></config> tag.
23 // only support key/value pair as <key>value</key> as each item. 50 // only support key/value pair as <key>value</key> as each item.
24 type XMLConfig struct { 51 type XMLConfig struct{}
25 }
26 52
27 // Parse returns a ConfigContainer with parsed xml config map. 53 // Parse returns a ConfigContainer with parsed xml config map.
28 func (xmls *XMLConfig) Parse(filename string) (config.ConfigContainer, error) { 54 func (xc *XMLConfig) Parse(filename string) (config.ConfigContainer, error) {
29 file, err := os.Open(filename) 55 file, err := os.Open(filename)
30 if err != nil { 56 if err != nil {
31 return nil, err 57 return nil, err
32 } 58 }
33 defer file.Close() 59 defer file.Close()
34 x := &XMLConfigContainer{ 60
35 data: make(map[string]interface{}), 61 x := &XMLConfigContainer{data: make(map[string]interface{})}
36 }
37 content, err := ioutil.ReadAll(file) 62 content, err := ioutil.ReadAll(file)
38 if err != nil { 63 if err != nil {
39 return nil, err 64 return nil, err
40 } 65 }
66
41 d, err := x2j.DocToMap(string(content)) 67 d, err := x2j.DocToMap(string(content))
42 if err != nil { 68 if err != nil {
43 return nil, err 69 return nil, err
44 } 70 }
71
45 x.data = d["config"].(map[string]interface{}) 72 x.data = d["config"].(map[string]interface{})
46 return x, nil 73 return x, nil
47 } 74 }
48 75
76 func (x *XMLConfig) ParseData(data []byte) (config.ConfigContainer, error) {
77 // Save memory data to temporary file
78 tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
79 os.MkdirAll(path.Dir(tmpName), os.ModePerm)
80 if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
81 return nil, err
82 }
83 return x.Parse(tmpName)
84 }
85
49 // A Config represents the xml configuration. 86 // A Config represents the xml configuration.
50 type XMLConfigContainer struct { 87 type XMLConfigContainer struct {
51 data map[string]interface{} 88 data map[string]interface{}
...@@ -57,21 +94,61 @@ func (c *XMLConfigContainer) Bool(key string) (bool, error) { ...@@ -57,21 +94,61 @@ func (c *XMLConfigContainer) Bool(key string) (bool, error) {
57 return strconv.ParseBool(c.data[key].(string)) 94 return strconv.ParseBool(c.data[key].(string))
58 } 95 }
59 96
97 // DefaultBool return the bool value if has no error
98 // otherwise return the defaultval
99 func (c *XMLConfigContainer) DefaultBool(key string, defaultval bool) bool {
100 if v, err := c.Bool(key); err != nil {
101 return defaultval
102 } else {
103 return v
104 }
105 }
106
60 // Int returns the integer value for a given key. 107 // Int returns the integer value for a given key.
61 func (c *XMLConfigContainer) Int(key string) (int, error) { 108 func (c *XMLConfigContainer) Int(key string) (int, error) {
62 return strconv.Atoi(c.data[key].(string)) 109 return strconv.Atoi(c.data[key].(string))
63 } 110 }
64 111
112 // DefaultInt returns the integer value for a given key.
113 // if err != nil return defaltval
114 func (c *XMLConfigContainer) DefaultInt(key string, defaultval int) int {
115 if v, err := c.Int(key); err != nil {
116 return defaultval
117 } else {
118 return v
119 }
120 }
121
65 // Int64 returns the int64 value for a given key. 122 // Int64 returns the int64 value for a given key.
66 func (c *XMLConfigContainer) Int64(key string) (int64, error) { 123 func (c *XMLConfigContainer) Int64(key string) (int64, error) {
67 return strconv.ParseInt(c.data[key].(string), 10, 64) 124 return strconv.ParseInt(c.data[key].(string), 10, 64)
68 } 125 }
69 126
127 // DefaultInt64 returns the int64 value for a given key.
128 // if err != nil return defaltval
129 func (c *XMLConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
130 if v, err := c.Int64(key); err != nil {
131 return defaultval
132 } else {
133 return v
134 }
135 }
136
70 // Float returns the float value for a given key. 137 // Float returns the float value for a given key.
71 func (c *XMLConfigContainer) Float(key string) (float64, error) { 138 func (c *XMLConfigContainer) Float(key string) (float64, error) {
72 return strconv.ParseFloat(c.data[key].(string), 64) 139 return strconv.ParseFloat(c.data[key].(string), 64)
73 } 140 }
74 141
142 // DefaultFloat returns the float64 value for a given key.
143 // if err != nil return defaltval
144 func (c *XMLConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
145 if v, err := c.Float(key); err != nil {
146 return defaultval
147 } else {
148 return v
149 }
150 }
151
75 // String returns the string value for a given key. 152 // String returns the string value for a given key.
76 func (c *XMLConfigContainer) String(key string) string { 153 func (c *XMLConfigContainer) String(key string) string {
77 if v, ok := c.data[key].(string); ok { 154 if v, ok := c.data[key].(string); ok {
...@@ -80,11 +157,56 @@ func (c *XMLConfigContainer) String(key string) string { ...@@ -80,11 +157,56 @@ func (c *XMLConfigContainer) String(key string) string {
80 return "" 157 return ""
81 } 158 }
82 159
160 // DefaultString returns the string value for a given key.
161 // if err != nil return defaltval
162 func (c *XMLConfigContainer) DefaultString(key string, defaultval string) string {
163 if v := c.String(key); v == "" {
164 return defaultval
165 } else {
166 return v
167 }
168 }
169
83 // Strings returns the []string value for a given key. 170 // Strings returns the []string value for a given key.
84 func (c *XMLConfigContainer) Strings(key string) []string { 171 func (c *XMLConfigContainer) Strings(key string) []string {
85 return strings.Split(c.String(key), ";") 172 return strings.Split(c.String(key), ";")
86 } 173 }
87 174
175 // DefaultStrings returns the []string value for a given key.
176 // if err != nil return defaltval
177 func (c *XMLConfigContainer) DefaultStrings(key string, defaultval []string) []string {
178 if v := c.Strings(key); len(v) == 0 {
179 return defaultval
180 } else {
181 return v
182 }
183 }
184
185 // GetSection returns map for the given section
186 func (c *XMLConfigContainer) GetSection(section string) (map[string]string, error) {
187 if v, ok := c.data[section]; ok {
188 return v.(map[string]string), nil
189 } else {
190 return nil, errors.New("not exist setction")
191 }
192 }
193
194 // SaveConfigFile save the config into file
195 func (c *XMLConfigContainer) SaveConfigFile(filename string) (err error) {
196 // Write configuration file by filename.
197 f, err := os.Create(filename)
198 if err != nil {
199 return err
200 }
201 defer f.Close()
202 b, err := xml.MarshalIndent(c.data, " ", " ")
203 if err != nil {
204 return err
205 }
206 _, err = f.Write(b)
207 return err
208 }
209
88 // WriteValue writes a new value for key. 210 // WriteValue writes a new value for key.
89 func (c *XMLConfigContainer) Set(key, val string) error { 211 func (c *XMLConfigContainer) Set(key, val string) error {
90 c.Lock() 212 c.Lock()
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package xml
8 16
9 import ( 17 import (
10 "os" 18 "os"
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 // package yaml for config provider
16 //
17 // depend on github.com/beego/goyaml2
18 //
19 // go install github.com/beego/goyaml2
20 //
21 // Usage:
22 // import(
23 // _ "github.com/astaxie/beego/config/yaml"
24 // "github.com/astaxie/beego/config"
25 // )
26 //
27 // cnf, err := config.NewConfig("yaml", "config.yaml")
28 //
29 // more docs http://beego.me/docs/module/config.md
30 package yaml
8 31
9 import ( 32 import (
10 "bytes" 33 "bytes"
11 "encoding/json" 34 "encoding/json"
12 "errors" 35 "errors"
36 "fmt"
13 "io/ioutil" 37 "io/ioutil"
14 "log" 38 "log"
15 "os" 39 "os"
40 "path"
16 "strings" 41 "strings"
17 "sync" 42 "sync"
43 "time"
18 44
19 "github.com/astaxie/beego/config" 45 "github.com/astaxie/beego/config"
20 "github.com/beego/goyaml2" 46 "github.com/beego/goyaml2"
21 ) 47 )
22 48
23 // YAMLConfig is a yaml config parser and implements Config interface. 49 // YAMLConfig is a yaml config parser and implements Config interface.
24 type YAMLConfig struct { 50 type YAMLConfig struct{}
25 }
26 51
27 // Parse returns a ConfigContainer with parsed yaml config map. 52 // Parse returns a ConfigContainer with parsed yaml config map.
28 func (yaml *YAMLConfig) Parse(filename string) (config.ConfigContainer, error) { 53 func (yaml *YAMLConfig) Parse(filename string) (y config.ConfigContainer, err error) {
29 y := &YAMLConfigContainer{
30 data: make(map[string]interface{}),
31 }
32 cnf, err := ReadYmlReader(filename) 54 cnf, err := ReadYmlReader(filename)
33 if err != nil { 55 if err != nil {
56 return
57 }
58 y = &YAMLConfigContainer{
59 data: cnf,
60 }
61 return
62 }
63
64 func (yaml *YAMLConfig) ParseData(data []byte) (config.ConfigContainer, error) {
65 // Save memory data to temporary file
66 tmpName := path.Join(os.TempDir(), "beego", fmt.Sprintf("%d", time.Now().Nanosecond()))
67 os.MkdirAll(path.Dir(tmpName), os.ModePerm)
68 if err := ioutil.WriteFile(tmpName, data, 0655); err != nil {
34 return nil, err 69 return nil, err
35 } 70 }
36 y.data = cnf 71 return yaml.Parse(tmpName)
37 return y, nil
38 } 72 }
39 73
40 // Read yaml file to map. 74 // Read yaml file to map.
41 // if json like, use json package, unless goyaml2 package. 75 // if json like, use json package, unless goyaml2 package.
42 func ReadYmlReader(path string) (cnf map[string]interface{}, err error) { 76 func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
43 err = nil
44 f, err := os.Open(path) 77 f, err := os.Open(path)
45 if err != nil { 78 if err != nil {
46 return 79 return
47 } 80 }
48 defer f.Close() 81 defer f.Close()
49 err = nil 82
50 buf, err := ioutil.ReadAll(f) 83 buf, err := ioutil.ReadAll(f)
51 if err != nil || len(buf) < 3 { 84 if err != nil || len(buf) < 3 {
52 return 85 return
53 } 86 }
54 87
55 if string(buf[0:1]) == "{" { 88 if string(buf[0:1]) == "{" {
56 log.Println("Look lile a Json, try it") 89 log.Println("Look like a Json, try json umarshal")
57 err = json.Unmarshal(buf, &cnf) 90 err = json.Unmarshal(buf, &cnf)
58 if err == nil { 91 if err == nil {
59 log.Println("It is Json Map") 92 log.Println("It is Json Map")
...@@ -61,19 +94,19 @@ func ReadYmlReader(path string) (cnf map[string]interface{}, err error) { ...@@ -61,19 +94,19 @@ func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
61 } 94 }
62 } 95 }
63 96
64 _map, _err := goyaml2.Read(bytes.NewBuffer(buf)) 97 data, err := goyaml2.Read(bytes.NewBuffer(buf))
65 if _err != nil { 98 if err != nil {
66 log.Println("Goyaml2 ERR>", string(buf), _err) 99 log.Println("Goyaml2 ERR>", string(buf), err)
67 //err = goyaml.Unmarshal(buf, &cnf)
68 err = _err
69 return 100 return
70 } 101 }
71 if _map == nil { 102
103 if data == nil {
72 log.Println("Goyaml2 output nil? Pls report bug\n" + string(buf)) 104 log.Println("Goyaml2 output nil? Pls report bug\n" + string(buf))
105 return
73 } 106 }
74 cnf, ok := _map.(map[string]interface{}) 107 cnf, ok := data.(map[string]interface{})
75 if !ok { 108 if !ok {
76 log.Println("Not a Map? >> ", string(buf), _map) 109 log.Println("Not a Map? >> ", string(buf), data)
77 cnf = nil 110 cnf = nil
78 } 111 }
79 return 112 return
...@@ -93,6 +126,16 @@ func (c *YAMLConfigContainer) Bool(key string) (bool, error) { ...@@ -93,6 +126,16 @@ func (c *YAMLConfigContainer) Bool(key string) (bool, error) {
93 return false, errors.New("not bool value") 126 return false, errors.New("not bool value")
94 } 127 }
95 128
129 // DefaultBool return the bool value if has no error
130 // otherwise return the defaultval
131 func (c *YAMLConfigContainer) DefaultBool(key string, defaultval bool) bool {
132 if v, err := c.Bool(key); err != nil {
133 return defaultval
134 } else {
135 return v
136 }
137 }
138
96 // Int returns the integer value for a given key. 139 // Int returns the integer value for a given key.
97 func (c *YAMLConfigContainer) Int(key string) (int, error) { 140 func (c *YAMLConfigContainer) Int(key string) (int, error) {
98 if v, ok := c.data[key].(int64); ok { 141 if v, ok := c.data[key].(int64); ok {
...@@ -101,6 +144,16 @@ func (c *YAMLConfigContainer) Int(key string) (int, error) { ...@@ -101,6 +144,16 @@ func (c *YAMLConfigContainer) Int(key string) (int, error) {
101 return 0, errors.New("not int value") 144 return 0, errors.New("not int value")
102 } 145 }
103 146
147 // DefaultInt returns the integer value for a given key.
148 // if err != nil return defaltval
149 func (c *YAMLConfigContainer) DefaultInt(key string, defaultval int) int {
150 if v, err := c.Int(key); err != nil {
151 return defaultval
152 } else {
153 return v
154 }
155 }
156
104 // Int64 returns the int64 value for a given key. 157 // Int64 returns the int64 value for a given key.
105 func (c *YAMLConfigContainer) Int64(key string) (int64, error) { 158 func (c *YAMLConfigContainer) Int64(key string) (int64, error) {
106 if v, ok := c.data[key].(int64); ok { 159 if v, ok := c.data[key].(int64); ok {
...@@ -109,6 +162,16 @@ func (c *YAMLConfigContainer) Int64(key string) (int64, error) { ...@@ -109,6 +162,16 @@ func (c *YAMLConfigContainer) Int64(key string) (int64, error) {
109 return 0, errors.New("not bool value") 162 return 0, errors.New("not bool value")
110 } 163 }
111 164
165 // DefaultInt64 returns the int64 value for a given key.
166 // if err != nil return defaltval
167 func (c *YAMLConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
168 if v, err := c.Int64(key); err != nil {
169 return defaultval
170 } else {
171 return v
172 }
173 }
174
112 // Float returns the float value for a given key. 175 // Float returns the float value for a given key.
113 func (c *YAMLConfigContainer) Float(key string) (float64, error) { 176 func (c *YAMLConfigContainer) Float(key string) (float64, error) {
114 if v, ok := c.data[key].(float64); ok { 177 if v, ok := c.data[key].(float64); ok {
...@@ -117,6 +180,16 @@ func (c *YAMLConfigContainer) Float(key string) (float64, error) { ...@@ -117,6 +180,16 @@ func (c *YAMLConfigContainer) Float(key string) (float64, error) {
117 return 0.0, errors.New("not float64 value") 180 return 0.0, errors.New("not float64 value")
118 } 181 }
119 182
183 // DefaultFloat returns the float64 value for a given key.
184 // if err != nil return defaltval
185 func (c *YAMLConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
186 if v, err := c.Float(key); err != nil {
187 return defaultval
188 } else {
189 return v
190 }
191 }
192
120 // String returns the string value for a given key. 193 // String returns the string value for a given key.
121 func (c *YAMLConfigContainer) String(key string) string { 194 func (c *YAMLConfigContainer) String(key string) string {
122 if v, ok := c.data[key].(string); ok { 195 if v, ok := c.data[key].(string); ok {
...@@ -125,11 +198,52 @@ func (c *YAMLConfigContainer) String(key string) string { ...@@ -125,11 +198,52 @@ func (c *YAMLConfigContainer) String(key string) string {
125 return "" 198 return ""
126 } 199 }
127 200
201 // DefaultString returns the string value for a given key.
202 // if err != nil return defaltval
203 func (c *YAMLConfigContainer) DefaultString(key string, defaultval string) string {
204 if v := c.String(key); v == "" {
205 return defaultval
206 } else {
207 return v
208 }
209 }
210
128 // Strings returns the []string value for a given key. 211 // Strings returns the []string value for a given key.
129 func (c *YAMLConfigContainer) Strings(key string) []string { 212 func (c *YAMLConfigContainer) Strings(key string) []string {
130 return strings.Split(c.String(key), ";") 213 return strings.Split(c.String(key), ";")
131 } 214 }
132 215
216 // DefaultStrings returns the []string value for a given key.
217 // if err != nil return defaltval
218 func (c *YAMLConfigContainer) DefaultStrings(key string, defaultval []string) []string {
219 if v := c.Strings(key); len(v) == 0 {
220 return defaultval
221 } else {
222 return v
223 }
224 }
225
226 // GetSection returns map for the given section
227 func (c *YAMLConfigContainer) GetSection(section string) (map[string]string, error) {
228 if v, ok := c.data[section]; ok {
229 return v.(map[string]string), nil
230 } else {
231 return nil, errors.New("not exist setction")
232 }
233 }
234
235 // SaveConfigFile save the config into file
236 func (c *YAMLConfigContainer) SaveConfigFile(filename string) (err error) {
237 // Write configuration file by filename.
238 f, err := os.Create(filename)
239 if err != nil {
240 return err
241 }
242 defer f.Close()
243 err = goyaml2.Write(f, c.data)
244 return err
245 }
246
133 // WriteValue writes a new value for key. 247 // WriteValue writes a new value for key.
134 func (c *YAMLConfigContainer) Set(key, val string) error { 248 func (c *YAMLConfigContainer) Set(key, val string) error {
135 c.Lock() 249 c.Lock()
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package config 15 package yaml
8 16
9 import ( 17 import (
10 "os" 18 "os"
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Usage:
16 //
17 // import "github.com/astaxie/beego/context"
18 //
19 // ctx := context.Context{Request:req,ResponseWriter:rw}
20 //
21 // more docs http://beego.me/docs/module/context.md
7 package context 22 package context
8 23
9 import ( 24 import (
...@@ -17,6 +32,7 @@ import ( ...@@ -17,6 +32,7 @@ import (
17 "time" 32 "time"
18 33
19 "github.com/astaxie/beego/middleware" 34 "github.com/astaxie/beego/middleware"
35 "github.com/astaxie/beego/utils"
20 ) 36 )
21 37
22 // Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter. 38 // Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
...@@ -26,20 +42,21 @@ type Context struct { ...@@ -26,20 +42,21 @@ type Context struct {
26 Output *BeegoOutput 42 Output *BeegoOutput
27 Request *http.Request 43 Request *http.Request
28 ResponseWriter http.ResponseWriter 44 ResponseWriter http.ResponseWriter
45 _xsrf_token string
29 } 46 }
30 47
31 // Redirect does redirection to localurl with http header status code. 48 // Redirect does redirection to localurl with http header status code.
32 // It sends http response header directly. 49 // It sends http response header directly.
33 func (ctx *Context) Redirect(status int, localurl string) { 50 func (ctx *Context) Redirect(status int, localurl string) {
34 ctx.Output.Header("Location", localurl) 51 ctx.Output.Header("Location", localurl)
35 ctx.Output.SetStatus(status) 52 ctx.ResponseWriter.WriteHeader(status)
36 } 53 }
37 54
38 // Abort stops this request. 55 // Abort stops this request.
39 // if middleware.ErrorMaps exists, panic body. 56 // if middleware.ErrorMaps exists, panic body.
40 // if middleware.HTTPExceptionMaps exists, panic HTTPException struct with status and body string. 57 // if middleware.HTTPExceptionMaps exists, panic HTTPException struct with status and body string.
41 func (ctx *Context) Abort(status int, body string) { 58 func (ctx *Context) Abort(status int, body string) {
42 ctx.Output.SetStatus(status) 59 ctx.ResponseWriter.WriteHeader(status)
43 // first panic from ErrorMaps, is is user defined error functions. 60 // first panic from ErrorMaps, is is user defined error functions.
44 if _, ok := middleware.ErrorMaps[body]; ok { 61 if _, ok := middleware.ErrorMaps[body]; ok {
45 panic(body) 62 panic(body)
...@@ -58,7 +75,7 @@ func (ctx *Context) Abort(status int, body string) { ...@@ -58,7 +75,7 @@ func (ctx *Context) Abort(status int, body string) {
58 // Write string to response body. 75 // Write string to response body.
59 // it sends response body. 76 // it sends response body.
60 func (ctx *Context) WriteString(content string) { 77 func (ctx *Context) WriteString(content string) {
61 ctx.Output.Body([]byte(content)) 78 ctx.ResponseWriter.Write([]byte(content))
62 } 79 }
63 80
64 // Get cookie from request by a given key. 81 // Get cookie from request by a given key.
...@@ -110,3 +127,35 @@ func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interf ...@@ -110,3 +127,35 @@ func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interf
110 cookie := strings.Join([]string{vs, timestamp, sig}, "|") 127 cookie := strings.Join([]string{vs, timestamp, sig}, "|")
111 ctx.Output.Cookie(name, cookie, others...) 128 ctx.Output.Cookie(name, cookie, others...)
112 } 129 }
130
131 // XsrfToken creates a xsrf token string and returns.
132 func (ctx *Context) XsrfToken(key string, expire int64) string {
133 if ctx._xsrf_token == "" {
134 token, ok := ctx.GetSecureCookie(key, "_xsrf")
135 if !ok {
136 token = string(utils.RandomCreateBytes(32))
137 ctx.SetSecureCookie(key, "_xsrf", token, expire)
138 }
139 ctx._xsrf_token = token
140 }
141 return ctx._xsrf_token
142 }
143
144 // CheckXsrfCookie checks xsrf token in this request is valid or not.
145 // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
146 // or in form field value named as "_xsrf".
147 func (ctx *Context) CheckXsrfCookie() bool {
148 token := ctx.Input.Query("_xsrf")
149 if token == "" {
150 token = ctx.Request.Header.Get("X-Xsrftoken")
151 }
152 if token == "" {
153 token = ctx.Request.Header.Get("X-Csrftoken")
154 }
155 if token == "" {
156 ctx.Abort(403, "'_xsrf' argument missing from POST")
157 } else if ctx._xsrf_token != token {
158 ctx.Abort(403, "XSRF cookie does not match POST argument")
159 }
160 return true
161 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package context 15 package context
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package context 15 package context
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package context 15 package context
8 16
...@@ -68,6 +76,14 @@ func (output *BeegoOutput) Body(content []byte) { ...@@ -68,6 +76,14 @@ func (output *BeegoOutput) Body(content []byte) {
68 } else { 76 } else {
69 output.Header("Content-Length", strconv.Itoa(len(content))) 77 output.Header("Content-Length", strconv.Itoa(len(content)))
70 } 78 }
79
80 // Write status code if it has been set manually
81 // Set it to 0 afterwards to prevent "multiple response.WriteHeader calls"
82 if output.Status != 0 {
83 output.Context.ResponseWriter.WriteHeader(output.Status)
84 output.Status = 0
85 }
86
71 output_writer.Write(content) 87 output_writer.Write(content)
72 switch output_writer.(type) { 88 switch output_writer.(type) {
73 case *gzip.Writer: 89 case *gzip.Writer:
...@@ -267,7 +283,6 @@ func (output *BeegoOutput) ContentType(ext string) { ...@@ -267,7 +283,6 @@ func (output *BeegoOutput) ContentType(ext string) {
267 // SetStatus sets response status code. 283 // SetStatus sets response status code.
268 // It writes response header directly. 284 // It writes response header directly.
269 func (output *BeegoOutput) SetStatus(status int) { 285 func (output *BeegoOutput) SetStatus(status int) {
270 output.Context.ResponseWriter.WriteHeader(status)
271 output.Status = status 286 output.Status = status
272 } 287 }
273 288
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
...@@ -22,7 +30,6 @@ import ( ...@@ -22,7 +30,6 @@ import (
22 30
23 "github.com/astaxie/beego/context" 31 "github.com/astaxie/beego/context"
24 "github.com/astaxie/beego/session" 32 "github.com/astaxie/beego/session"
25 "github.com/astaxie/beego/utils"
26 ) 33 )
27 34
28 //commonly used mime-types 35 //commonly used mime-types
...@@ -270,6 +277,11 @@ func (c *Controller) Abort(code string) { ...@@ -270,6 +277,11 @@ func (c *Controller) Abort(code string) {
270 } 277 }
271 } 278 }
272 279
280 // CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
281 func (c *Controller) CustomAbort(status int, body string) {
282 c.Ctx.Abort(status, body)
283 }
284
273 // StopRun makes panic of USERSTOPRUN error and go to recover function if defined. 285 // StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
274 func (c *Controller) StopRun() { 286 func (c *Controller) StopRun() {
275 panic(USERSTOPRUN) 287 panic(USERSTOPRUN)
...@@ -474,18 +486,13 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter ...@@ -474,18 +486,13 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter
474 // XsrfToken creates a xsrf token string and returns. 486 // XsrfToken creates a xsrf token string and returns.
475 func (c *Controller) XsrfToken() string { 487 func (c *Controller) XsrfToken() string {
476 if c._xsrf_token == "" { 488 if c._xsrf_token == "" {
477 token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf") 489 var expire int64
478 if !ok { 490 if c.XSRFExpire > 0 {
479 var expire int64 491 expire = int64(c.XSRFExpire)
480 if c.XSRFExpire > 0 { 492 } else {
481 expire = int64(c.XSRFExpire) 493 expire = int64(XSRFExpire)
482 } else {
483 expire = int64(XSRFExpire)
484 }
485 token = string(utils.RandomCreateBytes(32))
486 c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire)
487 } 494 }
488 c._xsrf_token = token 495 c._xsrf_token = c.Ctx.XsrfToken(XSRFKEY, expire)
489 } 496 }
490 return c._xsrf_token 497 return c._xsrf_token
491 } 498 }
...@@ -497,19 +504,7 @@ func (c *Controller) CheckXsrfCookie() bool { ...@@ -497,19 +504,7 @@ func (c *Controller) CheckXsrfCookie() bool {
497 if !c.EnableXSRF { 504 if !c.EnableXSRF {
498 return true 505 return true
499 } 506 }
500 token := c.GetString("_xsrf") 507 return c.Ctx.CheckXsrfCookie()
501 if token == "" {
502 token = c.Ctx.Request.Header.Get("X-Xsrftoken")
503 }
504 if token == "" {
505 token = c.Ctx.Request.Header.Get("X-Csrftoken")
506 }
507 if token == "" {
508 c.Ctx.Abort(403, "'_xsrf' argument missing from POST")
509 } else if c._xsrf_token != token {
510 c.Ctx.Abort(403, "XSRF cookie does not match POST argument")
511 }
512 return true
513 } 508 }
514 509
515 // XsrfFormHtml writes an input field contains xsrf token value. 510 // XsrfFormHtml writes an input field contains xsrf token value.
......
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
1 package beego 15 package beego
2 16
3 import ( 17 import (
......
1 // Beego (http://beego.me/) 1 // Beego (http://beego.me/)
2
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 3 // @description beego is an open-source, high-performance web framework for the Go programming language.
4
3 // @link http://github.com/astaxie/beego for the canonical source repository 5 // @link http://github.com/astaxie/beego for the canonical source repository
6
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 7 // @license http://github.com/astaxie/beego/blob/master/LICENSE
8
5 // @authors astaxie 9 // @authors astaxie
6 10
7 package main 11 package main
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
15 // Usage:
16 //
17 // import "github.com/astaxie/beego/context"
18 //
19 // b := httplib.Post("http://beego.me/")
20 // b.Param("username","astaxie")
21 // b.Param("password","123456")
22 // b.PostFile("uploadfile1", "httplib.pdf")
23 // b.PostFile("uploadfile2", "httplib.txt")
24 // str, err := b.String()
25 // if err != nil {
26 // t.Fatal(err)
27 // }
28 // fmt.Println(str)
29 //
30 // more docs http://beego.me/docs/module/httplib.md
7 package httplib 31 package httplib
8 32
9 import ( 33 import (
...@@ -52,41 +76,46 @@ func SetDefaultSetting(setting BeegoHttpSettings) { ...@@ -52,41 +76,46 @@ func SetDefaultSetting(setting BeegoHttpSettings) {
52 // Get returns *BeegoHttpRequest with GET method. 76 // Get returns *BeegoHttpRequest with GET method.
53 func Get(url string) *BeegoHttpRequest { 77 func Get(url string) *BeegoHttpRequest {
54 var req http.Request 78 var req http.Request
79 var resp http.Response
55 req.Method = "GET" 80 req.Method = "GET"
56 req.Header = http.Header{} 81 req.Header = http.Header{}
57 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting} 82 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting, &resp, nil}
58 } 83 }
59 84
60 // Post returns *BeegoHttpRequest with POST method. 85 // Post returns *BeegoHttpRequest with POST method.
61 func Post(url string) *BeegoHttpRequest { 86 func Post(url string) *BeegoHttpRequest {
62 var req http.Request 87 var req http.Request
88 var resp http.Response
63 req.Method = "POST" 89 req.Method = "POST"
64 req.Header = http.Header{} 90 req.Header = http.Header{}
65 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting} 91 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting, &resp, nil}
66 } 92 }
67 93
68 // Put returns *BeegoHttpRequest with PUT method. 94 // Put returns *BeegoHttpRequest with PUT method.
69 func Put(url string) *BeegoHttpRequest { 95 func Put(url string) *BeegoHttpRequest {
70 var req http.Request 96 var req http.Request
97 var resp http.Response
71 req.Method = "PUT" 98 req.Method = "PUT"
72 req.Header = http.Header{} 99 req.Header = http.Header{}
73 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting} 100 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting, &resp, nil}
74 } 101 }
75 102
76 // Delete returns *BeegoHttpRequest DELETE GET method. 103 // Delete returns *BeegoHttpRequest DELETE GET method.
77 func Delete(url string) *BeegoHttpRequest { 104 func Delete(url string) *BeegoHttpRequest {
78 var req http.Request 105 var req http.Request
106 var resp http.Response
79 req.Method = "DELETE" 107 req.Method = "DELETE"
80 req.Header = http.Header{} 108 req.Header = http.Header{}
81 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting} 109 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting, &resp, nil}
82 } 110 }
83 111
84 // Head returns *BeegoHttpRequest with HEAD method. 112 // Head returns *BeegoHttpRequest with HEAD method.
85 func Head(url string) *BeegoHttpRequest { 113 func Head(url string) *BeegoHttpRequest {
86 var req http.Request 114 var req http.Request
115 var resp http.Response
87 req.Method = "HEAD" 116 req.Method = "HEAD"
88 req.Header = http.Header{} 117 req.Header = http.Header{}
89 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting} 118 return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, defaultSetting, &resp, nil}
90 } 119 }
91 120
92 // BeegoHttpSettings 121 // BeegoHttpSettings
...@@ -108,6 +137,8 @@ type BeegoHttpRequest struct { ...@@ -108,6 +137,8 @@ type BeegoHttpRequest struct {
108 params map[string]string 137 params map[string]string
109 files map[string]string 138 files map[string]string
110 setting BeegoHttpSettings 139 setting BeegoHttpSettings
140 resp *http.Response
141 body []byte
111 } 142 }
112 143
113 // Change request settings 144 // Change request settings
...@@ -123,7 +154,7 @@ func (b *BeegoHttpRequest) SetEnableCookie(enable bool) *BeegoHttpRequest { ...@@ -123,7 +154,7 @@ func (b *BeegoHttpRequest) SetEnableCookie(enable bool) *BeegoHttpRequest {
123 } 154 }
124 155
125 // SetUserAgent sets User-Agent header field 156 // SetUserAgent sets User-Agent header field
126 func (b *BeegoHttpRequest) SetAgent(useragent string) *BeegoHttpRequest { 157 func (b *BeegoHttpRequest) SetUserAgent(useragent string) *BeegoHttpRequest {
127 b.setting.UserAgent = useragent 158 b.setting.UserAgent = useragent
128 return b 159 return b
129 } 160 }
...@@ -223,6 +254,9 @@ func (b *BeegoHttpRequest) Body(data interface{}) *BeegoHttpRequest { ...@@ -223,6 +254,9 @@ func (b *BeegoHttpRequest) Body(data interface{}) *BeegoHttpRequest {
223 } 254 }
224 255
225 func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { 256 func (b *BeegoHttpRequest) getResponse() (*http.Response, error) {
257 if b.resp.StatusCode != 0 {
258 return b.resp, nil
259 }
226 var paramBody string 260 var paramBody string
227 if len(b.params) > 0 { 261 if len(b.params) > 0 {
228 var buf bytes.Buffer 262 var buf bytes.Buffer
...@@ -341,6 +375,7 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { ...@@ -341,6 +375,7 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) {
341 if err != nil { 375 if err != nil {
342 return nil, err 376 return nil, err
343 } 377 }
378 b.resp = resp
344 return resp, nil 379 return resp, nil
345 } 380 }
346 381
...@@ -358,6 +393,9 @@ func (b *BeegoHttpRequest) String() (string, error) { ...@@ -358,6 +393,9 @@ func (b *BeegoHttpRequest) String() (string, error) {
358 // Bytes returns the body []byte in response. 393 // Bytes returns the body []byte in response.
359 // it calls Response inner. 394 // it calls Response inner.
360 func (b *BeegoHttpRequest) Bytes() ([]byte, error) { 395 func (b *BeegoHttpRequest) Bytes() ([]byte, error) {
396 if b.body != nil {
397 return b.body, nil
398 }
361 resp, err := b.getResponse() 399 resp, err := b.getResponse()
362 if err != nil { 400 if err != nil {
363 return nil, err 401 return nil, err
...@@ -370,6 +408,7 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) { ...@@ -370,6 +408,7 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) {
370 if err != nil { 408 if err != nil {
371 return nil, err 409 return nil, err
372 } 410 }
411 b.body = data
373 return data, nil 412 return data, nil
374 } 413 }
375 414
...@@ -391,10 +430,7 @@ func (b *BeegoHttpRequest) ToFile(filename string) error { ...@@ -391,10 +430,7 @@ func (b *BeegoHttpRequest) ToFile(filename string) error {
391 } 430 }
392 defer resp.Body.Close() 431 defer resp.Body.Close()
393 _, err = io.Copy(f, resp.Body) 432 _, err = io.Copy(f, resp.Body)
394 if err != nil { 433 return err
395 return err
396 }
397 return nil
398 } 434 }
399 435
400 // ToJson returns the map that marshals from the body bytes as json in response . 436 // ToJson returns the map that marshals from the body bytes as json in response .
...@@ -405,24 +441,18 @@ func (b *BeegoHttpRequest) ToJson(v interface{}) error { ...@@ -405,24 +441,18 @@ func (b *BeegoHttpRequest) ToJson(v interface{}) error {
405 return err 441 return err
406 } 442 }
407 err = json.Unmarshal(data, v) 443 err = json.Unmarshal(data, v)
408 if err != nil { 444 return err
409 return err
410 }
411 return nil
412 } 445 }
413 446
414 // ToXml returns the map that marshals from the body bytes as xml in response . 447 // ToXml returns the map that marshals from the body bytes as xml in response .
415 // it calls Response inner. 448 // it calls Response inner.
416 func (b *BeegoHttpRequest) ToXML(v interface{}) error { 449 func (b *BeegoHttpRequest) ToXml(v interface{}) error {
417 data, err := b.Bytes() 450 data, err := b.Bytes()
418 if err != nil { 451 if err != nil {
419 return err 452 return err
420 } 453 }
421 err = xml.Unmarshal(data, v) 454 err = xml.Unmarshal(data, v)
422 if err != nil { 455 return err
423 return err
424 }
425 return nil
426 } 456 }
427 457
428 // Response executes request client gets response mannually. 458 // Response executes request client gets response mannually.
......
1 // Beego (http://beego.me) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package httplib 15 package httplib
8 16
9 import ( 17 import (
10 "fmt"
11 "io/ioutil" 18 "io/ioutil"
19 "os"
20 "strings"
12 "testing" 21 "testing"
13 ) 22 )
14 23
15 func TestGetUrl(t *testing.T) { 24 func TestResponse(t *testing.T) {
16 resp, err := Get("http://beego.me").Debug(true).Response() 25 req := Get("http://httpbin.org/get")
26 resp, err := req.Response()
17 if err != nil { 27 if err != nil {
18 t.Fatal(err) 28 t.Fatal(err)
19 } 29 }
20 if resp.Body == nil { 30 t.Log(resp)
21 t.Fatal("body is nil") 31 }
32
33 func TestGet(t *testing.T) {
34 req := Get("http://httpbin.org/get")
35 b, err := req.Bytes()
36 if err != nil {
37 t.Fatal(err)
22 } 38 }
23 data, err := ioutil.ReadAll(resp.Body) 39 t.Log(b)
24 defer resp.Body.Close() 40
41 s, err := req.String()
25 if err != nil { 42 if err != nil {
26 t.Fatal(err) 43 t.Fatal(err)
27 } 44 }
28 if len(data) == 0 { 45 t.Log(s)
29 t.Fatal("data is no") 46
47 if string(b) != s {
48 t.Fatal("request data not match")
30 } 49 }
50 }
51
52 func TestSimplePost(t *testing.T) {
53 v := "smallfish"
54 req := Post("http://httpbin.org/post")
55 req.Param("username", v)
31 56
32 str, err := Get("http://beego.me").String() 57 str, err := req.String()
33 if err != nil { 58 if err != nil {
34 t.Fatal(err) 59 t.Fatal(err)
35 } 60 }
36 if len(str) == 0 { 61 t.Log(str)
37 t.Fatal("has no info") 62
63 n := strings.Index(str, v)
64 if n == -1 {
65 t.Fatal(v + " not found in post")
38 } 66 }
39 } 67 }
40 68
41 func ExamplePost(t *testing.T) { 69 func TestPostFile(t *testing.T) {
42 b := Post("http://beego.me/").Debug(true) 70 v := "smallfish"
43 b.Param("username", "astaxie") 71 req := Post("http://httpbin.org/post")
44 b.Param("password", "hello") 72 req.Param("username", v)
45 b.PostFile("uploadfile", "httplib_test.go") 73 req.PostFile("uploadfile", "httplib_test.go")
46 str, err := b.String() 74
75 str, err := req.String()
47 if err != nil { 76 if err != nil {
48 t.Fatal(err) 77 t.Fatal(err)
49 } 78 }
50 fmt.Println(str) 79 t.Log(str)
80
81 n := strings.Index(str, v)
82 if n == -1 {
83 t.Fatal(v + " not found in post")
84 }
51 } 85 }
52 86
53 func TestSimpleGetString(t *testing.T) { 87 func TestSimplePut(t *testing.T) {
54 fmt.Println("TestSimpleGetString==========================================") 88 str, err := Put("http://httpbin.org/put").String()
55 html, err := Get("http://httpbin.org/headers").SetAgent("beegoooooo").String() 89 if err != nil {
90 t.Fatal(err)
91 }
92 t.Log(str)
93 }
94
95 func TestSimpleDelete(t *testing.T) {
96 str, err := Delete("http://httpbin.org/delete").String()
97 if err != nil {
98 t.Fatal(err)
99 }
100 t.Log(str)
101 }
102
103 func TestWithCookie(t *testing.T) {
104 v := "smallfish"
105 str, err := Get("http://httpbin.org/cookies/set?k1=" + v).SetEnableCookie(true).String()
106 if err != nil {
107 t.Fatal(err)
108 }
109 t.Log(str)
110
111 str, err = Get("http://httpbin.org/cookies").SetEnableCookie(true).String()
56 if err != nil { 112 if err != nil {
57 t.Fatal(err) 113 t.Fatal(err)
58 } 114 }
59 fmt.Println(html) 115 t.Log(str)
60 fmt.Println("TestSimpleGetString==========================================") 116
117 n := strings.Index(str, v)
118 if n == -1 {
119 t.Fatal(v + " not found in cookie")
120 }
61 } 121 }
62 122
63 func TestSimpleGetStringWithDefaultCookie(t *testing.T) { 123 func TestWithUserAgent(t *testing.T) {
64 fmt.Println("TestSimpleGetStringWithDefaultCookie==========================================") 124 v := "beego"
65 html, err := Get("http://httpbin.org/cookies/set?k1=v1").SetEnableCookie(true).String() 125 str, err := Get("http://httpbin.org/headers").SetUserAgent(v).String()
66 if err != nil { 126 if err != nil {
67 t.Fatal(err) 127 t.Fatal(err)
68 } 128 }
69 fmt.Println(html) 129 t.Log(str)
70 html, err = Get("http://httpbin.org/cookies").SetEnableCookie(true).String() 130
131 n := strings.Index(str, v)
132 if n == -1 {
133 t.Fatal(v + " not found in user-agent")
134 }
135 }
136
137 func TestWithSetting(t *testing.T) {
138 v := "beego"
139 var setting BeegoHttpSettings
140 setting.EnableCookie = true
141 setting.UserAgent = v
142 setting.Transport = nil
143 SetDefaultSetting(setting)
144
145 str, err := Get("http://httpbin.org/get").String()
71 if err != nil { 146 if err != nil {
72 t.Fatal(err) 147 t.Fatal(err)
73 } 148 }
74 fmt.Println(html) 149 t.Log(str)
75 fmt.Println("TestSimpleGetStringWithDefaultCookie==========================================") 150
151 n := strings.Index(str, v)
152 if n == -1 {
153 t.Fatal(v + " not found in user-agent")
154 }
76 } 155 }
77 156
78 func TestDefaultSetting(t *testing.T) { 157 func TestToJson(t *testing.T) {
79 fmt.Println("TestDefaultSetting==========================================") 158 req := Get("http://httpbin.org/ip")
80 var def BeegoHttpSettings 159 resp, err := req.Response()
81 def.EnableCookie = true
82 //def.ShowDebug = true
83 def.UserAgent = "UserAgent"
84 //def.ConnectTimeout = 60*time.Second
85 //def.ReadWriteTimeout = 60*time.Second
86 def.Transport = nil //http.DefaultTransport
87 SetDefaultSetting(def)
88
89 html, err := Get("http://httpbin.org/headers").String()
90 if err != nil { 160 if err != nil {
91 t.Fatal(err) 161 t.Fatal(err)
92 } 162 }
93 fmt.Println(html) 163 t.Log(resp)
94 html, err = Get("http://httpbin.org/headers").String() 164
165 // httpbin will return http remote addr
166 type Ip struct {
167 Origin string `json:"origin"`
168 }
169 var ip Ip
170 err = req.ToJson(&ip)
95 if err != nil { 171 if err != nil {
96 t.Fatal(err) 172 t.Fatal(err)
97 } 173 }
98 fmt.Println(html) 174 t.Log(ip.Origin)
99 fmt.Println("TestDefaultSetting==========================================") 175
176 if n := strings.Count(ip.Origin, "."); n != 3 {
177 t.Fatal("response is not valid ip")
178 }
179 }
180
181 func TestToFile(t *testing.T) {
182 f := "beego_testfile"
183 req := Get("http://httpbin.org/ip")
184 err := req.ToFile(f)
185 if err != nil {
186 t.Fatal(err)
187 }
188 defer os.Remove(f)
189 b, err := ioutil.ReadFile(f)
190 if n := strings.Index(string(b), "origin"); n == -1 {
191 t.Fatal(err)
192 }
100 } 193 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
...@@ -14,12 +22,14 @@ import ( ...@@ -14,12 +22,14 @@ import (
14 22
15 // Log levels to control the logging output. 23 // Log levels to control the logging output.
16 const ( 24 const (
17 LevelTrace = iota 25 LevelEmergency = iota
18 LevelDebug 26 LevelAlert
19 LevelInfo
20 LevelWarning
21 LevelError
22 LevelCritical 27 LevelCritical
28 LevelError
29 LevelWarning
30 LevelNotice
31 LevelInformational
32 LevelDebug
23 ) 33 )
24 34
25 // SetLogLevel sets the global log level used by the simple 35 // SetLogLevel sets the global log level used by the simple
...@@ -45,34 +55,57 @@ func SetLogger(adaptername string, config string) error { ...@@ -45,34 +55,57 @@ func SetLogger(adaptername string, config string) error {
45 return nil 55 return nil
46 } 56 }
47 57
48 // Trace logs a message at trace level. 58 func Emergency(v ...interface{}) {
49 func Trace(v ...interface{}) { 59 BeeLogger.Emergency(generateFmtStr(len(v)), v...)
50 BeeLogger.Trace(generateFmtStr(len(v)), v...)
51 } 60 }
52 61
53 // Debug logs a message at debug level. 62 func Alert(v ...interface{}) {
54 func Debug(v ...interface{}) { 63 BeeLogger.Alert(generateFmtStr(len(v)), v...)
55 BeeLogger.Debug(generateFmtStr(len(v)), v...)
56 } 64 }
57 65
58 // Info logs a message at info level. 66 // Critical logs a message at critical level.
59 func Info(v ...interface{}) { 67 func Critical(v ...interface{}) {
60 BeeLogger.Info(generateFmtStr(len(v)), v...) 68 BeeLogger.Critical(generateFmtStr(len(v)), v...)
69 }
70
71 // Error logs a message at error level.
72 func Error(v ...interface{}) {
73 BeeLogger.Error(generateFmtStr(len(v)), v...)
61 } 74 }
62 75
63 // Warning logs a message at warning level. 76 // Warning logs a message at warning level.
77 func Warning(v ...interface{}) {
78 BeeLogger.Warning(generateFmtStr(len(v)), v...)
79 }
80
81 // Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0.
64 func Warn(v ...interface{}) { 82 func Warn(v ...interface{}) {
65 BeeLogger.Warn(generateFmtStr(len(v)), v...) 83 Warning(v...)
66 } 84 }
67 85
68 // Error logs a message at error level. 86 func Notice(v ...interface{}) {
69 func Error(v ...interface{}) { 87 BeeLogger.Notice(generateFmtStr(len(v)), v...)
70 BeeLogger.Error(generateFmtStr(len(v)), v...)
71 } 88 }
72 89
73 // Critical logs a message at critical level. 90 // Info logs a message at info level.
74 func Critical(v ...interface{}) { 91 func Informational(v ...interface{}) {
75 BeeLogger.Critical(generateFmtStr(len(v)), v...) 92 BeeLogger.Informational(generateFmtStr(len(v)), v...)
93 }
94
95 // Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0.
96 func Info(v ...interface{}) {
97 Informational(v...)
98 }
99
100 // Debug logs a message at debug level.
101 func Debug(v ...interface{}) {
102 BeeLogger.Debug(generateFmtStr(len(v)), v...)
103 }
104
105 // Trace logs a message at trace level.
106 // Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0.
107 func Trace(v ...interface{}) {
108 BeeLogger.Trace(generateFmtStr(len(v)), v...)
76 } 109 }
77 110
78 func generateFmtStr(n int) string { 111 func generateFmtStr(n int) string {
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -45,7 +53,7 @@ func (c *ConnWriter) Init(jsonconfig string) error { ...@@ -45,7 +53,7 @@ func (c *ConnWriter) Init(jsonconfig string) error {
45 // write message in connection. 53 // write message in connection.
46 // if connection is down, try to re-connect. 54 // if connection is down, try to re-connect.
47 func (c *ConnWriter) WriteMsg(msg string, level int) error { 55 func (c *ConnWriter) WriteMsg(msg string, level int) error {
48 if level < c.Level { 56 if level > c.Level {
49 return nil 57 return nil
50 } 58 }
51 if c.neddedConnectOnMsg() { 59 if c.neddedConnectOnMsg() {
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -13,5 +21,5 @@ import ( ...@@ -13,5 +21,5 @@ import (
13 func TestConn(t *testing.T) { 21 func TestConn(t *testing.T) {
14 log := NewLogger(1000) 22 log := NewLogger(1000)
15 log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) 23 log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`)
16 log.Info("info") 24 log.Informational("informational")
17 } 25 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -24,12 +32,14 @@ func NewBrush(color string) Brush { ...@@ -24,12 +32,14 @@ func NewBrush(color string) Brush {
24 } 32 }
25 33
26 var colors = []Brush{ 34 var colors = []Brush{
27 NewBrush("1;36"), // Trace cyan 35 NewBrush("1;37"), // Emergency white
28 NewBrush("1;34"), // Debug blue 36 NewBrush("1;36"), // Alert cyan
29 NewBrush("1;32"), // Info green 37 NewBrush("1;35"), // Critical magenta
30 NewBrush("1;33"), // Warn yellow
31 NewBrush("1;31"), // Error red 38 NewBrush("1;31"), // Error red
32 NewBrush("1;35"), // Critical purple 39 NewBrush("1;33"), // Warning yellow
40 NewBrush("1;32"), // Notice green
41 NewBrush("1;34"), // Informational blue
42 NewBrush("1;34"), // Debug blue
33 } 43 }
34 44
35 // ConsoleWriter implements LoggerInterface and writes messages to terminal. 45 // ConsoleWriter implements LoggerInterface and writes messages to terminal.
...@@ -42,7 +52,7 @@ type ConsoleWriter struct { ...@@ -42,7 +52,7 @@ type ConsoleWriter struct {
42 func NewConsole() LoggerInterface { 52 func NewConsole() LoggerInterface {
43 cw := new(ConsoleWriter) 53 cw := new(ConsoleWriter)
44 cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime) 54 cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime)
45 cw.Level = LevelTrace 55 cw.Level = LevelDebug
46 return cw 56 return cw
47 } 57 }
48 58
...@@ -61,7 +71,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error { ...@@ -61,7 +71,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error {
61 71
62 // write message in console. 72 // write message in console.
63 func (c *ConsoleWriter) WriteMsg(msg string, level int) error { 73 func (c *ConsoleWriter) WriteMsg(msg string, level int) error {
64 if level < c.Level { 74 if level > c.Level {
65 return nil 75 return nil
66 } 76 }
67 if goos := runtime.GOOS; goos == "windows" { 77 if goos := runtime.GOOS; goos == "windows" {
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -10,22 +18,29 @@ import ( ...@@ -10,22 +18,29 @@ import (
10 "testing" 18 "testing"
11 ) 19 )
12 20
21 // Try each log level in decreasing order of priority.
22 func testConsoleCalls(bl *BeeLogger) {
23 bl.Emergency("emergency")
24 bl.Alert("alert")
25 bl.Critical("critical")
26 bl.Error("error")
27 bl.Warning("warning")
28 bl.Notice("notice")
29 bl.Informational("informational")
30 bl.Debug("debug")
31 }
32
33 // Test console logging by visually comparing the lines being output with and
34 // without a log level specification.
13 func TestConsole(t *testing.T) { 35 func TestConsole(t *testing.T) {
14 log := NewLogger(10000) 36 log1 := NewLogger(10000)
15 log.EnableFuncCallDepth(true) 37 log1.EnableFuncCallDepth(true)
16 log.SetLogger("console", "") 38 log1.SetLogger("console", "")
17 log.Trace("trace") 39 testConsoleCalls(log1)
18 log.Info("info") 40
19 log.Warn("warning")
20 log.Debug("debug")
21 log.Critical("critical")
22 log2 := NewLogger(100) 41 log2 := NewLogger(100)
23 log2.SetLogger("console", `{"level":1}`) 42 log2.SetLogger("console", `{"level":3}`)
24 log.Trace("trace") 43 testConsoleCalls(log2)
25 log.Info("info")
26 log.Warn("warning")
27 log.Debug("debug")
28 log.Critical("critical")
29 } 44 }
30 45
31 func BenchmarkConsole(b *testing.B) { 46 func BenchmarkConsole(b *testing.B) {
...@@ -33,6 +48,6 @@ func BenchmarkConsole(b *testing.B) { ...@@ -33,6 +48,6 @@ func BenchmarkConsole(b *testing.B) {
33 log.EnableFuncCallDepth(true) 48 log.EnableFuncCallDepth(true)
34 log.SetLogger("console", "") 49 log.SetLogger("console", "")
35 for i := 0; i < b.N; i++ { 50 for i := 0; i < b.N; i++ {
36 log.Trace("trace") 51 log.Debug("debug")
37 } 52 }
38 } 53 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -138,7 +146,7 @@ func (w *FileLogWriter) docheck(size int) { ...@@ -138,7 +146,7 @@ func (w *FileLogWriter) docheck(size int) {
138 146
139 // write logger message into file. 147 // write logger message into file.
140 func (w *FileLogWriter) WriteMsg(msg string, level int) error { 148 func (w *FileLogWriter) WriteMsg(msg string, level int) error {
141 if level < w.Level { 149 if level > w.Level {
142 return nil 150 return nil
143 } 151 }
144 n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] " 152 n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] "
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -10,6 +18,7 @@ import ( ...@@ -10,6 +18,7 @@ import (
10 "bufio" 18 "bufio"
11 "fmt" 19 "fmt"
12 "os" 20 "os"
21 "strconv"
13 "testing" 22 "testing"
14 "time" 23 "time"
15 ) 24 )
...@@ -17,12 +26,14 @@ import ( ...@@ -17,12 +26,14 @@ import (
17 func TestFile(t *testing.T) { 26 func TestFile(t *testing.T) {
18 log := NewLogger(10000) 27 log := NewLogger(10000)
19 log.SetLogger("file", `{"filename":"test.log"}`) 28 log.SetLogger("file", `{"filename":"test.log"}`)
20 log.Trace("test")
21 log.Info("info")
22 log.Debug("debug") 29 log.Debug("debug")
23 log.Warn("warning") 30 log.Informational("info")
31 log.Notice("notice")
32 log.Warning("warning")
24 log.Error("error") 33 log.Error("error")
34 log.Alert("alert")
25 log.Critical("critical") 35 log.Critical("critical")
36 log.Emergency("emergency")
26 time.Sleep(time.Second * 4) 37 time.Sleep(time.Second * 4)
27 f, err := os.Open("test.log") 38 f, err := os.Open("test.log")
28 if err != nil { 39 if err != nil {
...@@ -39,21 +50,24 @@ func TestFile(t *testing.T) { ...@@ -39,21 +50,24 @@ func TestFile(t *testing.T) {
39 linenum++ 50 linenum++
40 } 51 }
41 } 52 }
42 if linenum != 6 { 53 var expected = LevelDebug + 1
43 t.Fatal(linenum, "not line 6") 54 if linenum != expected {
55 t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines")
44 } 56 }
45 os.Remove("test.log") 57 os.Remove("test.log")
46 } 58 }
47 59
48 func TestFile2(t *testing.T) { 60 func TestFile2(t *testing.T) {
49 log := NewLogger(10000) 61 log := NewLogger(10000)
50 log.SetLogger("file", `{"filename":"test2.log","level":2}`) 62 log.SetLogger("file", fmt.Sprintf(`{"filename":"test2.log","level":%d}`, LevelError))
51 log.Trace("test")
52 log.Info("info")
53 log.Debug("debug") 63 log.Debug("debug")
54 log.Warn("warning") 64 log.Info("info")
65 log.Notice("notice")
66 log.Warning("warning")
55 log.Error("error") 67 log.Error("error")
68 log.Alert("alert")
56 log.Critical("critical") 69 log.Critical("critical")
70 log.Emergency("emergency")
57 time.Sleep(time.Second * 4) 71 time.Sleep(time.Second * 4)
58 f, err := os.Open("test2.log") 72 f, err := os.Open("test2.log")
59 if err != nil { 73 if err != nil {
...@@ -70,8 +84,9 @@ func TestFile2(t *testing.T) { ...@@ -70,8 +84,9 @@ func TestFile2(t *testing.T) {
70 linenum++ 84 linenum++
71 } 85 }
72 } 86 }
73 if linenum != 4 { 87 var expected = LevelError + 1
74 t.Fatal(linenum, "not line 4") 88 if linenum != expected {
89 t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines")
75 } 90 }
76 os.Remove("test2.log") 91 os.Remove("test2.log")
77 } 92 }
...@@ -79,17 +94,19 @@ func TestFile2(t *testing.T) { ...@@ -79,17 +94,19 @@ func TestFile2(t *testing.T) {
79 func TestFileRotate(t *testing.T) { 94 func TestFileRotate(t *testing.T) {
80 log := NewLogger(10000) 95 log := NewLogger(10000)
81 log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`) 96 log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`)
82 log.Trace("test")
83 log.Info("info")
84 log.Debug("debug") 97 log.Debug("debug")
85 log.Warn("warning") 98 log.Info("info")
99 log.Notice("notice")
100 log.Warning("warning")
86 log.Error("error") 101 log.Error("error")
102 log.Alert("alert")
87 log.Critical("critical") 103 log.Critical("critical")
104 log.Emergency("emergency")
88 time.Sleep(time.Second * 4) 105 time.Sleep(time.Second * 4)
89 rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) 106 rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1)
90 b, err := exists(rotatename) 107 b, err := exists(rotatename)
91 if !b || err != nil { 108 if !b || err != nil {
92 t.Fatal("rotate not gen") 109 t.Fatal("rotate not generated")
93 } 110 }
94 os.Remove(rotatename) 111 os.Remove(rotatename)
95 os.Remove("test3.log") 112 os.Remove("test3.log")
...@@ -110,7 +127,7 @@ func BenchmarkFile(b *testing.B) { ...@@ -110,7 +127,7 @@ func BenchmarkFile(b *testing.B) {
110 log := NewLogger(100000) 127 log := NewLogger(100000)
111 log.SetLogger("file", `{"filename":"test4.log"}`) 128 log.SetLogger("file", `{"filename":"test4.log"}`)
112 for i := 0; i < b.N; i++ { 129 for i := 0; i < b.N; i++ {
113 log.Trace("trace") 130 log.Debug("debug")
114 } 131 }
115 os.Remove("test4.log") 132 os.Remove("test4.log")
116 } 133 }
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
15 // Usage:
16 //
17 // import "github.com/astaxie/beego/logs"
18 //
19 // log := NewLogger(10000)
20 // log.SetLogger("console", "")
21 //
22 // > the first params stand for how many channel
23 //
24 // Use it like this:
25 //
26 // log.Trace("trace")
27 // log.Info("info")
28 // log.Warn("warning")
29 // log.Debug("debug")
30 // log.Critical("critical")
31 //
32 // more docs http://beego.me/docs/module/logs.md
7 package logs 33 package logs
8 34
9 import ( 35 import (
...@@ -13,14 +39,25 @@ import ( ...@@ -13,14 +39,25 @@ import (
13 "sync" 39 "sync"
14 ) 40 )
15 41
42 // RFC5424 log message levels.
16 const ( 43 const (
17 // log message levels 44 LevelEmergency = iota
18 LevelTrace = iota 45 LevelAlert
19 LevelDebug
20 LevelInfo
21 LevelWarn
22 LevelError
23 LevelCritical 46 LevelCritical
47 LevelError
48 LevelWarning
49 LevelNotice
50 LevelInformational
51 LevelDebug
52 )
53
54 // Legacy loglevel constants to ensure backwards compatibility.
55 //
56 // Deprecated: will be removed in 1.5.0.
57 const (
58 LevelInfo = LevelInformational
59 LevelTrace = LevelDebug
60 LevelWarn = LevelWarning
24 ) 61 )
25 62
26 type loggerType func() LoggerInterface 63 type loggerType func() LoggerInterface
...@@ -69,6 +106,7 @@ type logMsg struct { ...@@ -69,6 +106,7 @@ type logMsg struct {
69 // if the buffering chan is full, logger adapters write to file or other way. 106 // if the buffering chan is full, logger adapters write to file or other way.
70 func NewLogger(channellen int64) *BeeLogger { 107 func NewLogger(channellen int64) *BeeLogger {
71 bl := new(BeeLogger) 108 bl := new(BeeLogger)
109 bl.level = LevelDebug
72 bl.loggerFuncCallDepth = 2 110 bl.loggerFuncCallDepth = 2
73 bl.msg = make(chan *logMsg, channellen) 111 bl.msg = make(chan *logMsg, channellen)
74 bl.outputs = make(map[string]LoggerInterface) 112 bl.outputs = make(map[string]LoggerInterface)
...@@ -110,7 +148,7 @@ func (bl *BeeLogger) DelLogger(adaptername string) error { ...@@ -110,7 +148,7 @@ func (bl *BeeLogger) DelLogger(adaptername string) error {
110 } 148 }
111 149
112 func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { 150 func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {
113 if bl.level > loglevel { 151 if loglevel > bl.level {
114 return nil 152 return nil
115 } 153 }
116 lm := new(logMsg) 154 lm := new(logMsg)
...@@ -130,8 +168,10 @@ func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { ...@@ -130,8 +168,10 @@ func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {
130 return nil 168 return nil
131 } 169 }
132 170
133 // set log message level. 171 // Set log message level.
134 // if message level (such as LevelTrace) is less than logger level (such as LevelWarn), ignore message. 172 //
173 // If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
174 // log providers will not even be sent the message.
135 func (bl *BeeLogger) SetLevel(l int) { 175 func (bl *BeeLogger) SetLevel(l int) {
136 bl.level = l 176 bl.level = l
137 } 177 }
...@@ -147,7 +187,7 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) { ...@@ -147,7 +187,7 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
147 } 187 }
148 188
149 // start logger chan reading. 189 // start logger chan reading.
150 // when chan is full, write logs. 190 // when chan is not empty, write logs.
151 func (bl *BeeLogger) startLogger() { 191 func (bl *BeeLogger) startLogger() {
152 for { 192 for {
153 select { 193 select {
...@@ -159,40 +199,73 @@ func (bl *BeeLogger) startLogger() { ...@@ -159,40 +199,73 @@ func (bl *BeeLogger) startLogger() {
159 } 199 }
160 } 200 }
161 201
162 // log trace level message. 202 // Log EMERGENCY level message.
163 func (bl *BeeLogger) Trace(format string, v ...interface{}) { 203 func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
164 msg := fmt.Sprintf("[T] "+format, v...) 204 msg := fmt.Sprintf("[D] "+format, v...)
165 bl.writerMsg(LevelTrace, msg) 205 bl.writerMsg(LevelEmergency, msg)
166 } 206 }
167 207
168 // log debug level message. 208 // Log ALERT level message.
169 func (bl *BeeLogger) Debug(format string, v ...interface{}) { 209 func (bl *BeeLogger) Alert(format string, v ...interface{}) {
170 msg := fmt.Sprintf("[D] "+format, v...) 210 msg := fmt.Sprintf("[D] "+format, v...)
171 bl.writerMsg(LevelDebug, msg) 211 bl.writerMsg(LevelAlert, msg)
172 } 212 }
173 213
174 // log info level message. 214 // Log CRITICAL level message.
175 func (bl *BeeLogger) Info(format string, v ...interface{}) { 215 func (bl *BeeLogger) Critical(format string, v ...interface{}) {
216 msg := fmt.Sprintf("[C] "+format, v...)
217 bl.writerMsg(LevelCritical, msg)
218 }
219
220 // Log ERROR level message.
221 func (bl *BeeLogger) Error(format string, v ...interface{}) {
222 msg := fmt.Sprintf("[E] "+format, v...)
223 bl.writerMsg(LevelError, msg)
224 }
225
226 // Log WARNING level message.
227 func (bl *BeeLogger) Warning(format string, v ...interface{}) {
228 msg := fmt.Sprintf("[W] "+format, v...)
229 bl.writerMsg(LevelWarning, msg)
230 }
231
232 // Log NOTICE level message.
233 func (bl *BeeLogger) Notice(format string, v ...interface{}) {
234 msg := fmt.Sprintf("[W] "+format, v...)
235 bl.writerMsg(LevelNotice, msg)
236 }
237
238 // Log INFORMATIONAL level message.
239 func (bl *BeeLogger) Informational(format string, v ...interface{}) {
176 msg := fmt.Sprintf("[I] "+format, v...) 240 msg := fmt.Sprintf("[I] "+format, v...)
177 bl.writerMsg(LevelInfo, msg) 241 bl.writerMsg(LevelInformational, msg)
178 } 242 }
179 243
180 // log warn level message. 244 // Log DEBUG level message.
245 func (bl *BeeLogger) Debug(format string, v ...interface{}) {
246 msg := fmt.Sprintf("[D] "+format, v...)
247 bl.writerMsg(LevelDebug, msg)
248 }
249
250 // Log WARN level message.
251 //
252 // Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0.
181 func (bl *BeeLogger) Warn(format string, v ...interface{}) { 253 func (bl *BeeLogger) Warn(format string, v ...interface{}) {
182 msg := fmt.Sprintf("[W] "+format, v...) 254 bl.Warning(format, v...)
183 bl.writerMsg(LevelWarn, msg)
184 } 255 }
185 256
186 // log error level message. 257 // Log INFO level message.
187 func (bl *BeeLogger) Error(format string, v ...interface{}) { 258 //
188 msg := fmt.Sprintf("[E] "+format, v...) 259 // Deprecated: compatibility alias for Informational(), Will be removed in 1.5.0.
189 bl.writerMsg(LevelError, msg) 260 func (bl *BeeLogger) Info(format string, v ...interface{}) {
261 bl.Informational(format, v...)
190 } 262 }
191 263
192 // log critical level message. 264 // Log TRACE level message.
193 func (bl *BeeLogger) Critical(format string, v ...interface{}) { 265 //
194 msg := fmt.Sprintf("[C] "+format, v...) 266 // Deprecated: compatibility alias for Debug(), Will be removed in 1.5.0.
195 bl.writerMsg(LevelCritical, msg) 267 func (bl *BeeLogger) Trace(format string, v ...interface{}) {
268 bl.Debug(format, v...)
196 } 269 }
197 270
198 // flush all chan data. 271 // flush all chan data.
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
...@@ -51,22 +59,30 @@ func (s *SmtpWriter) Init(jsonconfig string) error { ...@@ -51,22 +59,30 @@ func (s *SmtpWriter) Init(jsonconfig string) error {
51 return nil 59 return nil
52 } 60 }
53 61
62 func (s *SmtpWriter) GetSmtpAuth(host string) smtp.Auth {
63 if len(strings.Trim(s.Username, " ")) == 0 && len(strings.Trim(s.Password, " ")) == 0 {
64 return nil
65 }
66 return smtp.PlainAuth(
67 "",
68 s.Username,
69 s.Password,
70 host,
71 )
72 }
73
54 // write message in smtp writer. 74 // write message in smtp writer.
55 // it will send an email with subject and only this message. 75 // it will send an email with subject and only this message.
56 func (s *SmtpWriter) WriteMsg(msg string, level int) error { 76 func (s *SmtpWriter) WriteMsg(msg string, level int) error {
57 if level < s.Level { 77 if level > s.Level {
58 return nil 78 return nil
59 } 79 }
60 80
61 hp := strings.Split(s.Host, ":") 81 hp := strings.Split(s.Host, ":")
62 82
63 // Set up authentication information. 83 // Set up authentication information.
64 auth := smtp.PlainAuth( 84 auth := s.GetSmtpAuth(hp[0])
65 "", 85
66 s.Username,
67 s.Password,
68 hp[0],
69 )
70 // Connect to the server, authenticate, set the sender and recipient, 86 // Connect to the server, authenticate, set the sender and recipient,
71 // and send the email all in one step. 87 // and send the email all in one step.
72 content_type := "Content-Type: text/plain" + "; charset=UTF-8" 88 content_type := "Content-Type: text/plain" + "; charset=UTF-8"
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package logs 15 package logs
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package beego 15 package beego
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package middleware 15 package middleware
8 16
...@@ -311,6 +319,7 @@ func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg strin ...@@ -311,6 +319,7 @@ func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg strin
311 if err != nil { 319 if err != nil {
312 isint = 500 320 isint = 500
313 } 321 }
322 w.Header().Set("Content-Type", "text/html; charset=utf-8")
314 w.WriteHeader(isint) 323 w.WriteHeader(isint)
315 h(w, r) 324 h(w, r)
316 return 325 return
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
6 14
7 package middleware 15 package middleware
8 16
......
1 // Beego (http://beego.me/) 1 // Copyright 2014 beego Author. All Rights Reserved.
2 // @description beego is an open-source, high-performance web framework for the Go programming language. 2 //
3 // @link http://github.com/astaxie/beego for the canonical source repository 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // @license http://github.com/astaxie/beego/blob/master/LICENSE 4 // you may not use this file except in compliance with the License.
5 // @authors astaxie 5 // You may obtain a copy of the License at
6 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Usage:
16 //
17 // import "github.com/astaxie/beego/middleware"
18 //
19 // I18N = middleware.NewLocale("conf/i18n.conf", beego.AppConfig.String("language"))
20 //
21 // more docs: http://beego.me/docs/module/i18n.md
7 package middleware 22 package middleware
8 23
9 //import ( 24 import (
10 // "github.com/astaxie/beego/config" 25 "encoding/json"
11 // "os" 26 "io/ioutil"
12 // "path" 27 "os"
13 //) 28 )
14 29
15 //type Translation struct { 30 type Translation struct {
16 // filetype string 31 filepath string
17 // CurrentLocal string 32 CurrentLocal string
18 // Locales map[string]map[string]string 33 Locales map[string]map[string]string
19 //} 34 }
20 35
21 //func NewLocale(filetype string) *Translation { 36 func NewLocale(filepath string, defaultlocal string) *Translation {
22 // return &Translation{ 37 i18n := make(map[string]map[string]string)
23 // filetype: filetype, 38 file, err := os.Open(filepath)
24 // CurrentLocal: "zh", 39 if err != nil {
25 // Locales: make(map[string]map[string]string), 40 panic("open " + filepath + " err :" + err.Error())
26 // } 41 }
27 //} 42 data, err := ioutil.ReadAll(file)
28 43 if err != nil {
29 //func (t *Translation) loadTranslations(dirPath string) error { 44 panic("read " + filepath + " err :" + err.Error())
30 // dir, err := os.Open(dirPath) 45 }
31 // if err != nil { 46 err = json.Unmarshal(data, &i18n)
32 // return err 47 if err != nil {
33 // } 48 panic("json.Unmarshal " + filepath + " err :" + err.Error())
34 // defer dir.Close() 49 }
35 50 return &Translation{
36 // names, err := dir.Readdirnames(-1) 51 filepath: filepath,
37 // if err != nil { 52 CurrentLocal: defaultlocal,
38 // return err 53 Locales: i18n,
39 // } 54 }
40 55 }
41 // for _, name := range names { 56
42 // fullPath := path.Join(dirPath, name) 57 func (t *Translation) SetLocale(local string) {
43 58 t.CurrentLocal = local
44 // fi, err := os.Stat(fullPath) 59 }
45 // if err != nil { 60
46 // return err 61 func (t *Translation) Translate(key string, local string) string {
47 // } 62 if local == "" {
48 63 local = t.CurrentLocal
49 // if fi.IsDir() { 64 }
50 // continue 65 if ct, ok := t.Locales[key]; ok {
51 // } else { 66 if v, o := ct[local]; o {
52 // if err := t.loadTranslation(fullPath, name); err != nil { 67 return v
53 // return err 68 }
54 // } 69 }
55 // } 70 return key
56 // } 71 }
57
58 // return nil
59 //}
60
61 //func (t *Translation) loadTranslation(fullPath, locale string) error {
62
63 // sourceKey2Trans, ok := t.Locales[locale]
64 // if !ok {
65 // sourceKey2Trans = make(map[string]string)
66
67 // t.Locales[locale] = sourceKey2Trans
68 // }
69
70 // for _, m := range trf.Messages {
71 // if m.Translation != "" {
72 // sourceKey2Trans[sourceKey(m.Source, m.Context)] = m.Translation
73 // }
74 // }
75
76 // return nil
77 //}
78
79 //func (t *Translation) SetLocale(local string) {
80 // t.CurrentLocal = local
81 //}
82
83 //func (t *Translation) Translate(key string) string {
84 // if ct, ok := t.Locales[t.CurrentLocal]; ok {
85 // if v, o := ct[key]; o {
86 // return v
87 // }
88 // }
89 // return key
90 //}
......
1 // Copyright 2014 beego Author. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // migration package for migration
16 //
17 // The table structure is as follow:
18 //
19 // CREATE TABLE `migrations` (
20 // `id_migration` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key',
21 // `name` varchar(255) DEFAULT NULL COMMENT 'migration name, unique',
22 // `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'date migrated or rolled back',
23 // `statements` longtext COMMENT 'SQL statements for this migration',
24 // `rollback_statements` longtext,
25 // `status` enum('update','rollback') DEFAULT NULL COMMENT 'update indicates it is a normal migration while rollback means this migration is rolled back',
26 // PRIMARY KEY (`id_migration`)
27 // ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
28 package migration
29
30 import (
31 "errors"
32 "sort"
33 "strings"
34 "time"
35
36 "github.com/astaxie/beego"
37 "github.com/astaxie/beego/orm"
38 )
39
40 // const the data format for the bee generate migration datatype
41 const (
42 M_DATE_FORMAT = "20060102_150405"
43 M_DB_DATE_FORMAT = "2006-01-02 15:04:05"
44 )
45
46 // Migrationer is an interface for all Migration struct
47 type Migrationer interface {
48 Up()
49 Down()
50 Reset()
51 Exec(name, status string) error
52 GetCreated() int64
53 }
54
55 var (
56 migrationMap map[string]Migrationer
57 )
58
59 func init() {
60 migrationMap = make(map[string]Migrationer)
61 }
62
63 // the basic type which will implement the basic type
64 type Migration struct {
65 sqls []string
66 Created string
67 }
68
69 // implement in the Inheritance struct for upgrade
70 func (m *Migration) Up() {
71
72 }
73
74 // implement in the Inheritance struct for down
75 func (m *Migration) Down() {
76
77 }
78
79 // add sql want to execute
80 func (m *Migration) Sql(sql string) {
81 m.sqls = append(m.sqls, sql)
82 }
83
84 // Reset the sqls
85 func (m *Migration) Reset() {
86 m.sqls = make([]string, 0)
87 }
88
89 // execute the sql already add in the sql
90 func (m *Migration) Exec(name, status string) error {
91 o := orm.NewOrm()
92 for _, s := range m.sqls {
93 beego.Info("exec sql:", s)
94 r := o.Raw(s)
95 _, err := r.Exec()
96 if err != nil {
97 return err
98 }
99 }
100 return m.addOrUpdateRecord(name, status)
101 }
102
103 func (m *Migration) addOrUpdateRecord(name, status string) error {
104 o := orm.NewOrm()
105 if status == "down" {
106 status = "rollback"
107 p, err := o.Raw("update migrations set `status` = ?, `rollback_statements` = ?, `created_at` = ? where name = ?").Prepare()
108 if err != nil {
109 return nil
110 }
111 _, err = p.Exec(status, strings.Join(m.sqls, "; "), time.Now().Format(M_DB_DATE_FORMAT), name)
112 return err
113 } else {
114 status = "update"
115 p, err := o.Raw("insert into migrations(`name`, `created_at`, `statements`, `status`) values(?,?,?,?)").Prepare()
116 if err != nil {
117 return err
118 }
119 _, err = p.Exec(name, time.Now().Format(M_DB_DATE_FORMAT), strings.Join(m.sqls, "; "), status)
120 return err
121 }
122 }
123
124 // get the unixtime from the Created
125 func (m *Migration) GetCreated() int64 {
126 t, err := time.Parse(M_DATE_FORMAT, m.Created)
127 if err != nil {
128 return 0
129 }
130 return t.Unix()
131 }
132
133 // register the Migration in the map
134 func Register(name string, m Migrationer) error {
135 if _, ok := migrationMap[name]; ok {
136 return errors.New("already exist name:" + name)
137 }
138 migrationMap[name] = m
139 return nil
140 }
141
142 // upgrate the migration from lasttime
143 func Upgrade(lasttime int64) error {
144 sm := sortMap(migrationMap)
145 i := 0
146 for _, v := range sm {
147 if v.created > lasttime {
148 beego.Info("start upgrade", v.name)
149 v.m.Reset()
150 v.m.Up()
151 err := v.m.Exec(v.name, "up")
152 if err != nil {
153 beego.Error("execute error:", err)
154 time.Sleep(2 * time.Second)
155 return err
156 }
157 beego.Info("end upgrade:", v.name)
158 i++
159 }
160 }
161 beego.Info("total success upgrade:", i, " migration")
162 time.Sleep(2 * time.Second)
163 return nil
164 }
165
166 //rollback the migration by the name
167 func Rollback(name string) error {
168 if v, ok := migrationMap[name]; ok {
169 beego.Info("start rollback")
170 v.Reset()
171 v.Down()
172 err := v.Exec(name, "down")
173 if err != nil {
174 beego.Error("execute error:", err)
175 time.Sleep(2 * time.Second)
176 return err
177 }
178 beego.Info("end rollback")
179 time.Sleep(2 * time.Second)
180 return nil
181 } else {
182 beego.Error("not exist the migrationMap name:" + name)
183 time.Sleep(2 * time.Second)
184 return errors.New("not exist the migrationMap name:" + name)
185 }
186 }
187
188 // reset all migration
189 // run all migration's down function
190 func Reset() error {
191 sm := sortMap(migrationMap)
192 i := 0
193 for j := len(sm) - 1; j >= 0; j-- {
194 v := sm[j]
195 if isRollBack(v.name) {
196 beego.Info("skip the", v.name)
197 time.Sleep(1 * time.Second)
198 continue
199 }
200 beego.Info("start reset:", v.name)
201 v.m.Reset()
202 v.m.Down()
203 err := v.m.Exec(v.name, "down")
204 if err != nil {
205 beego.Error("execute error:", err)
206 time.Sleep(2 * time.Second)
207 return err
208 }
209 i++
210 beego.Info("end reset:", v.name)
211 }
212 beego.Info("total success reset:", i, " migration")
213 time.Sleep(2 * time.Second)
214 return nil
215 }
216
217 // first Reset, then Upgrade
218 func Refresh() error {
219 err := Reset()
220 if err != nil {
221 beego.Error("execute error:", err)
222 time.Sleep(2 * time.Second)
223 return err
224 }
225 err = Upgrade(0)
226 return err
227 }
228
229 type dataSlice []data
230
231 type data struct {
232 created int64
233 name string
234 m Migrationer
235 }
236
237 // Len is part of sort.Interface.
238 func (d dataSlice) Len() int {
239 return len(d)
240 }
241
242 // Swap is part of sort.Interface.
243 func (d dataSlice) Swap(i, j int) {
244 d[i], d[j] = d[j], d[i]
245 }
246
247 // Less is part of sort.Interface. We use count as the value to sort by
248 func (d dataSlice) Less(i, j int) bool {
249 return d[i].created < d[j].created
250 }
251
252 func sortMap(m map[string]Migrationer) dataSlice {
253 s := make(dataSlice, 0, len(m))
254 for k, v := range m {
255 d := data{}
256 d.created = v.GetCreated()
257 d.name = k
258 d.m = v
259 s = append(s, d)
260 }
261 sort.Sort(s)
262 return s
263 }
264
265 func isRollBack(name string) bool {
266 o := orm.NewOrm()
267 var maps []orm.Params
268 num, err := o.Raw("select * from migrations where `name` = ? order by id_migration desc", name).Values(&maps)
269 if err != nil {
270 beego.Info("get name has error", err)
271 return false
272 }
273 if num <= 0 {
274 return false
275 }
276 if maps[0]["status"] == "rollback" {
277 return true
278 }
279 return false
280 }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!