From 3a12e238cc75ccdd9caf46bbb0e1657b18f27e1b Mon Sep 17 00:00:00 2001 From: astaxie Date: Thu, 10 Mar 2016 21:23:13 +0800 Subject: [PATCH 01/81] support oracle --- orm/db_alias.go | 3 ++- orm/db_oracle.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/orm/db_alias.go b/orm/db_alias.go index 79576b8e..b6c833a7 100644 --- a/orm/db_alias.go +++ b/orm/db_alias.go @@ -59,6 +59,7 @@ var ( "postgres": DRPostgres, "sqlite3": DRSqlite, "tidb": DRTiDB, + "oracle": DROracle, } dbBasers = map[DriverType]dbBaser{ DRMySQL: newdbBaseMysql(), @@ -151,7 +152,7 @@ func detectTZ(al *alias) { al.Engine = "INNODB" } - case DRSqlite: + case DRSqlite, DROracle: al.TZ = time.UTC case DRPostgres: diff --git a/orm/db_oracle.go b/orm/db_oracle.go index 1e385c9a..deca36ad 100644 --- a/orm/db_oracle.go +++ b/orm/db_oracle.go @@ -14,6 +14,41 @@ package orm +import ( + "fmt" + "strings" +) + +// oracle operators. +var oracleOperators = map[string]string{ + "exact": "= ?", + "gt": "> ?", + "gte": ">= ?", + "lt": "< ?", + "lte": "<= ?", + "//iendswith": "LIKE ?", +} + +// oracle column field types. +var oracleTypes = map[string]string{ + "pk": "NOT NULL PRIMARY KEY", + "bool": "bool", + "string": "VARCHAR2(%d)", + "string-text": "VARCHAR2(%d)", + "time.Time-date": "DATE", + "time.Time": "TIMESTAMP", + "int8": "INTEGER", + "int16": "INTEGER", + "int32": "INTEGER", + "int64": "INTEGER", + "uint8": "INTEGER", + "uint16": "INTEGER", + "uint32": "INTEGER", + "uint64": "INTEGER", + "float64": "NUMBER", + "float64-decimal": "NUMBER(%d, %d)", +} + // oracle dbBaser type dbBaseOracle struct { dbBase @@ -27,3 +62,35 @@ func newdbBaseOracle() dbBaser { b.ins = b return b } + +// OperatorSQL get oracle operator. +func (d *dbBaseOracle) OperatorSQL(operator string) string { + return oracleOperators[operator] +} + +// DbTypes get oracle table field types. +func (d *dbBaseOracle) DbTypes() map[string]string { + return oracleTypes +} + +//ShowTablesQuery show all the tables in database +func (d *dbBaseOracle) ShowTablesQuery() string { + return "SELECT TABLE_NAME FROM USER_TABLES" +} + +// Oracle +func (d *dbBaseOracle) ShowColumnsQuery(table string) string { + return fmt.Sprintf("SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS "+ + "WHERE TABLE_NAME ='%s'", strings.ToUpper(table)) +} + +// check index is exist +func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool { + row := db.QueryRow("SELECT COUNT(*) FROM USER_IND_COLUMNS, USER_INDEXES "+ + "WHERE USER_IND_COLUMNS.INDEX_NAME = USER_INDEXES.INDEX_NAME "+ + "AND USER_IND_COLUMNS.TABLE_NAME = ? AND USER_IND_COLUMNS.INDEX_NAME = ?", strings.ToUpper(table), strings.ToUpper(name)) + + var cnt int + row.Scan(&cnt) + return cnt > 0 +} From 31f7524dae97dbd457665fd385ca406d960691a9 Mon Sep 17 00:00:00 2001 From: astaxie Date: Thu, 10 Mar 2016 21:47:50 +0800 Subject: [PATCH 02/81] fix the golint travis --- .travis.yml | 2 +- context/context.go | 36 ++++++++++++++++++------------------ orm/models_test.go | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c821dcd..d8922fd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ after_script: - rm -rf ./res/var/* script: - go vet -x ./... - - $HOME/gopath/bin/golint ./... + - $HOME/gopath/bin/golint ./... | grep -v "should be" - go test -v ./... notifications: webhooks: https://hooks.pubu.im/services/z7m9bvybl3rgtg9 diff --git a/context/context.go b/context/context.go index 31698c85..63a1313d 100644 --- a/context/context.go +++ b/context/context.go @@ -190,34 +190,34 @@ func (r *Response) reset(rw http.ResponseWriter) { // Write writes the data to the connection as part of an HTTP reply, // and sets `started` to true. // started means the response has sent out. -func (w *Response) Write(p []byte) (int, error) { - w.Started = true - return w.ResponseWriter.Write(p) +func (r *Response) Write(p []byte) (int, error) { + r.Started = true + return r.ResponseWriter.Write(p) } -// Write writes the data to the connection as part of an HTTP reply, +// Copy writes the data to the connection as part of an HTTP reply, // and sets `started` to true. // started means the response has sent out. -func (w *Response) Copy(buf *bytes.Buffer) (int64, error) { - w.Started = true - return io.Copy(w.ResponseWriter, buf) +func (r *Response) Copy(buf *bytes.Buffer) (int64, error) { + r.Started = true + return io.Copy(r.ResponseWriter, buf) } // WriteHeader sends an HTTP response header with status code, // and sets `started` to true. -func (w *Response) WriteHeader(code int) { - if w.Status > 0 { +func (r *Response) WriteHeader(code int) { + if r.Status > 0 { //prevent multiple response.WriteHeader calls return } - w.Status = code - w.Started = true - w.ResponseWriter.WriteHeader(code) + r.Status = code + r.Started = true + r.ResponseWriter.WriteHeader(code) } // Hijack hijacker for http -func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hj, ok := w.ResponseWriter.(http.Hijacker) +func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { + hj, ok := r.ResponseWriter.(http.Hijacker) if !ok { return nil, nil, errors.New("webserver doesn't support hijacking") } @@ -225,15 +225,15 @@ func (w *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { } // Flush http.Flusher -func (w *Response) Flush() { - if f, ok := w.ResponseWriter.(http.Flusher); ok { +func (r *Response) Flush() { + if f, ok := r.ResponseWriter.(http.Flusher); ok { f.Flush() } } // CloseNotify http.CloseNotifier -func (w *Response) CloseNotify() <-chan bool { - if cn, ok := w.ResponseWriter.(http.CloseNotifier); ok { +func (r *Response) CloseNotify() <-chan bool { + if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok { return cn.CloseNotify() } return nil diff --git a/orm/models_test.go b/orm/models_test.go index 1ff4e53b..ffb16ea0 100644 --- a/orm/models_test.go +++ b/orm/models_test.go @@ -352,7 +352,7 @@ type GroupPermissions struct { } type ModelID struct { - Id int64 + ID int64 } type ModelBase struct { From 90e7d252a7ff9db0b49e9f9ec3a32d97bfe813f2 Mon Sep 17 00:00:00 2001 From: Gavin Fang Date: Thu, 10 Mar 2016 21:59:50 +0800 Subject: [PATCH 03/81] fix static pattern match for leaf --- tree.go | 2 +- tree_test.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tree.go b/tree.go index 594e9999..0601099c 100644 --- a/tree.go +++ b/tree.go @@ -389,7 +389,7 @@ type leafInfo struct { func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok bool) { //fmt.Println("Leaf:", wildcardValues, leaf.wildcards, leaf.regexps) if leaf.regexps == nil { - if len(wildcardValues) == 0 { // static path + if len(wildcardValues) == 0 && len(leaf.wildcards) == 0 { // static path return true } // match * diff --git a/tree_test.go b/tree_test.go index 531df046..81ff7edd 100644 --- a/tree_test.go +++ b/tree_test.go @@ -97,6 +97,21 @@ func TestTreeRouters(t *testing.T) { } } +func TestStaticPath(t *testing.T) { + tr := NewTree() + tr.AddRouter("/topic/:id", "wildcard") + tr.AddRouter("/topic", "static") + ctx := context.NewContext() + obj := tr.Match("/topic", ctx) + if obj == nil || obj.(string) != "static" { + t.Fatal("/topic is a static route") + } + obj = tr.Match("/topic/1", ctx) + if obj == nil || obj.(string) != "wildcard" { + t.Fatal("/topic/1 is a wildcard route") + } +} + func TestAddTree(t *testing.T) { tr := NewTree() tr.AddRouter("/shop/:id/account", "astaxie") From 1f0a65f0a2fb2e35343625a7242dbbd456e35a02 Mon Sep 17 00:00:00 2001 From: astaxie Date: Thu, 10 Mar 2016 22:21:21 +0800 Subject: [PATCH 04/81] fix the orm test --- .travis.yml | 2 +- orm/orm_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d8922fd2..3c821dcd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ after_script: - rm -rf ./res/var/* script: - go vet -x ./... - - $HOME/gopath/bin/golint ./... | grep -v "should be" + - $HOME/gopath/bin/golint ./... - go test -v ./... notifications: webhooks: https://hooks.pubu.im/services/z7m9bvybl3rgtg9 diff --git a/orm/orm_test.go b/orm/orm_test.go index f638fba4..ec0f0d3a 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -1943,7 +1943,7 @@ func TestInLine(t *testing.T) { throwFail(t, AssertIs(id, 1)) il := NewInLine() - il.Id = 1 + il.ID = 1 err = dORM.Read(il) throwFail(t, err) From 22196d78415fff13189bffc387c2545f4d9bf377 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 09:21:13 +0800 Subject: [PATCH 05/81] add mis function NSHandler --- namespace.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/namespace.go b/namespace.go index 0dfdd7af..4007d44c 100644 --- a/namespace.go +++ b/namespace.go @@ -388,3 +388,10 @@ func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace { ns.Namespace(n) } } + +// NSHandler add handler +func NSHandler(rootpath string, h http.Handler) LinkNamespace { + return func(ns *Namespace) { + ns.Handler(rootpath, h) + } +} From 420cd507b24f03b049e002707f7c84e448afba87 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 10:07:44 +0800 Subject: [PATCH 06/81] update output information --- parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser.go b/parser.go index f23f4720..46d02320 100644 --- a/parser.go +++ b/parser.go @@ -58,7 +58,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { rep := strings.NewReplacer("/", "_", ".", "_") commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go" if !compareFile(pkgRealpath) { - Info(pkgRealpath + " has not changed, not reloading") + Info(pkgRealpath + " no changed") return nil } genInfoList = make(map[string][]ControllerComments) From 4801099675f9237ecf3708879d5caa27f27f206e Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 11 Mar 2016 10:12:17 +0800 Subject: [PATCH 07/81] duplicate adapter logger bug fixed --- logs/log.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/logs/log.go b/logs/log.go index c6ba3dc3..3b3e2208 100644 --- a/logs/log.go +++ b/logs/log.go @@ -146,17 +146,25 @@ func (bl *BeeLogger) Async() *BeeLogger { func (bl *BeeLogger) SetLogger(adapterName string, config string) error { bl.lock.Lock() defer bl.lock.Unlock() - if log, ok := adapters[adapterName]; ok { - lg := log() - err := lg.Init(config) - if err != nil { - fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) - return err + + for _, l := range bl.outputs { + if l.name == adapterName { + return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName) } - bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg}) - } else { + } + + log, ok := adapters[adapterName] + if !ok { return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName) } + + lg := log() + err := lg.Init(config) + if err != nil { + fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) + return err + } + bl.outputs = append(bl.outputs, &nameLogger{name: adapterName, Logger: lg}) return nil } From 1aeb3d90512734def678c7aa9f612fe6f659e6b5 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 11:35:24 +0800 Subject: [PATCH 08/81] release 1.6.1 --- beego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beego.go b/beego.go index fb628e5f..8f82cdcf 100644 --- a/beego.go +++ b/beego.go @@ -23,7 +23,7 @@ import ( const ( // VERSION represent beego web framework version. - VERSION = "1.6.0" + VERSION = "1.6.1" // DEV is for develop DEV = "dev" From 40b41cc121bcf04af8d644e7ea6bdf40c0d81495 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 12:14:18 +0800 Subject: [PATCH 09/81] fix the misspell99 --- plugins/apiauth/apiauth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/apiauth/apiauth.go b/plugins/apiauth/apiauth.go index 8af08088..970367c9 100644 --- a/plugins/apiauth/apiauth.go +++ b/plugins/apiauth/apiauth.go @@ -35,7 +35,7 @@ // // beego.InsertFilter("*", beego.BeforeRouter,apiauth.APISecretAuth(getAppSecret, 360)) // -// Infomation: +// Information: // // In the request user should include these params in the query // From 83fe43f331fe2cb353c4d44b9dd09a50e5172180 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 13:00:58 +0800 Subject: [PATCH 10/81] gofmt -s -w --- logs/log.go | 2 +- logs/logger.go | 1 - tree.go | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/logs/log.go b/logs/log.go index 3b3e2208..a5982e45 100644 --- a/logs/log.go +++ b/logs/log.go @@ -152,7 +152,7 @@ func (bl *BeeLogger) SetLogger(adapterName string, config string) error { return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName) } } - + log, ok := adapters[adapterName] if !ok { return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adapterName) diff --git a/logs/logger.go b/logs/logger.go index 323c41c5..b25bfaef 100644 --- a/logs/logger.go +++ b/logs/logger.go @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - package logs import ( diff --git a/tree.go b/tree.go index 0601099c..25b78e50 100644 --- a/tree.go +++ b/tree.go @@ -141,7 +141,7 @@ func (t *Tree) addtree(segments []string, tree *Tree, wildcards []string, reg st regexpStr = "([^.]+).(.+)" params = params[1:] } else { - for _ = range params { + for range params { regexpStr = "([^/]+)/" + regexpStr } } @@ -254,7 +254,7 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string, regexpStr = "/([^.]+).(.+)" params = params[1:] } else { - for _ = range params { + for range params { regexpStr = "/([^/]+)" + regexpStr } } From 9872041f12cd123ecbe3cf9893607d870cba4f8e Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 11 Mar 2016 14:14:58 +0800 Subject: [PATCH 11/81] timeDur is used only when need --- router.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/router.go b/router.go index d0bf534f..e767bec5 100644 --- a/router.go +++ b/router.go @@ -802,9 +802,9 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) p.execFilter(context, FinishRouter, urlPath) Admin: - timeDur := time.Since(startTime) //admin module record QPS if BConfig.Listen.EnableAdmin { + timeDur := time.Since(startTime) if FilterMonitorFunc(r.Method, r.URL.Path, timeDur) { if runRouter != nil { go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, runRouter.Name(), timeDur) @@ -815,6 +815,7 @@ Admin: } if BConfig.RunMode == DEV || BConfig.Log.AccessLogs { + timeDur := time.Since(startTime) var devInfo string if findRouter { if routerInfo != nil { From 88816348b92863cc17109721e39e069c3209c206 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 11 Mar 2016 15:29:52 +0800 Subject: [PATCH 12/81] window console can't output colorful --- logs/console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/console.go b/logs/console.go index 05d08a42..dc41dd7d 100644 --- a/logs/console.go +++ b/logs/console.go @@ -56,7 +56,7 @@ func NewConsole() Logger { cw := &consoleWriter{ lg: newLogWriter(os.Stdout), Level: LevelDebug, - Colorful: true, + Colorful: runtime.GOOS != "windows", } return cw } From 8b0957cf2e740dd0960716fbfb2b22a7ede450c9 Mon Sep 17 00:00:00 2001 From: Simon Rawet Date: Sat, 12 Mar 2016 00:20:19 +0100 Subject: [PATCH 13/81] Fixed infinite loop in ini config adapter If parseFile recived a directory it would go into a infinit loop --- config/ini.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/ini.go b/config/ini.go index 9c19b9b1..c3934c53 100644 --- a/config/ini.go +++ b/config/ini.go @@ -82,6 +82,10 @@ func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) { if err == io.EOF { break } + //It might be a good idea to throw a error on all unknonw errors? + if _, ok := err.(*os.PathError); ok { + return nil, err + } if bytes.Equal(line, bEmpty) { continue } From d90195061f4510922e7b1811fde33d28cab89fe8 Mon Sep 17 00:00:00 2001 From: astaxie Date: Sun, 13 Mar 2016 11:16:19 +0800 Subject: [PATCH 14/81] fix #1783 --- context/context.go | 10 ---------- context/output.go | 8 +++++--- router.go | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/context/context.go b/context/context.go index 63a1313d..ab3a3d3f 100644 --- a/context/context.go +++ b/context/context.go @@ -24,13 +24,11 @@ package context import ( "bufio" - "bytes" "crypto/hmac" "crypto/sha1" "encoding/base64" "errors" "fmt" - "io" "net" "net/http" "strconv" @@ -195,14 +193,6 @@ func (r *Response) Write(p []byte) (int, error) { return r.ResponseWriter.Write(p) } -// Copy writes the data to the connection as part of an HTTP reply, -// and sets `started` to true. -// started means the response has sent out. -func (r *Response) Copy(buf *bytes.Buffer) (int64, error) { - r.Started = true - return io.Copy(r.ResponseWriter, buf) -} - // WriteHeader sends an HTTP response header with status code, // and sets `started` to true. func (r *Response) WriteHeader(code int) { diff --git a/context/output.go b/context/output.go index 17404702..ea5498c0 100644 --- a/context/output.go +++ b/context/output.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "html/template" + "io" "mime" "net/http" "path/filepath" @@ -72,10 +73,11 @@ func (output *BeegoOutput) Body(content []byte) error { if output.Status != 0 { output.Context.ResponseWriter.WriteHeader(output.Status) output.Status = 0 + } else { + output.Context.ResponseWriter.Started = true } - - _, err := output.Context.ResponseWriter.Copy(buf) - return err + io.Copy(output.Context.ResponseWriter, buf) + return nil } // Cookie sets cookie value via given key. diff --git a/router.go b/router.go index d0bf534f..5d0e1970 100644 --- a/router.go +++ b/router.go @@ -783,7 +783,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if !context.ResponseWriter.Started && context.Output.Status == 0 { if BConfig.WebConfig.AutoRender { if err := execController.Render(); err != nil { - panic(err) + Error(err) } } } From dcfcb2789e2481fdb2269fddc25201aaf9d6566a Mon Sep 17 00:00:00 2001 From: miraclesu Date: Sun, 13 Mar 2016 21:01:56 +0800 Subject: [PATCH 15/81] orm: inline struct relate test case --- orm/models_test.go | 12 ++++++++++++ orm/orm_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/orm/models_test.go b/orm/models_test.go index ffb16ea0..4c8d32f8 100644 --- a/orm/models_test.go +++ b/orm/models_test.go @@ -375,6 +375,18 @@ func NewInLine() *InLine { return new(InLine) } +type InLineOneToOne struct { + // Common Fields + ModelBase + + Note string + InLine *InLine `orm:"rel(fk);column(inline)"` +} + +func NewInLineOneToOne() *InLineOneToOne { + return new(InLineOneToOne) +} + var DBARGS = struct { Driver string Source string diff --git a/orm/orm_test.go b/orm/orm_test.go index ec0f0d3a..181106bb 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -188,6 +188,7 @@ func TestSyncDb(t *testing.T) { RegisterModel(new(Permission)) RegisterModel(new(GroupPermissions)) RegisterModel(new(InLine)) + RegisterModel(new(InLineOneToOne)) err := RunSyncdb("default", true, Debug) throwFail(t, err) @@ -208,6 +209,7 @@ func TestRegisterModels(t *testing.T) { RegisterModel(new(Permission)) RegisterModel(new(GroupPermissions)) RegisterModel(new(InLine)) + RegisterModel(new(InLineOneToOne)) BootStrap() @@ -1952,3 +1954,40 @@ func TestInLine(t *testing.T) { throwFail(t, AssertIs(il.Created.In(DefaultTimeLoc), inline.Created.In(DefaultTimeLoc), testDate)) throwFail(t, AssertIs(il.Updated.In(DefaultTimeLoc), inline.Updated.In(DefaultTimeLoc), testDateTime)) } + +func TestInLineOneToOne(t *testing.T) { + name := "121" + email := "121@go.com" + inline := NewInLine() + inline.Name = name + inline.Email = email + + id, err := dORM.Insert(inline) + throwFail(t, err) + throwFail(t, AssertIs(id, 2)) + + note := "one2one" + il121 := NewInLineOneToOne() + il121.Note = note + il121.InLine = inline + _, err = dORM.Insert(il121) + throwFail(t, err) + throwFail(t, AssertIs(il121.ID, 1)) + + il := NewInLineOneToOne() + err = dORM.QueryTable(il).Filter("Id", 1).RelatedSel().One(il) + + throwFail(t, err) + throwFail(t, AssertIs(il.Note, note)) + throwFail(t, AssertIs(il.InLine.ID, id)) + throwFail(t, AssertIs(il.InLine.Name, name)) + throwFail(t, AssertIs(il.InLine.Email, email)) + + rinline := NewInLine() + err = dORM.QueryTable(rinline).Filter("InLineOneToOne__Id", 1).One(rinline) + + throwFail(t, err) + throwFail(t, AssertIs(rinline.ID, id)) + throwFail(t, AssertIs(rinline.Name, name)) + throwFail(t, AssertIs(rinline.Email, email)) +} From 9aa2e5b575ba23b57130ab0a849cd1bf4dae90a3 Mon Sep 17 00:00:00 2001 From: youngsterxyf Date: Sun, 13 Mar 2016 21:39:26 +0800 Subject: [PATCH 16/81] =?UTF-8?q?fix=20issue#1787:=20The=20cause=20is=20th?= =?UTF-8?q?at=20if=20the=20url=20is=20/m=EF=BC=8Cand=20we=20set=20beego.BC?= =?UTF-8?q?onfig.WebConfig.DirectoryIndex=20=3D=20true,=20then=20it=20shou?= =?UTF-8?q?ld=20redirect=20to=20/m/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- staticfile.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/staticfile.go b/staticfile.go index 0aad2c81..1cd75b8c 100644 --- a/staticfile.go +++ b/staticfile.go @@ -54,8 +54,13 @@ func serverStaticRouter(ctx *context.Context) { return } if fileInfo.IsDir() { - //serveFile will list dir - http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath) + requestURL := ctx.Input.URL() + if requestURL[len(requestURL)-1] != '/' { + ctx.Redirect(302, requestURL+"/") + } else { + //serveFile will list dir + http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath) + } return } From c92c3fc8b512b1a9ae6107a6351ba076d5acdba5 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 11 Mar 2016 14:45:39 +0800 Subject: [PATCH 17/81] make the BeegoLogger a adapter of http server ErrorLog --- app.go | 2 ++ logs/log.go | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index af54ea4b..a065670a 100644 --- a/app.go +++ b/app.go @@ -16,6 +16,7 @@ package beego import ( "fmt" + "log" "net" "net/http" "net/http/fcgi" @@ -95,6 +96,7 @@ func (app *App) Run() { app.Server.Handler = app.Handlers app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second + app.Server.ErrorLog = log.New(BeeLogger, "", 0) // run graceful mode if BConfig.Listen.Graceful { diff --git a/logs/log.go b/logs/log.go index a5982e45..583b35e0 100644 --- a/logs/log.go +++ b/logs/log.go @@ -196,6 +196,22 @@ func (bl *BeeLogger) writeToLoggers(when time.Time, msg string, level int) { } } +func (bl *BeeLogger) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + // writeMsg will always add a '\n' character + if p[len(p)-1] == '\n' { + p = p[0 : len(p)-1] + } + // set LevelCritical to ensure all log message will be write out + err = bl.writeMsg(LevelCritical, string(p)) + if err == nil { + return len(p), err + } + return 0, err +} + func (bl *BeeLogger) writeMsg(logLevel int, msg string) error { when := time.Now() if bl.enableFuncCallDepth { @@ -205,7 +221,7 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string) error { line = 0 } _, filename := path.Split(file) - msg = "[" + filename + ":" + strconv.FormatInt(int64(line), 10) + "]" + msg + msg = "[" + filename + ":" + strconv.FormatInt(int64(line), 10) + "] " + msg } if bl.asynchronous { lm := logMsgPool.Get().(*logMsg) From 549a39c4787afe9ab377d3373a271f94da3ba33a Mon Sep 17 00:00:00 2001 From: youngsterxyf Date: Mon, 14 Mar 2016 11:26:26 +0800 Subject: [PATCH 18/81] fix issue1789: when testing, load config explicitly and forcibly --- beego.go | 1 + config.go | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/beego.go b/beego.go index 8f82cdcf..a6074d22 100644 --- a/beego.go +++ b/beego.go @@ -87,5 +87,6 @@ func TestBeegoInit(ap string) { os.Setenv("BEEGO_RUNMODE", "test") appConfigPath = filepath.Join(ap, "conf", "app.conf") os.Chdir(ap) + LoadAppConfig(appConfigProvider, appConfigPath) initBeforeHTTPRun() } diff --git a/config.go b/config.go index 2761e7cb..0d4df95c 100644 --- a/config.go +++ b/config.go @@ -316,10 +316,6 @@ func LoadAppConfig(adapterName, configPath string) error { return fmt.Errorf("the target config file: %s don't exist", configPath) } - if absConfigPath == appConfigPath { - return nil - } - appConfigPath = absConfigPath appConfigProvider = adapterName From 8660a54facfff34b6f6297921fbe4808c8a7e8bc Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 15 Mar 2016 11:49:23 +0800 Subject: [PATCH 19/81] make router fast --- admin.go | 2 +- namespace.go | 4 ++-- router.go | 55 +++++++++++++++++++++++++--------------------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/admin.go b/admin.go index 031e6421..cf5bc63a 100644 --- a/admin.go +++ b/admin.go @@ -196,7 +196,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) { BeforeExec: "Before Exec", AfterExec: "After Exec", FinishRouter: "Finish Router"} { - if bf, ok := BeeApp.Handlers.filters[k]; ok { + if bf := BeeApp.Handlers.filters[k]; len(bf) > 0 { filterType = fr filterTypes = append(filterTypes, filterType) resultList := new([][]string) diff --git a/namespace.go b/namespace.go index 4007d44c..cfde0111 100644 --- a/namespace.go +++ b/namespace.go @@ -44,7 +44,7 @@ func NewNamespace(prefix string, params ...LinkNamespace) *Namespace { return ns } -// Cond set condtion function +// Cond set condition function // if cond return true can run this namespace, else can't // usage: // ns.Cond(func (ctx *context.Context) bool{ @@ -60,7 +60,7 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace { exception("405", ctx) } } - if v, ok := n.handlers.filters[BeforeRouter]; ok { + if v := n.handlers.filters[BeforeRouter]; len(v) > 0 { mr := new(FilterRouter) mr.tree = NewTree() mr.pattern = "*" diff --git a/router.go b/router.go index 5b4b1ff9..597acbb9 100644 --- a/router.go +++ b/router.go @@ -114,7 +114,7 @@ type controllerInfo struct { type ControllerRegister struct { routers map[string]*Tree enableFilter bool - filters map[int][]*FilterRouter + filters [5][]*FilterRouter pool sync.Pool } @@ -122,7 +122,6 @@ type ControllerRegister struct { func NewControllerRegister() *ControllerRegister { cr := &ControllerRegister{ routers: make(map[string]*Tree), - filters: make(map[int][]*FilterRouter), } cr.pool.New = func() interface{} { return beecontext.NewContext() @@ -408,7 +407,6 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) // InsertFilter Add a FilterFunc with pattern rule and action constant. // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error { - mr := new(FilterRouter) mr.tree = NewTree() mr.pattern = pattern @@ -426,9 +424,13 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter } // add Filter into -func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) error { - p.filters[pos] = append(p.filters[pos], mr) +func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) { + if pos < BeforeStatic || pos > FinishRouter { + err = fmt.Errorf("can not find your filter postion") + return + } p.enableFilter = true + p.filters[pos] = append(p.filters[pos], mr) return nil } @@ -577,20 +579,16 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin return false, "" } -func (p *ControllerRegister) execFilter(context *beecontext.Context, pos int, urlPath string) (started bool) { - if p.enableFilter { - if l, ok := p.filters[pos]; ok { - for _, filterR := range l { - if filterR.returnOnOutput && context.ResponseWriter.Started { - return true - } - if ok := filterR.ValidRouter(urlPath, context); ok { - filterR.filterFunc(context) - } - if filterR.returnOnOutput && context.ResponseWriter.Started { - return true - } - } +func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, l []*FilterRouter) (started bool) { + for _, filterR := range l { + if filterR.returnOnOutput && context.ResponseWriter.Started { + return true + } + if ok := filterR.ValidRouter(urlPath, context); ok { + filterR.filterFunc(context) + } + if filterR.returnOnOutput && context.ResponseWriter.Started { + return true } } return false @@ -617,11 +615,10 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) context.Output.Header("Server", BConfig.ServerName) } - var urlPath string + var urlPath = r.URL.Path + if !BConfig.RouterCaseSensitive { urlPath = strings.ToLower(r.URL.Path) - } else { - urlPath = r.URL.Path } // filter wrong http method @@ -631,7 +628,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } // filter for static file - if p.execFilter(context, BeforeStatic, urlPath) { + if fs := p.filters[BeforeStatic]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { goto Admin } @@ -663,8 +660,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } }() } - - if p.execFilter(context, BeforeRouter, urlPath) { + if fs := p.filters[BeforeRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { goto Admin } @@ -693,7 +689,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if findRouter { //execute middleware filters - if p.execFilter(context, BeforeExec, urlPath) { + if fs := p.filters[BeforeExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { goto Admin } isRunnable := false @@ -794,12 +790,13 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } //execute middleware filters - if p.execFilter(context, AfterExec, urlPath) { + if fs := p.filters[AfterExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { goto Admin } } - - p.execFilter(context, FinishRouter, urlPath) + if fs := p.filters[FinishRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + goto Admin + } Admin: //admin module record QPS From c51bc86d3fd0dc38596017f8869b0bb2ff2b6733 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 15 Mar 2016 16:51:21 +0800 Subject: [PATCH 20/81] goto bug fixed --- router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router.go b/router.go index 597acbb9..9b62c4cc 100644 --- a/router.go +++ b/router.go @@ -652,7 +652,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if err != nil { Error(err) exception("503", context) - return + goto Admin } defer func() { if context.Input.CruSession != nil { From 34615ee8fcbb485574b181bd2bf9be86e3a97e87 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 15 Mar 2016 18:37:54 +0800 Subject: [PATCH 21/81] add router filter enable flag --- router.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/router.go b/router.go index 9b62c4cc..9e75e013 100644 --- a/router.go +++ b/router.go @@ -114,7 +114,8 @@ type controllerInfo struct { type ControllerRegister struct { routers map[string]*Tree enableFilter bool - filters [5][]*FilterRouter + filters [FinishRouter + 1][]*FilterRouter + filterFlag [FinishRouter + 1]bool pool sync.Pool } @@ -430,6 +431,7 @@ func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err return } p.enableFilter = true + p.filterFlag[pos] = true p.filters[pos] = append(p.filters[pos], mr) return nil } @@ -579,8 +581,8 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin return false, "" } -func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, l []*FilterRouter) (started bool) { - for _, filterR := range l { +func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, pos int) (started bool) { + for _, filterR := range p.filters[pos] { if filterR.returnOnOutput && context.ResponseWriter.Started { return true } @@ -628,11 +630,12 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } // filter for static file - if fs := p.filters[BeforeStatic]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + if p.filterFlag[BeforeStatic] && p.execFilter(context, urlPath, BeforeStatic) { goto Admin } serverStaticRouter(context) + if context.ResponseWriter.Started { findRouter = true goto Admin @@ -660,7 +663,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } }() } - if fs := p.filters[BeforeRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + if p.filterFlag[BeforeRouter] && p.execFilter(context, urlPath, BeforeRouter) { goto Admin } @@ -689,7 +692,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if findRouter { //execute middleware filters - if fs := p.filters[BeforeExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + if p.filterFlag[BeforeExec] && p.execFilter(context, urlPath, BeforeExec) { goto Admin } isRunnable := false @@ -790,11 +793,11 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } //execute middleware filters - if fs := p.filters[AfterExec]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + if p.filterFlag[AfterExec] && p.execFilter(context, urlPath, AfterExec) { goto Admin } } - if fs := p.filters[FinishRouter]; len(fs) > 0 && p.execFilter(context, urlPath, fs) { + if p.filterFlag[FinishRouter] && p.execFilter(context, urlPath, FinishRouter) { goto Admin } From 565c4a4d592cf196610a3759d88b00822c87fef8 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 15 Mar 2016 18:50:18 +0800 Subject: [PATCH 22/81] make the code run more fast --- router.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/router.go b/router.go index 9e75e013..0da56464 100644 --- a/router.go +++ b/router.go @@ -115,7 +115,6 @@ type ControllerRegister struct { routers map[string]*Tree enableFilter bool filters [FinishRouter + 1][]*FilterRouter - filterFlag [FinishRouter + 1]bool pool sync.Pool } @@ -431,7 +430,6 @@ func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err return } p.enableFilter = true - p.filterFlag[pos] = true p.filters[pos] = append(p.filters[pos], mr) return nil } @@ -630,7 +628,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } // filter for static file - if p.filterFlag[BeforeStatic] && p.execFilter(context, urlPath, BeforeStatic) { + if len(p.filters[BeforeStatic]) > 0 && p.execFilter(context, urlPath, BeforeStatic) { goto Admin } @@ -663,7 +661,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } }() } - if p.filterFlag[BeforeRouter] && p.execFilter(context, urlPath, BeforeRouter) { + if len(p.filters[BeforeRouter]) > 0 && p.execFilter(context, urlPath, BeforeRouter) { goto Admin } @@ -692,7 +690,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if findRouter { //execute middleware filters - if p.filterFlag[BeforeExec] && p.execFilter(context, urlPath, BeforeExec) { + if len(p.filters[BeforeExec]) > 0 && p.execFilter(context, urlPath, BeforeExec) { goto Admin } isRunnable := false @@ -793,11 +791,11 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } //execute middleware filters - if p.filterFlag[AfterExec] && p.execFilter(context, urlPath, AfterExec) { + if len(p.filters[AfterExec]) > 0 && p.execFilter(context, urlPath, AfterExec) { goto Admin } } - if p.filterFlag[FinishRouter] && p.execFilter(context, urlPath, FinishRouter) { + if len(p.filters[FinishRouter]) > 0 && p.execFilter(context, urlPath, FinishRouter) { goto Admin } From 94599013fc8a932de20bba7ce2fce91f61634c16 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 16 Mar 2016 07:53:36 +0800 Subject: [PATCH 23/81] url to lower case --- router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router.go b/router.go index 0da56464..71be4c16 100644 --- a/router.go +++ b/router.go @@ -618,7 +618,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) var urlPath = r.URL.Path if !BConfig.RouterCaseSensitive { - urlPath = strings.ToLower(r.URL.Path) + urlPath = strings.ToLower(urlPath) } // filter wrong http method From 2b1316c73826c8bfdbe34fa194f18770930599af Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 16 Mar 2016 18:04:07 +0800 Subject: [PATCH 24/81] data race bug fixed --- logs/file.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/logs/file.go b/logs/file.go index 9d3f78a0..672823fa 100644 --- a/logs/file.go +++ b/logs/file.go @@ -30,7 +30,7 @@ import ( // fileLogWriter implements LoggerInterface. // It writes messages by lines limit, file size limit, or time frequency. type fileLogWriter struct { - sync.Mutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize + sync.RWMutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize // The opened file Filename string `json:"filename"` fileWriter *os.File @@ -77,7 +77,7 @@ func newFileWriter() Logger { // { // "filename":"logs/beego.log", // "maxLines":10000, -// "maxsize":1<<30, +// "maxsize":1024, // "daily":true, // "maxDays":15, // "rotate":true, @@ -128,7 +128,9 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { h, d := formatTimeHeader(when) msg = string(h) + msg + "\n" if w.Rotate { + w.RLock() if w.needRotate(len(msg), d) { + w.RUnlock() w.Lock() if w.needRotate(len(msg), d) { if err := w.doRotate(when); err != nil { @@ -136,6 +138,8 @@ func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error { } } w.Unlock() + } else { + w.RUnlock() } } From ec35bd0c28aecbba2d6e26f049166b76f264e542 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 16 Mar 2016 18:04:27 +0800 Subject: [PATCH 25/81] orm log header flag --- orm/orm_log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orm/orm_log.go b/orm/orm_log.go index 712eb219..54723273 100644 --- a/orm/orm_log.go +++ b/orm/orm_log.go @@ -31,7 +31,7 @@ type Log struct { // NewLog set io.Writer to create a Logger. func NewLog(out io.Writer) *Log { d := new(Log) - d.Logger = log.New(out, "[ORM]", 1e9) + d.Logger = log.New(out, "[ORM]", log.LstdFlags) return d } From 443d71397cd33f8b18c7fc82b7b372bdf5b36539 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 09:35:14 +0800 Subject: [PATCH 26/81] write error to response --- error.go | 208 +++++++++++++++++++++++++------------------------------ 1 file changed, 94 insertions(+), 114 deletions(-) diff --git a/error.go b/error.go index 4f48fab2..6488fc6c 100644 --- a/error.go +++ b/error.go @@ -210,159 +210,139 @@ var ErrorMaps = make(map[string]*errorInfo, 10) // show 401 unauthorized error. func unauthorized(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(401), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested can't be authorized." + - "
Perhaps you are here because:" + - "

    " + - "
    The credentials you supplied are incorrect" + - "
    There are errors in the website address" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 401, + "
The page you have requested can't be authorized."+ + "
Perhaps you are here because:"+ + "

    "+ + "
    The credentials you supplied are incorrect"+ + "
    There are errors in the website address"+ + "
", + ) } // show 402 Payment Required func paymentRequired(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(402), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested Payment Required." + - "
Perhaps you are here because:" + - "

    " + - "
    The credentials you supplied are incorrect" + - "
    There are errors in the website address" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 402, + "
The page you have requested Payment Required."+ + "
Perhaps you are here because:"+ + "

    "+ + "
    The credentials you supplied are incorrect"+ + "
    There are errors in the website address"+ + "
", + ) } // show 403 forbidden error. func forbidden(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(403), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested is forbidden." + - "
Perhaps you are here because:" + - "

    " + - "
    Your address may be blocked" + - "
    The site may be disabled" + - "
    You need to log in" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 403, + "
The page you have requested is forbidden."+ + "
Perhaps you are here because:"+ + "

    "+ + "
    Your address may be blocked"+ + "
    The site may be disabled"+ + "
    You need to log in"+ + "
", + ) } -// show 404 notfound error. +// show 404 not found error. func notFound(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(404), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested has flown the coop." + - "
Perhaps you are here because:" + - "

    " + - "
    The page has moved" + - "
    The page no longer exists" + - "
    You were looking for your puppy and got lost" + - "
    You like 404 pages" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 404, + "
The page you have requested has flown the coop."+ + "
Perhaps you are here because:"+ + "

    "+ + "
    The page has moved"+ + "
    The page no longer exists"+ + "
    You were looking for your puppy and got lost"+ + "
    You like 404 pages"+ + "
", + ) } // show 405 Method Not Allowed func methodNotAllowed(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(405), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The method you have requested Not Allowed." + - "
Perhaps you are here because:" + - "

    " + - "
    The method specified in the Request-Line is not allowed for the resource identified by the Request-URI" + - "
    The response MUST include an Allow header containing a list of valid methods for the requested resource." + - "
") - t.Execute(rw, data) + responseError(rw, r, + 405, + "
The method you have requested Not Allowed."+ + "
Perhaps you are here because:"+ + "

    "+ + "
    The method specified in the Request-Line is not allowed for the resource identified by the Request-URI"+ + "
    The response MUST include an Allow header containing a list of valid methods for the requested resource."+ + "
", + ) } // show 500 internal server error. func internalServerError(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(500), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested is down right now." + - "

    " + - "
    Please try again later and report the error to the website administrator" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 500, + "
The page you have requested is down right now."+ + "

    "+ + "
    Please try again later and report the error to the website administrator"+ + "
", + ) } // show 501 Not Implemented. func notImplemented(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(504), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested is Not Implemented." + - "

    " + - "
    Please try again later and report the error to the website administrator" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 501, + "
The page you have requested is Not Implemented."+ + "

    "+ + "
    Please try again later and report the error to the website administrator"+ + "
", + ) } // show 502 Bad Gateway. func badGateway(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(502), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested is down right now." + - "

    " + - "
    The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request." + - "
    Please try again later and report the error to the website administrator" + - "
") - t.Execute(rw, data) + responseError(rw, r, + 502, + "
The page you have requested is down right now."+ + "

    "+ + "
    The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request."+ + "
    Please try again later and report the error to the website administrator"+ + "
", + ) } // show 503 service unavailable error. func serviceUnavailable(rw http.ResponseWriter, r *http.Request) { - t, _ := template.New("beegoerrortemp").Parse(errtpl) - data := map[string]interface{}{ - "Title": http.StatusText(503), - "BeegoVersion": VERSION, - } - data["Content"] = template.HTML("
The page you have requested is unavailable." + - "
Perhaps you are here because:" + - "

    " + - "

    The page is overloaded" + - "
    Please try again later." + - "
") - t.Execute(rw, data) + responseError(rw, r, + 503, + "
The page you have requested is unavailable."+ + "
Perhaps you are here because:"+ + "

    "+ + "

    The page is overloaded"+ + "
    Please try again later."+ + "
", + ) } // show 504 Gateway Timeout. func gatewayTimeout(rw http.ResponseWriter, r *http.Request) { + responseError(rw, r, + 504, + "
The page you have requested is unavailable"+ + "
Perhaps you are here because:"+ + "

    "+ + "

    The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI."+ + "
    Please try again later."+ + "
", + ) +} + +func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) { t, _ := template.New("beegoerrortemp").Parse(errtpl) data := map[string]interface{}{ - "Title": http.StatusText(504), + "Title": http.StatusText(errCode), "BeegoVersion": VERSION, + "Content": errContent, } - data["Content"] = template.HTML("
The page you have requested is unavailable." + - "
Perhaps you are here because:" + - "

    " + - "

    The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI." + - "
    Please try again later." + - "
") t.Execute(rw, data) } From 0859ec570cba6327faf6881efc2eff2a136ced79 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 09:46:34 +0800 Subject: [PATCH 27/81] refactor of error response and fix err code bug --- controller.go | 3 ++- error.go | 5 ++++- router.go | 37 ++++++++++++++++++------------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/controller.go b/controller.go index 85894275..9d265758 100644 --- a/controller.go +++ b/controller.go @@ -261,12 +261,13 @@ func (c *Controller) Abort(code string) { // CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body. func (c *Controller) CustomAbort(status int, body string) { - c.Ctx.Output.Status = status // first panic from ErrorMaps, is is user defined error functions. if _, ok := ErrorMaps[body]; ok { + c.Ctx.Output.Status = status panic(body) } // last panic user string + c.Ctx.ResponseWriter.WriteHeader(status) c.Ctx.ResponseWriter.Write([]byte(body)) panic(ErrAbort) } diff --git a/error.go b/error.go index 6488fc6c..8cfa0c67 100644 --- a/error.go +++ b/error.go @@ -388,7 +388,10 @@ func exception(errCode string, ctx *context.Context) { if err == nil { return v } - return 503 + if ctx.Output.Status == 0 { + return 503 + } + return ctx.Output.Status } for _, ec := range []string{errCode, "503", "500"} { diff --git a/router.go b/router.go index 5b4b1ff9..99780b5c 100644 --- a/router.go +++ b/router.go @@ -844,27 +844,26 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) { } if !BConfig.RecoverPanic { panic(err) - } else { - if BConfig.EnableErrorsShow { - if _, ok := ErrorMaps[fmt.Sprint(err)]; ok { - exception(fmt.Sprint(err), context) - return - } + } + if BConfig.EnableErrorsShow { + if _, ok := ErrorMaps[fmt.Sprint(err)]; ok { + exception(fmt.Sprint(err), context) + return } - var stack string - Critical("the request url is ", context.Input.URL()) - Critical("Handler crashed with error", err) - for i := 1; ; i++ { - _, file, line, ok := runtime.Caller(i) - if !ok { - break - } - Critical(fmt.Sprintf("%s:%d", file, line)) - stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line)) - } - if BConfig.RunMode == DEV { - showErr(err, context, stack) + } + var stack string + Critical("the request url is ", context.Input.URL()) + Critical("Handler crashed with error", err) + for i := 1; ; i++ { + _, file, line, ok := runtime.Caller(i) + if !ok { + break } + Critical(fmt.Sprintf("%s:%d", file, line)) + stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line)) + } + if BConfig.RunMode == DEV { + showErr(err, context, stack) } } } From 48147f50d8e65838938adeffb239de45da4f91aa Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 19:09:21 +0800 Subject: [PATCH 28/81] add some gzip future --- context/acceptencoder.go | 93 ++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index 033d9ca8..2e5af83a 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -25,8 +25,35 @@ import ( "strconv" "strings" "sync" + + "github.com/astaxie/beego/config" ) +var ( +//Content will only be compressed if content length is either unknown or greater than minGzipSize. + gzipMinLength int +//Default size==20B like nginx + defaultGzipMinLength=20 +//The compression level used for deflate compression. (0-9). + gzipCompressLevel int +//List of HTTP methods to compress. If not set, only GET requests are compressed. + includedMethods map[string]bool + getMethodOnly bool +) + +func InitGzip(cf config.Configer) { + gzipMinLength = cf.DefaultInt("gzipMinLength", defaultGzipMinLength) + gzipCompressLevel = cf.DefaultInt("gzipCompressLevel", flate.DefaultCompression) + if gzipCompressLevel < flate.DefaultCompression || gzipCompressLevel > flate.BestCompression { + gzipCompressLevel = flate.BestSpeed + } + methods := cf.DefaultStrings("includedMethods", []string{"GET"}) + getMethodOnly = len(methods) == 1 && strings.ToUpper(methods[0]) == "GET" + for _, v := range methods { + includedMethods[strings.ToUpper(v)] = true + } +} + type resetWriter interface { io.Writer Reset(w io.Writer) @@ -41,20 +68,20 @@ func (n nopResetWriter) Reset(w io.Writer) { } type acceptEncoder struct { - name string - levelEncode func(int) resetWriter - bestSpeedPool *sync.Pool - bestCompressionPool *sync.Pool + name string + levelEncode func(int) resetWriter + customCompressLevelPool *sync.Pool + bestCompressionPool *sync.Pool } func (ac acceptEncoder) encode(wr io.Writer, level int) resetWriter { - if ac.bestSpeedPool == nil || ac.bestCompressionPool == nil { + if ac.customCompressLevelPool == nil || ac.bestCompressionPool == nil { return nopResetWriter{wr} } var rwr resetWriter switch level { case flate.BestSpeed: - rwr = ac.bestSpeedPool.Get().(resetWriter) + rwr = ac.customCompressLevelPool.Get().(resetWriter) case flate.BestCompression: rwr = ac.bestCompressionPool.Get().(resetWriter) default: @@ -65,13 +92,16 @@ func (ac acceptEncoder) encode(wr io.Writer, level int) resetWriter { } func (ac acceptEncoder) put(wr resetWriter, level int) { - if ac.bestSpeedPool == nil || ac.bestCompressionPool == nil { + if ac.customCompressLevelPool == nil || ac.bestCompressionPool == nil { return } wr.Reset(nil) + //notice + //compressionLevel==BestCompression DOES NOT MATTER + //sync.Pool will not memory leak switch level { - case flate.BestSpeed: - ac.bestSpeedPool.Put(wr) + case gzipCompressLevel: + ac.customCompressLevelPool.Put(wr) case flate.BestCompression: ac.bestCompressionPool.Put(wr) } @@ -79,28 +109,22 @@ func (ac acceptEncoder) put(wr resetWriter, level int) { var ( noneCompressEncoder = acceptEncoder{"", nil, nil, nil} - gzipCompressEncoder = acceptEncoder{"gzip", - func(level int) resetWriter { wr, _ := gzip.NewWriterLevel(nil, level); return wr }, - &sync.Pool{ - New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestSpeed); return wr }, - }, - &sync.Pool{ - New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }, - }, + gzipCompressEncoder = acceptEncoder{ + name: "gzip", + levelEncode: func(level int) resetWriter { wr, _ := gzip.NewWriterLevel(nil, level); return wr }, + customCompressLevelPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, gzipCompressLevel); return wr }}, + bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }}, } - //according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed - //deflate - //The "zlib" format defined in RFC 1950 [31] in combination with - //the "deflate" compression mechanism described in RFC 1951 [29]. - deflateCompressEncoder = acceptEncoder{"deflate", - func(level int) resetWriter { wr, _ := zlib.NewWriterLevel(nil, level); return wr }, - &sync.Pool{ - New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, flate.BestSpeed); return wr }, - }, - &sync.Pool{ - New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, flate.BestCompression); return wr }, - }, +//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed +//deflate +//The "zlib" format defined in RFC 1950 [31] in combination with +//the "deflate" compression mechanism described in RFC 1951 [29]. + deflateCompressEncoder = acceptEncoder{ + name: "deflate", + levelEncode: func(level int) resetWriter { wr, _ := zlib.NewWriterLevel(nil, level); return wr }, + customCompressLevelPool: &sync.Pool{New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, gzipCompressLevel); return wr }}, + bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, flate.BestCompression); return wr }}, } ) @@ -120,7 +144,11 @@ func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, // WriteBody reads writes content to writer by the specific encoding(gzip/deflate) func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, error) { - return writeLevel(encoding, writer, bytes.NewReader(content), flate.BestSpeed) + if encoding == "" || len(content) < gzipMinLength { + _, err := writer.Write(content) + return false, "", err + } + return writeLevel(encoding, writer, bytes.NewReader(content), gzipCompressLevel) } // writeLevel reads from reader,writes to writer by specific encoding and compress level @@ -156,7 +184,10 @@ func ParseEncoding(r *http.Request) string { if r == nil { return "" } - return parseEncoding(r) + if (getMethodOnly && r.Method == "GET") || includedMethods[r.Method] { + return parseEncoding(r) + } + return "" } type q struct { From 5a9bff2000701fd565027c184cfa010c7c820592 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 19:09:38 +0800 Subject: [PATCH 29/81] init gzip level --- beego.go | 8 +++++--- hooks.go | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/beego.go b/beego.go index 8f82cdcf..89e4f671 100644 --- a/beego.go +++ b/beego.go @@ -22,12 +22,12 @@ import ( ) const ( - // VERSION represent beego web framework version. +// VERSION represent beego web framework version. VERSION = "1.6.1" - // DEV is for develop +// DEV is for develop DEV = "dev" - // PROD is for production +// PROD is for production PROD = "prod" ) @@ -51,6 +51,7 @@ func AddAPPStartHook(hf hookfunc) { // beego.Run(":8089") // beego.Run("127.0.0.1:8089") func Run(params ...string) { + initBeforeHTTPRun() if len(params) > 0 && params[0] != "" { @@ -74,6 +75,7 @@ func initBeforeHTTPRun() { AddAPPStartHook(registerDocs) AddAPPStartHook(registerTemplate) AddAPPStartHook(registerAdmin) + AddAPPStartHook(registerGzip) for _, hk := range hooks { if err := hk(); err != nil { diff --git a/hooks.go b/hooks.go index 59b10b32..1a7937b5 100644 --- a/hooks.go +++ b/hooks.go @@ -6,6 +6,7 @@ import ( "net/http" "path/filepath" + "github.com/astaxie/beego/context" "github.com/astaxie/beego/session" ) @@ -91,3 +92,10 @@ func registerAdmin() error { } return nil } + +func registerGzip() error { + if BConfig.EnableGzip { + context.InitGzip(AppConfig) + } + return nil +} From 35e34261abd45205becb700e302c7a5972c98fa1 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 19:40:29 +0800 Subject: [PATCH 30/81] gzip method support --- context/acceptencoder.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index 2e5af83a..21ede1a5 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -30,13 +30,13 @@ import ( ) var ( -//Content will only be compressed if content length is either unknown or greater than minGzipSize. + //Content will only be compressed if content length is either unknown or greater than minGzipSize. gzipMinLength int -//Default size==20B like nginx - defaultGzipMinLength=20 -//The compression level used for deflate compression. (0-9). + //Default size==20B like nginx + defaultGzipMinLength = 20 + //The compression level used for deflate compression. (0-9). gzipCompressLevel int -//List of HTTP methods to compress. If not set, only GET requests are compressed. + //List of HTTP methods to compress. If not set, only GET requests are compressed. includedMethods map[string]bool getMethodOnly bool ) @@ -96,9 +96,11 @@ func (ac acceptEncoder) put(wr resetWriter, level int) { return } wr.Reset(nil) + //notice //compressionLevel==BestCompression DOES NOT MATTER //sync.Pool will not memory leak + switch level { case gzipCompressLevel: ac.customCompressLevelPool.Put(wr) @@ -116,10 +118,10 @@ var ( bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }}, } -//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed -//deflate -//The "zlib" format defined in RFC 1950 [31] in combination with -//the "deflate" compression mechanism described in RFC 1951 [29]. + //according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed + //deflate + //The "zlib" format defined in RFC 1950 [31] in combination with + //the "deflate" compression mechanism described in RFC 1951 [29]. deflateCompressEncoder = acceptEncoder{ name: "deflate", levelEncode: func(level int) resetWriter { wr, _ := zlib.NewWriterLevel(nil, level); return wr }, From 57eace07a79f80aaeab7b0d06058a8e81ee05af3 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 19:52:09 +0800 Subject: [PATCH 31/81] comment update --- context/acceptencoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index 21ede1a5..bc67bb5e 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -30,7 +30,7 @@ import ( ) var ( - //Content will only be compressed if content length is either unknown or greater than minGzipSize. + //Content will only be compressed if content length is either unknown or greater than gzipMinLength. gzipMinLength int //Default size==20B like nginx defaultGzipMinLength = 20 From 0b401481ef1c9abc920996d6cbe67818970984bf Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 19:59:48 +0800 Subject: [PATCH 32/81] go fmt the comment --- beego.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/beego.go b/beego.go index 89e4f671..65dd79cb 100644 --- a/beego.go +++ b/beego.go @@ -22,12 +22,12 @@ import ( ) const ( -// VERSION represent beego web framework version. + // VERSION represent beego web framework version. VERSION = "1.6.1" -// DEV is for develop + // DEV is for develop DEV = "dev" -// PROD is for production + // PROD is for production PROD = "prod" ) From 9f21928a90e6782e92cfc26462d66223557b680d Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 17 Mar 2016 20:07:24 +0800 Subject: [PATCH 33/81] some typo fixed --- context/acceptencoder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index bc67bb5e..bc048e77 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -32,7 +32,7 @@ import ( var ( //Content will only be compressed if content length is either unknown or greater than gzipMinLength. gzipMinLength int - //Default size==20B like nginx + //Default size==20B same as nginx defaultGzipMinLength = 20 //The compression level used for deflate compression. (0-9). gzipCompressLevel int @@ -43,7 +43,7 @@ var ( func InitGzip(cf config.Configer) { gzipMinLength = cf.DefaultInt("gzipMinLength", defaultGzipMinLength) - gzipCompressLevel = cf.DefaultInt("gzipCompressLevel", flate.DefaultCompression) + gzipCompressLevel = cf.DefaultInt("gzipCompressLevel", flate.BestSpeed) if gzipCompressLevel < flate.DefaultCompression || gzipCompressLevel > flate.BestCompression { gzipCompressLevel = flate.BestSpeed } From a3d4218d9df28355dcfd0b1042e8dfae4615d97c Mon Sep 17 00:00:00 2001 From: miraclesu Date: Thu, 17 Mar 2016 21:34:49 +0800 Subject: [PATCH 34/81] orm: fix miss pk when pk is negative --- orm/db.go | 8 ++++---- orm/db_utils.go | 4 ++-- orm/models_fields.go | 8 ++++---- orm/orm.go | 2 +- orm/orm_object.go | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/orm/db.go b/orm/db.go index 314c3535..9ff84411 100644 --- a/orm/db.go +++ b/orm/db.go @@ -181,7 +181,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val } default: switch { - case fi.fieldType&IsPostiveIntegerField > 0: + case fi.fieldType&IsPositiveIntegerField > 0: if field.Kind() == reflect.Ptr { if field.IsNil() { value = nil @@ -516,7 +516,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. } if num > 0 { if mi.fields.pk.auto { - if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { + if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 { ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(0) } else { ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(0) @@ -1140,7 +1140,7 @@ setValue: tErr = err goto end } - if fieldType&IsPostiveIntegerField > 0 { + if fieldType&IsPositiveIntegerField > 0 { v, _ := str.Uint64() value = v } else { @@ -1292,7 +1292,7 @@ setValue: field.Set(reflect.ValueOf(&v)) } case fieldType&IsIntegerField > 0: - if fieldType&IsPostiveIntegerField > 0 { + if fieldType&IsPositiveIntegerField > 0 { if isNative { if value == nil { value = uint64(0) diff --git a/orm/db_utils.go b/orm/db_utils.go index c97caf36..ff36b286 100644 --- a/orm/db_utils.go +++ b/orm/db_utils.go @@ -33,13 +33,13 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac fi := mi.fields.pk v := ind.FieldByIndex(fi.fieldIndex) - if fi.fieldType&IsPostiveIntegerField > 0 { + if fi.fieldType&IsPositiveIntegerField > 0 { vu := v.Uint() exist = vu > 0 value = vu } else if fi.fieldType&IsIntegerField > 0 { vu := v.Int() - exist = vu > 0 + exist = true value = vu } else { vu := v.String() diff --git a/orm/models_fields.go b/orm/models_fields.go index a8cf8e4f..ad1fb6f9 100644 --- a/orm/models_fields.go +++ b/orm/models_fields.go @@ -46,10 +46,10 @@ const ( // Define some logic enum const ( - IsIntegerField = ^-TypePositiveBigIntegerField >> 4 << 5 - IsPostiveIntegerField = ^-TypePositiveBigIntegerField >> 8 << 9 - IsRelField = ^-RelReverseMany >> 14 << 15 - IsFieldType = ^-RelReverseMany<<1 + 1 + IsIntegerField = ^-TypePositiveBigIntegerField >> 4 << 5 + IsPositiveIntegerField = ^-TypePositiveBigIntegerField >> 8 << 9 + IsRelField = ^-RelReverseMany >> 14 << 15 + IsFieldType = ^-RelReverseMany<<1 + 1 ) // BooleanField A true/false field. diff --git a/orm/orm.go b/orm/orm.go index 0ffb6b86..38c89334 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -159,7 +159,7 @@ func (o *orm) Insert(md interface{}) (int64, error) { // set auto pk field func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { if mi.fields.pk.auto { - if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { + if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 { ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id)) } else { ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(id) diff --git a/orm/orm_object.go b/orm/orm_object.go index 8a5d85e2..de3181ce 100644 --- a/orm/orm_object.go +++ b/orm/orm_object.go @@ -50,7 +50,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) { } if id > 0 { if o.mi.fields.pk.auto { - if o.mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { + if o.mi.fields.pk.fieldType&IsPositiveIntegerField > 0 { ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetUint(uint64(id)) } else { ind.FieldByIndex(o.mi.fields.pk.fieldIndex).SetInt(id) From 4caf044be2e7b18d52a6c525c7d5d209ed7d987a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 18 Mar 2016 15:18:00 +0800 Subject: [PATCH 35/81] getMethodOnly assign fixed --- context/acceptencoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index bc048e77..e73744f5 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -48,7 +48,7 @@ func InitGzip(cf config.Configer) { gzipCompressLevel = flate.BestSpeed } methods := cf.DefaultStrings("includedMethods", []string{"GET"}) - getMethodOnly = len(methods) == 1 && strings.ToUpper(methods[0]) == "GET" + getMethodOnly = (len(methods) == 0) || (len(methods) == 1 && strings.ToUpper(methods[0]) == "GET") for _, v := range methods { includedMethods[strings.ToUpper(v)] = true } From 84ae930c6490b1aa9b62ae7a6591ab859c6f150f Mon Sep 17 00:00:00 2001 From: miraclesu Date: Fri, 18 Mar 2016 21:58:11 +0800 Subject: [PATCH 36/81] orm: Add test case for integer pk --- orm/models_test.go | 5 +++++ orm/orm_test.go | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/orm/models_test.go b/orm/models_test.go index 4c8d32f8..b6ae21cf 100644 --- a/orm/models_test.go +++ b/orm/models_test.go @@ -387,6 +387,11 @@ func NewInLineOneToOne() *InLineOneToOne { return new(InLineOneToOne) } +type IntegerPk struct { + Id int64 `orm:"pk"` + Value string +} + var DBARGS = struct { Driver string Source string diff --git a/orm/orm_test.go b/orm/orm_test.go index 181106bb..832c7301 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -19,6 +19,7 @@ import ( "database/sql" "fmt" "io/ioutil" + "math" "os" "path/filepath" "reflect" @@ -189,6 +190,7 @@ func TestSyncDb(t *testing.T) { RegisterModel(new(GroupPermissions)) RegisterModel(new(InLine)) RegisterModel(new(InLineOneToOne)) + RegisterModel(new(IntegerPk)) err := RunSyncdb("default", true, Debug) throwFail(t, err) @@ -210,6 +212,7 @@ func TestRegisterModels(t *testing.T) { RegisterModel(new(GroupPermissions)) RegisterModel(new(InLine)) RegisterModel(new(InLineOneToOne)) + RegisterModel(new(IntegerPk)) BootStrap() @@ -1991,3 +1994,22 @@ func TestInLineOneToOne(t *testing.T) { throwFail(t, AssertIs(rinline.Name, name)) throwFail(t, AssertIs(rinline.Email, email)) } + +func TestIntegerPk(t *testing.T) { + its := []IntegerPk{ + {Id: math.MinInt64, Value: "-"}, + {Id: 0, Value: "0"}, + {Id: math.MaxInt64, Value: "+"}, + } + + num, err := dORM.InsertMulti(len(its), its) + throwFail(t, err) + throwFail(t, AssertIs(num, len(its))) + + for _, intPk := range its { + out := IntegerPk{Id: intPk.Id} + err = dORM.Read(&out) + throwFail(t, err) + throwFail(t, AssertIs(out.Value, intPk.Value)) + } +} From 33ae75b25197ee6f678b07a7d8970985c2e39510 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 21 Mar 2016 08:50:56 +0800 Subject: [PATCH 37/81] golint check only works on Go 1.5 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c821dcd..fbcb8a24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ before_install: - cd ssdb - make - cd .. + - '[[ $(go version) == *1.[5-9]* ]] && go get github.com/golang/lint/golint' install: - go get github.com/lib/pq - go get github.com/go-sql-driver/mysql @@ -32,7 +33,6 @@ install: - go get github.com/siddontang/ledisdb/config - go get github.com/siddontang/ledisdb/ledis - go get golang.org/x/tools/cmd/vet - - go get github.com/golang/lint/golint - go get github.com/ssdb/gossdb/ssdb before_script: - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" @@ -45,7 +45,7 @@ after_script: - rm -rf ./res/var/* script: - go vet -x ./... - - $HOME/gopath/bin/golint ./... + - '[[ $(go version) == *1.[5-9]* ]] && $HOME/gopath/bin/golint ./...' - go test -v ./... notifications: webhooks: https://hooks.pubu.im/services/z7m9bvybl3rgtg9 From 959b9a5a580e2e232b92680f640b1865bf3af24d Mon Sep 17 00:00:00 2001 From: JessonChan Date: Mon, 21 Mar 2016 09:32:41 +0800 Subject: [PATCH 38/81] config index out of range bug fixed --- config.go | 2 +- context/acceptencoder.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config.go b/config.go index 2761e7cb..15d11386 100644 --- a/config.go +++ b/config.go @@ -353,7 +353,7 @@ func (b *beegoAppConfig) String(key string) string { } func (b *beegoAppConfig) Strings(key string) []string { - if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); v[0] != "" { + if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 { return v } return b.innerConfig.Strings(key) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index e73744f5..fc2775ce 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -49,6 +49,7 @@ func InitGzip(cf config.Configer) { } methods := cf.DefaultStrings("includedMethods", []string{"GET"}) getMethodOnly = (len(methods) == 0) || (len(methods) == 1 && strings.ToUpper(methods[0]) == "GET") + includedMethods = make(map[string]bool, len(methods)) for _, v := range methods { includedMethods[strings.ToUpper(v)] = true } From f2ed27cc8f6aabcc779009e1c670d1154df89afa Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 21 Mar 2016 11:10:57 +0800 Subject: [PATCH 39/81] make sure works for travis --- .travis.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index fbcb8a24..d01dc3a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,8 @@ language: go go: - - tip - - 1.6.0 + - 1.6 - 1.5.3 - - 1.4.3 services: - redis-server - mysql @@ -19,7 +17,6 @@ before_install: - cd ssdb - make - cd .. - - '[[ $(go version) == *1.[5-9]* ]] && go get github.com/golang/lint/golint' install: - go get github.com/lib/pq - go get github.com/go-sql-driver/mysql @@ -34,6 +31,7 @@ install: - go get github.com/siddontang/ledisdb/ledis - go get golang.org/x/tools/cmd/vet - go get github.com/ssdb/gossdb/ssdb + - go get github.com/golang/lint/golint before_script: - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" @@ -45,7 +43,5 @@ after_script: - rm -rf ./res/var/* script: - go vet -x ./... - - '[[ $(go version) == *1.[5-9]* ]] && $HOME/gopath/bin/golint ./...' + - golint ./...' - go test -v ./... -notifications: - webhooks: https://hooks.pubu.im/services/z7m9bvybl3rgtg9 From 630f77bca34c353a713ea6c7d5a475ec41129907 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 21 Mar 2016 11:18:38 +0800 Subject: [PATCH 40/81] update travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d01dc3a9..92d9ac8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: go go: - 1.6 - 1.5.3 + - 1.4.3 services: - redis-server - mysql @@ -31,11 +32,11 @@ install: - go get github.com/siddontang/ledisdb/ledis - go get golang.org/x/tools/cmd/vet - go get github.com/ssdb/gossdb/ssdb - - go get github.com/golang/lint/golint before_script: - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi" + - sh -c "if [ $(go version) == *1.[5-9]* ]; then go get github.com/golang/lint/golint; golint ./...; fi" - mkdir -p res/var - ./ssdb/ssdb-server ./ssdb/ssdb.conf -d after_script: @@ -43,5 +44,4 @@ after_script: - rm -rf ./res/var/* script: - go vet -x ./... - - golint ./...' - go test -v ./... From 4db78f243e90b1eab3c4b78b6fb186ad0d18cbec Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Mar 2016 16:42:42 +0800 Subject: [PATCH 41/81] change the function args of init gzip method --- context/acceptencoder.go | 15 +++++++-------- hooks.go | 6 +++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index fc2775ce..1c3cf1d5 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -25,15 +25,13 @@ import ( "strconv" "strings" "sync" - - "github.com/astaxie/beego/config" ) var ( - //Content will only be compressed if content length is either unknown or greater than gzipMinLength. - gzipMinLength int //Default size==20B same as nginx defaultGzipMinLength = 20 + //Content will only be compressed if content length is either unknown or greater than gzipMinLength. + gzipMinLength = defaultGzipMinLength //The compression level used for deflate compression. (0-9). gzipCompressLevel int //List of HTTP methods to compress. If not set, only GET requests are compressed. @@ -41,13 +39,14 @@ var ( getMethodOnly bool ) -func InitGzip(cf config.Configer) { - gzipMinLength = cf.DefaultInt("gzipMinLength", defaultGzipMinLength) - gzipCompressLevel = cf.DefaultInt("gzipCompressLevel", flate.BestSpeed) +func InitGzip(minLength, compressLevel int, methods []string) { + if minLength >= 0 { + gzipMinLength = minLength + } + gzipCompressLevel = compressLevel if gzipCompressLevel < flate.DefaultCompression || gzipCompressLevel > flate.BestCompression { gzipCompressLevel = flate.BestSpeed } - methods := cf.DefaultStrings("includedMethods", []string{"GET"}) getMethodOnly = (len(methods) == 0) || (len(methods) == 1 && strings.ToUpper(methods[0]) == "GET") includedMethods = make(map[string]bool, len(methods)) for _, v := range methods { diff --git a/hooks.go b/hooks.go index 1a7937b5..674f2858 100644 --- a/hooks.go +++ b/hooks.go @@ -95,7 +95,11 @@ func registerAdmin() error { func registerGzip() error { if BConfig.EnableGzip { - context.InitGzip(AppConfig) + context.InitGzip( + AppConfig.DefaultInt("gzipMinLength", -1), + AppConfig.DefaultInt("gzipCompressLevel", -1), + AppConfig.DefaultStrings("includedMethods", []string{"GET"}), + ) } return nil } From 7bad3d1c67f8d3da1ef12071e48e31c2d82f8095 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Mar 2016 16:47:11 +0800 Subject: [PATCH 42/81] change the compress leve to [0~9] --- context/acceptencoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/context/acceptencoder.go b/context/acceptencoder.go index 1c3cf1d5..cb735445 100644 --- a/context/acceptencoder.go +++ b/context/acceptencoder.go @@ -44,7 +44,7 @@ func InitGzip(minLength, compressLevel int, methods []string) { gzipMinLength = minLength } gzipCompressLevel = compressLevel - if gzipCompressLevel < flate.DefaultCompression || gzipCompressLevel > flate.BestCompression { + if gzipCompressLevel < flate.NoCompression || gzipCompressLevel > flate.BestCompression { gzipCompressLevel = flate.BestSpeed } getMethodOnly = (len(methods) == 0) || (len(methods) == 1 && strings.ToUpper(methods[0]) == "GET") From b2098266a30d58acfffb4542c090eb173783828b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Mar 2016 18:27:29 +0800 Subject: [PATCH 43/81] add error test --- context/context.go | 1 + error_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 error_test.go diff --git a/context/context.go b/context/context.go index ab3a3d3f..fee5e1c5 100644 --- a/context/context.go +++ b/context/context.go @@ -77,6 +77,7 @@ func (ctx *Context) Redirect(status int, localurl string) { // Abort stops this request. // if beego.ErrorMaps exists, panic body. func (ctx *Context) Abort(status int, body string) { + ctx.Output.SetStatus(status) panic(body) } diff --git a/error_test.go b/error_test.go new file mode 100644 index 00000000..85b6268d --- /dev/null +++ b/error_test.go @@ -0,0 +1,73 @@ +package beego + +import ( + "net/http" + "net/http/httptest" + "strconv" + "strings" + "testing" +) + +type errorTestController struct { + Controller +} + +func (ec *errorTestController) Get() { + errorCode, err := ec.GetInt("code") + if err != nil { + ec.Abort("parse code error") + } + if errorCode != 0 { + ec.CustomAbort(errorCode, ec.GetString("code")) + } + ec.Abort("404") +} + +func TestErrorCode_01(t *testing.T) { + registerDefaultErrorHandler() + for k, _ := range ErrorMaps { + r, _ := http.NewRequest("GET", "/error?code="+k, nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.Add("/error", &errorTestController{}) + handler.ServeHTTP(w, r) + code, _ := strconv.Atoi(k) + if w.Code != code { + t.Fail() + } + if !strings.Contains(string(w.Body.Bytes()), http.StatusText(code)) { + t.Fail() + } + } +} + +func TestErrorCode_02(t *testing.T) { + registerDefaultErrorHandler() + r, _ := http.NewRequest("GET", "/error?code=0", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.Add("/error", &errorTestController{}) + handler.ServeHTTP(w, r) + if w.Code != 404 { + t.Fail() + + } +} + +func TestErrorCode_03(t *testing.T) { + registerDefaultErrorHandler() + r, _ := http.NewRequest("GET", "/error?code=crash", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegister() + handler.Add("/error", &errorTestController{}) + handler.ServeHTTP(w, r) + if w.Code != 200 { + t.Fail() + } + if string(w.Body.Bytes()) != "parse code error" { + t.Fail() + } +} From 1a401af23bd9f5e3e005216abbda8de8966b2846 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Mar 2016 18:28:44 +0800 Subject: [PATCH 44/81] copyright --- error_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/error_test.go b/error_test.go index 85b6268d..713c0a45 100644 --- a/error_test.go +++ b/error_test.go @@ -1,3 +1,17 @@ +// Copyright 2016 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package beego import ( From 5858607f49000b095506a46255653f586714df5c Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Mar 2016 18:32:14 +0800 Subject: [PATCH 45/81] go fmt error_test.go --- error_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/error_test.go b/error_test.go index 713c0a45..f6e40c80 100644 --- a/error_test.go +++ b/error_test.go @@ -26,10 +26,12 @@ type errorTestController struct { Controller } +const parseCodeError = "parse code error" + func (ec *errorTestController) Get() { errorCode, err := ec.GetInt("code") if err != nil { - ec.Abort("parse code error") + ec.Abort(parseCodeError) } if errorCode != 0 { ec.CustomAbort(errorCode, ec.GetString("code")) @@ -66,13 +68,12 @@ func TestErrorCode_02(t *testing.T) { handler.ServeHTTP(w, r) if w.Code != 404 { t.Fail() - } } func TestErrorCode_03(t *testing.T) { registerDefaultErrorHandler() - r, _ := http.NewRequest("GET", "/error?code=crash", nil) + r, _ := http.NewRequest("GET", "/error?code=panic", nil) w := httptest.NewRecorder() handler := NewControllerRegister() @@ -81,7 +82,7 @@ func TestErrorCode_03(t *testing.T) { if w.Code != 200 { t.Fail() } - if string(w.Body.Bytes()) != "parse code error" { + if string(w.Body.Bytes()) != parseCodeError { t.Fail() } } From b78de2b44092b5582240bef4ead42f6e7dcc6208 Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 23 Mar 2016 16:56:40 +0800 Subject: [PATCH 46/81] add ISSUE_TEMPLATE --- .github/ISSUE_TEMPLATE | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 00000000..b11d6e23 --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,18 @@ +Please answer these questions before submitting your issue. Thanks! + +1. What version of Go and beego are you using (`bee version`)? + + +2. What operating system and processor architecture are you using (`go env`)? + + +3. What did you do? +If possible, provide a recipe for reproducing the error. +A complete runnable program is good. +A link on play.golang.org is best. + + +4. What did you expect to see? + + +5. What did you see instead? \ No newline at end of file From 88c5dfa6ead42e624c2e7d9e04eab6cb2d07412a Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 23 Mar 2016 17:05:40 +0800 Subject: [PATCH 47/81] update issue template --- .github/ISSUE_TEMPLATE | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index b11d6e23..db349198 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -9,7 +9,6 @@ Please answer these questions before submitting your issue. Thanks! 3. What did you do? If possible, provide a recipe for reproducing the error. A complete runnable program is good. -A link on play.golang.org is best. 4. What did you expect to see? From 1786b16e61c8763b6ad5f6ff478652182bcb621c Mon Sep 17 00:00:00 2001 From: miraclesu Date: Wed, 23 Mar 2016 20:13:38 +0800 Subject: [PATCH 48/81] orm: support insert a specified value to auto field --- orm/db.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/orm/db.go b/orm/db.go index 9ff84411..af05e686 100644 --- a/orm/db.go +++ b/orm/db.go @@ -72,11 +72,11 @@ var _ dbBaser = new(dbBase) // get struct columns values as interface slice. func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, skipAuto bool, insert bool, names *[]string, tz *time.Location) (values []interface{}, err error) { - var columns []string - - if names != nil { - columns = *names + if names == nil { + ns := make([]string, 0, len(cols)) + names = &ns } + values = make([]interface{}, 0, len(cols)) for _, column := range cols { var fi *fieldInfo @@ -93,15 +93,20 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, return nil, err } - if names != nil { - columns = append(columns, column) + // ignore empty value auto field + if fi.auto { + if fi.fieldType&IsPositiveIntegerField > 0 { + if vu, ok := value.(uint64); !ok || vu == 0 { + continue + } + } else { + if vu, ok := value.(int64); !ok || vu == 0 { + continue + } + } } - values = append(values, value) - } - - if names != nil { - *names = columns + *names, values = append(*names, column), append(values, value) } return @@ -349,8 +354,8 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo // execute insert sql dbQuerier with given struct reflect.Value. func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { - names := make([]string, 0, len(mi.fields.dbcols)-1) - values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz) + names := make([]string, 0, len(mi.fields.dbcols)) + values, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) if err != nil { return 0, err } From 8f70df6c7b6218b5627cc838074e3eb94a9c2fc6 Mon Sep 17 00:00:00 2001 From: miraclesu Date: Wed, 23 Mar 2016 20:28:22 +0800 Subject: [PATCH 49/81] orm: add test case for insert specified value to auto field --- orm/orm_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/orm/orm_test.go b/orm/orm_test.go index 832c7301..5ae9a0a4 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2013,3 +2013,24 @@ func TestIntegerPk(t *testing.T) { throwFail(t, AssertIs(out.Value, intPk.Value)) } } + +func TestInsertAuto(t *testing.T) { + u := &User{ + UserName: "autoPre", + Email: "autoPre@gmail.com", + } + + id, err := dORM.Insert(u) + throwFail(t, err) + + id += 100 + su := &User{ + ID: int(id), + UserName: "auto", + Email: "auto@gmail.com", + } + + sid, err := dORM.Insert(su) + throwFail(t, err) + throwFail(t, AssertIs(id, sid)) +} From 1eab11ca900538d85e2af0260e1ba70e22721d0b Mon Sep 17 00:00:00 2001 From: ysqi Date: Wed, 23 Mar 2016 21:27:28 +0800 Subject: [PATCH 50/81] fixed #1815 check file before download --- context/output.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/context/output.go b/context/output.go index ea5498c0..0de3085c 100644 --- a/context/output.go +++ b/context/output.go @@ -24,6 +24,7 @@ import ( "io" "mime" "net/http" + "os" "path/filepath" "strconv" "strings" @@ -237,6 +238,13 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error { // Download forces response for download file. // it prepares the download response header automatically. func (output *BeegoOutput) Download(file string, filename ...string) { + + // check get file error, file not found or other error. + if _, err := os.Stat(file); err != nil { + http.ServeFile(output.Context.ResponseWriter, output.Context.Request, file) + return + } + output.Header("Content-Description", "File Transfer") output.Header("Content-Type", "application/octet-stream") if len(filename) > 0 && filename[0] != "" { From 3be6688cd1f8b178f2e7f80e67f7e50d81b53b61 Mon Sep 17 00:00:00 2001 From: miraclesu Date: Wed, 23 Mar 2016 21:18:54 +0800 Subject: [PATCH 51/81] orm: fix painc when pk is uint on ReadOrCreate --- orm/orm.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/orm/orm.go b/orm/orm.go index 38c89334..26ebb7c1 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -140,7 +140,14 @@ func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, i return (err == nil), id, err } - return false, ind.FieldByIndex(mi.fields.pk.fieldIndex).Int(), err + id, vid := int64(0), ind.FieldByIndex(mi.fields.pk.fieldIndex) + if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { + id = int64(vid.Uint()) + } else { + id = vid.Int() + } + + return false, id, err } // insert model data to database From eaf38bb09605106db60365efdfa70a6ac873419d Mon Sep 17 00:00:00 2001 From: miraclesu Date: Wed, 23 Mar 2016 21:32:52 +0800 Subject: [PATCH 52/81] orm: add test case for uint pk read or create --- orm/models_test.go | 5 +++++ orm/orm.go | 2 +- orm/orm_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/orm/models_test.go b/orm/models_test.go index b6ae21cf..f42d725e 100644 --- a/orm/models_test.go +++ b/orm/models_test.go @@ -392,6 +392,11 @@ type IntegerPk struct { Value string } +type UintPk struct { + Id uint32 `orm:"pk"` + Name string +} + var DBARGS = struct { Driver string Source string diff --git a/orm/orm.go b/orm/orm.go index 26ebb7c1..6f4b7731 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -141,7 +141,7 @@ func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, i } id, vid := int64(0), ind.FieldByIndex(mi.fields.pk.fieldIndex) - if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { + if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 { id = int64(vid.Uint()) } else { id = vid.Int() diff --git a/orm/orm_test.go b/orm/orm_test.go index 832c7301..0c827c2a 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -191,6 +191,7 @@ func TestSyncDb(t *testing.T) { RegisterModel(new(InLine)) RegisterModel(new(InLineOneToOne)) RegisterModel(new(IntegerPk)) + RegisterModel(new(UintPk)) err := RunSyncdb("default", true, Debug) throwFail(t, err) @@ -213,6 +214,7 @@ func TestRegisterModels(t *testing.T) { RegisterModel(new(InLine)) RegisterModel(new(InLineOneToOne)) RegisterModel(new(IntegerPk)) + RegisterModel(new(UintPk)) BootStrap() @@ -2013,3 +2015,26 @@ func TestIntegerPk(t *testing.T) { throwFail(t, AssertIs(out.Value, intPk.Value)) } } + +func TestUintPk(t *testing.T) { + name := "go" + u := &UintPk{ + Id: 8, + Name: name, + } + + created, pk, err := dORM.ReadOrCreate(u, "Id") + throwFail(t, err) + throwFail(t, AssertIs(created, true)) + throwFail(t, AssertIs(u.Name, name)) + + nu := &UintPk{Id: 8} + created, pk, err = dORM.ReadOrCreate(nu, "Id") + throwFail(t, err) + throwFail(t, AssertIs(created, false)) + throwFail(t, AssertIs(nu.Id, u.Id)) + throwFail(t, AssertIs(pk, u.Id)) + throwFail(t, AssertIs(nu.Name, name)) + + dORM.Delete(u) +} From b7d1afbf86117a5e85dcddf390ef62d3c850f854 Mon Sep 17 00:00:00 2001 From: YuShuangqi Date: Thu, 24 Mar 2016 08:35:42 +0800 Subject: [PATCH 53/81] Remote empty line --- context/output.go | 1 - 1 file changed, 1 deletion(-) diff --git a/context/output.go b/context/output.go index 0de3085c..3568d89c 100644 --- a/context/output.go +++ b/context/output.go @@ -238,7 +238,6 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error { // Download forces response for download file. // it prepares the download response header automatically. func (output *BeegoOutput) Download(file string, filename ...string) { - // check get file error, file not found or other error. if _, err := os.Stat(file); err != nil { http.ServeFile(output.Context.ResponseWriter, output.Context.Request, file) From 2e6a23743b73cd514411c0c647dbdb6acfd9753b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:37:56 +0800 Subject: [PATCH 54/81] refactor logs package --- logs/log.go | 178 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 167 insertions(+), 11 deletions(-) diff --git a/logs/log.go b/logs/log.go index 583b35e0..1ec7dd1d 100644 --- a/logs/log.go +++ b/logs/log.go @@ -35,10 +35,12 @@ package logs import ( "fmt" + "log" "os" "path" "runtime" "strconv" + "strings" "sync" "time" ) @@ -55,6 +57,15 @@ const ( LevelDebug ) +const ( + AdapterConsole = "console" + AdapterFile = "file" + AdapterMultiFile = "multifile" + AdapterMail = "stmp" + AdapterConn = "conn" + AdaterEs = "es" +) + // Legacy loglevel constants to ensure backwards compatibility. // // Deprecated: will be removed in 1.5.0. @@ -94,6 +105,7 @@ func Register(name string, log loggerType) { type BeeLogger struct { lock sync.Mutex level int + msgChanLen int64 enableFuncCallDepth bool loggerFuncCallDepth int asynchronous bool @@ -119,11 +131,14 @@ var logMsgPool *sync.Pool // NewLogger returns a new BeeLogger. // channelLen means the number of messages in chan(used where asynchronous is true). // if the buffering chan is full, logger adapters write to file or other way. -func NewLogger(channelLen int64) *BeeLogger { +func NewLogger(channelLens ...int64) *BeeLogger { bl := new(BeeLogger) bl.level = LevelDebug bl.loggerFuncCallDepth = 2 - bl.msgChan = make(chan *logMsg, channelLen) + bl.msgChanLen = append(channelLens, 0)[0] + if bl.msgChanLen < 0 { + bl.msgChanLen = 0 + } bl.signalChan = make(chan string, 1) return bl } @@ -131,6 +146,7 @@ func NewLogger(channelLen int64) *BeeLogger { // Async set the log to asynchronous and start the goroutine func (bl *BeeLogger) Async() *BeeLogger { bl.asynchronous = true + bl.msgChan = make(chan *logMsg, bl.msgChanLen) logMsgPool = &sync.Pool{ New: func() interface{} { return &logMsg{} @@ -143,7 +159,8 @@ func (bl *BeeLogger) Async() *BeeLogger { // SetLogger provides a given logger adapter into BeeLogger with config string. // config need to be correct JSON as string: {"interval":360}. -func (bl *BeeLogger) SetLogger(adapterName string, config string) error { +func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error { + config := append(configs, "{}")[0] bl.lock.Lock() defer bl.lock.Unlock() @@ -402,6 +419,7 @@ func (bl *BeeLogger) Close() { if bl.asynchronous { bl.signalChan <- "close" bl.wg.Wait() + close(bl.msgChan) } else { bl.flush() for _, l := range bl.outputs { @@ -409,7 +427,6 @@ func (bl *BeeLogger) Close() { } bl.outputs = nil } - close(bl.msgChan) close(bl.signalChan) } @@ -423,16 +440,155 @@ func (bl *BeeLogger) Reset() { } func (bl *BeeLogger) flush() { - for { - if len(bl.msgChan) > 0 { - bm := <-bl.msgChan - bl.writeToLoggers(bm.when, bm.msg, bm.level) - logMsgPool.Put(bm) - continue + if bl.asynchronous { + for { + if len(bl.msgChan) > 0 { + bm := <-bl.msgChan + bl.writeToLoggers(bm.when, bm.msg, bm.level) + logMsgPool.Put(bm) + continue + } + break } - break } for _, l := range bl.outputs { l.Flush() } } + +// BeeLogger references the used application logger. +var beeLogger = NewLogger(100) + +// GetLogger returns the default BeeLogger +func GetBeeLogger() *BeeLogger { + return beeLogger +} + +var beeLoggerMap = struct { + sync.RWMutex + logs map[string]*log.Logger +}{ + logs: map[string]*log.Logger{}, +} + +// GetLogger returns the default BeeLogger +func GetLogger(prefixes ...string) *log.Logger { + prefix := append(prefixes, "")[0] + if prefix != "" { + prefix = fmt.Sprintf(`[%s] `, prefix) + } + beeLoggerMap.RLock() + l, ok := beeLoggerMap.logs[prefix] + if ok { + beeLoggerMap.RUnlock() + return l + } + beeLoggerMap.RUnlock() + beeLoggerMap.Lock() + defer beeLoggerMap.Unlock() + l, ok = beeLoggerMap.logs[prefix] + if !ok { + l = log.New(beeLogger, prefix, 0) + beeLoggerMap.logs[prefix] = l + } + return l +} + +// Reset will remove all the adapter +func Reset() { + beeLogger.Reset() +} + +// SetLevel sets the global log level used by the simple logger. +func SetLevel(l int) { + beeLogger.SetLevel(l) +} + +// SetLogFuncCall set the CallDepth, default is 3 +func SetLogFuncCall(b bool) { + beeLogger.EnableFuncCallDepth(b) + beeLogger.SetLogFuncCallDepth(3) +} + +// SetLogger sets a new logger. +func SetLogger(adaptername string, config string) error { + err := beeLogger.SetLogger(adaptername, config) + if err != nil { + return err + } + return nil +} + +// Emergency logs a message at emergency level. +func Emergency(f interface{}, v ...interface{}) { + beeLogger.Emergency(logf(f, v...)) +} + +// Alert logs a message at alert level. +func Alert(f interface{}, v ...interface{}) { + beeLogger.Alert(logf(f, v...)) +} + +// Critical logs a message at critical level. +func Critical(f interface{}, v ...interface{}) { + beeLogger.Critical(logf(f, v...)) +} + +// Error logs a message at error level. +func Error(f interface{}, v ...interface{}) { + beeLogger.Error(logf(f, v...)) +} + +// Warning logs a message at warning level. +func Warning(f interface{}, v ...interface{}) { + beeLogger.Warning(logf(f, v...)) +} + +// Warn compatibility alias for Warning() +func Warn(f interface{}, v ...interface{}) { + beeLogger.Warn(logf(f, v...)) +} + +// Notice logs a message at notice level. +func Notice(f interface{}, v ...interface{}) { + beeLogger.Notice(logf(f, v...)) +} + +// Informational logs a message at info level. +func Informational(f interface{}, v ...interface{}) { + beeLogger.Informational(logf(f, v...)) +} + +// Info compatibility alias for Warning() +func Info(f interface{}, v ...interface{}) { + fmt.Print() + beeLogger.Info(logf(f, v...)) +} + +// Debug logs a message at debug level. +func Debug(f interface{}, v ...interface{}) { + beeLogger.Debug(logf(f, v...)) +} + +// Trace logs a message at trace level. +// compatibility alias for Warning() +func Trace(f interface{}, v ...interface{}) { + beeLogger.Trace(logf(f, v...)) +} + +func logf(f interface{}, v ...interface{}) string { + var msg string + switch f.(type) { + case string: + msg = f.(string) + if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") { + //format string + } else { + //do not contain format char + msg += strings.Repeat(" %v", len(v)) + } + default: + msg = fmt.Sprint(f) + strings.Repeat(" %v", len(v)) + } + return fmt.Sprintf(msg, v...) +} From 03840f3fe88cb9ca9f3c59045adfd730acc07564 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:38:26 +0800 Subject: [PATCH 55/81] give each of the adapter a neme --- logs/conn.go | 2 +- logs/console.go | 2 +- logs/es/es.go | 2 +- logs/file.go | 2 +- logs/multifile.go | 2 +- logs/smtp.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/logs/conn.go b/logs/conn.go index 1db1a427..6d5bf6bf 100644 --- a/logs/conn.go +++ b/logs/conn.go @@ -113,5 +113,5 @@ func (c *connWriter) needToConnectOnMsg() bool { } func init() { - Register("conn", NewConn) + Register(AdapterConn, NewConn) } diff --git a/logs/console.go b/logs/console.go index dc41dd7d..e6bf6c29 100644 --- a/logs/console.go +++ b/logs/console.go @@ -97,5 +97,5 @@ func (c *consoleWriter) Flush() { } func init() { - Register("console", NewConsole) + Register(AdapterConsole, NewConsole) } diff --git a/logs/es/es.go b/logs/es/es.go index 397ca2ef..ceebe71a 100644 --- a/logs/es/es.go +++ b/logs/es/es.go @@ -76,5 +76,5 @@ func (el *esLogger) Flush() { } func init() { - logs.Register("es", NewES) + logs.Register(logs.AdaterEs, NewES) } diff --git a/logs/file.go b/logs/file.go index 672823fa..159d4970 100644 --- a/logs/file.go +++ b/logs/file.go @@ -282,5 +282,5 @@ func (w *fileLogWriter) Flush() { } func init() { - Register("file", newFileWriter) + Register(AdapterFile, newFileWriter) } diff --git a/logs/multifile.go b/logs/multifile.go index b82ba274..63204e17 100644 --- a/logs/multifile.go +++ b/logs/multifile.go @@ -112,5 +112,5 @@ func newFilesWriter() Logger { } func init() { - Register("multifile", newFilesWriter) + Register(AdapterMultiFile, newFilesWriter) } diff --git a/logs/smtp.go b/logs/smtp.go index 47f5a0c6..834130ef 100644 --- a/logs/smtp.go +++ b/logs/smtp.go @@ -156,5 +156,5 @@ func (s *SMTPWriter) Destroy() { } func init() { - Register("smtp", newSMTPWriter) + Register(AdapterMail, newSMTPWriter) } From 98dfecfd8a0de2c6e2852bf019d7a01bc21b88cc Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:39:29 +0800 Subject: [PATCH 56/81] change beego log function to logs function --- admin.go | 5 ++- app.go | 28 ++++++------ config.go | 7 +-- hooks.go | 3 +- log.go | 116 -------------------------------------------------- parser.go | 5 ++- router.go | 17 ++++---- staticfile.go | 5 ++- template.go | 9 ++-- 9 files changed, 43 insertions(+), 152 deletions(-) delete mode 100644 log.go diff --git a/admin.go b/admin.go index cf5bc63a..94fa55b9 100644 --- a/admin.go +++ b/admin.go @@ -24,6 +24,7 @@ import ( "time" "github.com/astaxie/beego/grace" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/toolbox" "github.com/astaxie/beego/utils" ) @@ -410,7 +411,7 @@ func (admin *adminApp) Run() { for p, f := range admin.routers { http.Handle(p, f) } - BeeLogger.Info("Admin server Running on %s", addr) + logs.Info("Admin server Running on %s", addr) var err error if BConfig.Listen.Graceful { @@ -419,6 +420,6 @@ func (admin *adminApp) Run() { err = http.ListenAndServe(addr, nil) } if err != nil { - BeeLogger.Critical("Admin ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid())) + logs.Critical("Admin ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid())) } } diff --git a/app.go b/app.go index a065670a..77116a81 100644 --- a/app.go +++ b/app.go @@ -16,7 +16,6 @@ package beego import ( "fmt" - "log" "net" "net/http" "net/http/fcgi" @@ -25,6 +24,7 @@ import ( "time" "github.com/astaxie/beego/grace" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/utils" ) @@ -69,9 +69,9 @@ func (app *App) Run() { if BConfig.Listen.EnableFcgi { if BConfig.Listen.EnableStdIo { if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O - BeeLogger.Info("Use FCGI via standard I/O") + logs.Info("Use FCGI via standard I/O") } else { - BeeLogger.Critical("Cannot use FCGI via standard I/O", err) + logs.Critical("Cannot use FCGI via standard I/O", err) } return } @@ -85,10 +85,10 @@ func (app *App) Run() { l, err = net.Listen("tcp", addr) } if err != nil { - BeeLogger.Critical("Listen: ", err) + logs.Critical("Listen: ", err) } if err = fcgi.Serve(l, app.Handlers); err != nil { - BeeLogger.Critical("fcgi.Serve: ", err) + logs.Critical("fcgi.Serve: ", err) } return } @@ -96,7 +96,7 @@ func (app *App) Run() { app.Server.Handler = app.Handlers app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second - app.Server.ErrorLog = log.New(BeeLogger, "", 0) + app.Server.ErrorLog = logs.GetLogger("HTTP") // run graceful mode if BConfig.Listen.Graceful { @@ -113,7 +113,7 @@ func (app *App) Run() { server.Server.ReadTimeout = app.Server.ReadTimeout server.Server.WriteTimeout = app.Server.WriteTimeout if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { - BeeLogger.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid())) + logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid())) time.Sleep(100 * time.Microsecond) endRunning <- true } @@ -128,7 +128,7 @@ func (app *App) Run() { server.Network = "tcp4" } if err := server.ListenAndServe(); err != nil { - BeeLogger.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid())) + logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid())) time.Sleep(100 * time.Microsecond) endRunning <- true } @@ -146,9 +146,9 @@ func (app *App) Run() { if BConfig.Listen.HTTPSPort != 0 { app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort) } - BeeLogger.Info("https server Running on %s", app.Server.Addr) + logs.Info("https server Running on %s", app.Server.Addr) if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { - BeeLogger.Critical("ListenAndServeTLS: ", err) + logs.Critical("ListenAndServeTLS: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } @@ -157,24 +157,24 @@ func (app *App) Run() { if BConfig.Listen.EnableHTTP { go func() { app.Server.Addr = addr - BeeLogger.Info("http server Running on %s", app.Server.Addr) + logs.Info("http server Running on %s", app.Server.Addr) if BConfig.Listen.ListenTCP4 { ln, err := net.Listen("tcp4", app.Server.Addr) if err != nil { - BeeLogger.Critical("ListenAndServe: ", err) + logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } if err = app.Server.Serve(ln); err != nil { - BeeLogger.Critical("ListenAndServe: ", err) + logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true return } } else { if err := app.Server.ListenAndServe(); err != nil { - BeeLogger.Critical("ListenAndServe: ", err) + logs.Critical("ListenAndServe: ", err) time.Sleep(100 * time.Microsecond) endRunning <- true } diff --git a/config.go b/config.go index f0316a62..72045fd3 100644 --- a/config.go +++ b/config.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/astaxie/beego/config" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/session" "github.com/astaxie/beego/utils" ) @@ -293,14 +294,14 @@ func parseConfig(appConfigPath string) (err error) { } //init log - BeeLogger.Reset() + logs.Reset() for adaptor, config := range BConfig.Log.Outputs { - err = BeeLogger.SetLogger(adaptor, config) + err = logs.SetLogger(adaptor, config) if err != nil { fmt.Printf("%s with the config `%s` got err:%s\n", adaptor, config, err) } } - SetLogFuncCall(BConfig.Log.FileLineNum) + logs.SetLogFuncCall(BConfig.Log.FileLineNum) return nil } diff --git a/hooks.go b/hooks.go index 674f2858..3d784467 100644 --- a/hooks.go +++ b/hooks.go @@ -7,6 +7,7 @@ import ( "path/filepath" "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/session" ) @@ -71,7 +72,7 @@ func registerSession() error { func registerTemplate() error { if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil { if BConfig.RunMode == DEV { - Warn(err) + logs.Warn(err) } return err } diff --git a/log.go b/log.go deleted file mode 100644 index 46ec57dd..00000000 --- a/log.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2014 beego Author. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package beego - -import ( - "strings" - - "github.com/astaxie/beego/logs" -) - -// Log levels to control the logging output. -const ( - LevelEmergency = iota - LevelAlert - LevelCritical - LevelError - LevelWarning - LevelNotice - LevelInformational - LevelDebug -) - -// BeeLogger references the used application logger. -var BeeLogger = logs.NewLogger(100) - -// SetLevel sets the global log level used by the simple logger. -func SetLevel(l int) { - BeeLogger.SetLevel(l) -} - -// SetLogFuncCall set the CallDepth, default is 3 -func SetLogFuncCall(b bool) { - BeeLogger.EnableFuncCallDepth(b) - BeeLogger.SetLogFuncCallDepth(3) -} - -// SetLogger sets a new logger. -func SetLogger(adaptername string, config string) error { - err := BeeLogger.SetLogger(adaptername, config) - if err != nil { - return err - } - return nil -} - -// Emergency logs a message at emergency level. -func Emergency(v ...interface{}) { - BeeLogger.Emergency(generateFmtStr(len(v)), v...) -} - -// Alert logs a message at alert level. -func Alert(v ...interface{}) { - BeeLogger.Alert(generateFmtStr(len(v)), v...) -} - -// Critical logs a message at critical level. -func Critical(v ...interface{}) { - BeeLogger.Critical(generateFmtStr(len(v)), v...) -} - -// Error logs a message at error level. -func Error(v ...interface{}) { - BeeLogger.Error(generateFmtStr(len(v)), v...) -} - -// Warning logs a message at warning level. -func Warning(v ...interface{}) { - BeeLogger.Warning(generateFmtStr(len(v)), v...) -} - -// Warn compatibility alias for Warning() -func Warn(v ...interface{}) { - BeeLogger.Warn(generateFmtStr(len(v)), v...) -} - -// Notice logs a message at notice level. -func Notice(v ...interface{}) { - BeeLogger.Notice(generateFmtStr(len(v)), v...) -} - -// Informational logs a message at info level. -func Informational(v ...interface{}) { - BeeLogger.Informational(generateFmtStr(len(v)), v...) -} - -// Info compatibility alias for Warning() -func Info(v ...interface{}) { - BeeLogger.Info(generateFmtStr(len(v)), v...) -} - -// Debug logs a message at debug level. -func Debug(v ...interface{}) { - BeeLogger.Debug(generateFmtStr(len(v)), v...) -} - -// Trace logs a message at trace level. -// compatibility alias for Warning() -func Trace(v ...interface{}) { - BeeLogger.Trace(generateFmtStr(len(v)), v...) -} - -func generateFmtStr(n int) string { - return strings.Repeat("%v ", n) -} diff --git a/parser.go b/parser.go index 46d02320..24f7549b 100644 --- a/parser.go +++ b/parser.go @@ -27,6 +27,7 @@ import ( "sort" "strings" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/utils" ) @@ -58,7 +59,7 @@ func parserPkg(pkgRealpath, pkgpath string) error { rep := strings.NewReplacer("/", "_", ".", "_") commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go" if !compareFile(pkgRealpath) { - Info(pkgRealpath + " no changed") + logs.Info(pkgRealpath + " no changed") return nil } genInfoList = make(map[string][]ControllerComments) @@ -131,7 +132,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat func genRouterCode() { os.Mkdir(path.Join(AppPath, "routers"), 0755) - Info("generate router from comments") + logs.Info("generate router from comments") var ( globalinfo string sortKey []string diff --git a/router.go b/router.go index 5516ecda..960cd104 100644 --- a/router.go +++ b/router.go @@ -28,6 +28,7 @@ import ( "time" beecontext "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/toolbox" "github.com/astaxie/beego/utils" ) @@ -439,11 +440,11 @@ func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string { paths := strings.Split(endpoint, ".") if len(paths) <= 1 { - Warn("urlfor endpoint must like path.controller.method") + logs.Warn("urlfor endpoint must like path.controller.method") return "" } if len(values)%2 != 0 { - Warn("urlfor params must key-value pair") + logs.Warn("urlfor params must key-value pair") return "" } params := make(map[string]string) @@ -651,7 +652,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) var err error context.Input.CruSession, err = GlobalSessions.SessionStart(rw, r) if err != nil { - Error(err) + logs.Error(err) exception("503", context) goto Admin } @@ -780,7 +781,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if !context.ResponseWriter.Started && context.Output.Status == 0 { if BConfig.WebConfig.AutoRender { if err := execController.Render(); err != nil { - Error(err) + logs.Error(err) } } } @@ -825,7 +826,7 @@ Admin: devInfo = fmt.Sprintf("| % -10s | % -40s | % -16s | % -10s |", r.Method, r.URL.Path, timeDur.String(), "notmatch") } if DefaultAccessLogFilter == nil || !DefaultAccessLogFilter.Filter(context) { - Debug(devInfo) + logs.Debug(devInfo) } } @@ -850,14 +851,14 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) { } } var stack string - Critical("the request url is ", context.Input.URL()) - Critical("Handler crashed with error", err) + logs.Critical("the request url is ", context.Input.URL()) + logs.Critical("Handler crashed with error", err) for i := 1; ; i++ { _, file, line, ok := runtime.Caller(i) if !ok { break } - Critical(fmt.Sprintf("%s:%d", file, line)) + logs.Critical(fmt.Sprintf("%s:%d", file, line)) stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line)) } if BConfig.RunMode == DEV { diff --git a/staticfile.go b/staticfile.go index 1cd75b8c..8a1bc57b 100644 --- a/staticfile.go +++ b/staticfile.go @@ -27,6 +27,7 @@ import ( "time" "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" ) var errNotStaticRequest = errors.New("request not a static file request") @@ -48,7 +49,7 @@ func serverStaticRouter(ctx *context.Context) { if filePath == "" || fileInfo == nil { if BConfig.RunMode == DEV { - Warn("Can't find/open the file:", filePath, err) + logs.Warn("Can't find/open the file:", filePath, err) } http.NotFound(ctx.ResponseWriter, ctx.Request) return @@ -72,7 +73,7 @@ func serverStaticRouter(ctx *context.Context) { b, n, sch, err := openFile(filePath, fileInfo, acceptEncoding) if err != nil { if BConfig.RunMode == DEV { - Warn("Can't compress the file:", filePath, err) + logs.Warn("Can't compress the file:", filePath, err) } http.NotFound(ctx.ResponseWriter, ctx.Request) return diff --git a/template.go b/template.go index e6c43f87..a7c719e8 100644 --- a/template.go +++ b/template.go @@ -26,6 +26,7 @@ import ( "strings" "sync" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/utils" ) @@ -46,7 +47,7 @@ func executeTemplate(wr io.Writer, name string, data interface{}) error { if t, ok := beeTemplates[name]; ok { err := t.ExecuteTemplate(wr, name, data) if err != nil { - Trace("template Execute err:", err) + logs.Trace("template Execute err:", err) } return err } @@ -162,7 +163,7 @@ func BuildTemplate(dir string, files ...string) error { templatesLock.Lock() t, err := getTemplate(self.root, file, v...) if err != nil { - Trace("parse template err:", file, err) + logs.Trace("parse template err:", file, err) } else { beeTemplates[file] = t } @@ -240,7 +241,7 @@ func _getTemplate(t0 *template.Template, root string, subMods [][]string, others var subMods1 [][]string t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { - Trace("template parse file err:", err) + logs.Trace("template parse file err:", err) } else if subMods1 != nil && len(subMods1) > 0 { t, err = _getTemplate(t, root, subMods1, others...) } @@ -261,7 +262,7 @@ func _getTemplate(t0 *template.Template, root string, subMods [][]string, others var subMods1 [][]string t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { - Trace("template parse file err:", err) + logs.Trace("template parse file err:", err) } else if subMods1 != nil && len(subMods1) > 0 { t, err = _getTemplate(t, root, subMods1, others...) } From cdfd830f659e210ec4ed3e70c72dedbef8ec8736 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:43:16 +0800 Subject: [PATCH 57/81] rename log format --- logs/log.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/logs/log.go b/logs/log.go index 1ec7dd1d..44bcfac1 100644 --- a/logs/log.go +++ b/logs/log.go @@ -521,62 +521,62 @@ func SetLogger(adaptername string, config string) error { // Emergency logs a message at emergency level. func Emergency(f interface{}, v ...interface{}) { - beeLogger.Emergency(logf(f, v...)) + beeLogger.Emergency(formatLog(f, v...)) } // Alert logs a message at alert level. func Alert(f interface{}, v ...interface{}) { - beeLogger.Alert(logf(f, v...)) + beeLogger.Alert(formatLog(f, v...)) } // Critical logs a message at critical level. func Critical(f interface{}, v ...interface{}) { - beeLogger.Critical(logf(f, v...)) + beeLogger.Critical(formatLog(f, v...)) } // Error logs a message at error level. func Error(f interface{}, v ...interface{}) { - beeLogger.Error(logf(f, v...)) + beeLogger.Error(formatLog(f, v...)) } // Warning logs a message at warning level. func Warning(f interface{}, v ...interface{}) { - beeLogger.Warning(logf(f, v...)) + beeLogger.Warning(formatLog(f, v...)) } // Warn compatibility alias for Warning() func Warn(f interface{}, v ...interface{}) { - beeLogger.Warn(logf(f, v...)) + beeLogger.Warn(formatLog(f, v...)) } // Notice logs a message at notice level. func Notice(f interface{}, v ...interface{}) { - beeLogger.Notice(logf(f, v...)) + beeLogger.Notice(formatLog(f, v...)) } // Informational logs a message at info level. func Informational(f interface{}, v ...interface{}) { - beeLogger.Informational(logf(f, v...)) + beeLogger.Informational(formatLog(f, v...)) } // Info compatibility alias for Warning() func Info(f interface{}, v ...interface{}) { fmt.Print() - beeLogger.Info(logf(f, v...)) + beeLogger.Info(formatLog(f, v...)) } // Debug logs a message at debug level. func Debug(f interface{}, v ...interface{}) { - beeLogger.Debug(logf(f, v...)) + beeLogger.Debug(formatLog(f, v...)) } // Trace logs a message at trace level. // compatibility alias for Warning() func Trace(f interface{}, v ...interface{}) { - beeLogger.Trace(logf(f, v...)) + beeLogger.Trace(formatLog(f, v...)) } -func logf(f interface{}, v ...interface{}) string { +func formatLog(f interface{}, v ...interface{}) string { var msg string switch f.(type) { case string: From a6c1377f91add359dd281405e2d7d297485f441e Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:43:45 +0800 Subject: [PATCH 58/81] change to 0 logger --- logs/log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/log.go b/logs/log.go index 44bcfac1..cdd82a02 100644 --- a/logs/log.go +++ b/logs/log.go @@ -457,7 +457,7 @@ func (bl *BeeLogger) flush() { } // BeeLogger references the used application logger. -var beeLogger = NewLogger(100) +var beeLogger = NewLogger() // GetLogger returns the default BeeLogger func GetBeeLogger() *BeeLogger { From 0fb4a8af24a788c5d8ba9731ee5f19b9f5815214 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:46:52 +0800 Subject: [PATCH 59/81] function change --- logs/log.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logs/log.go b/logs/log.go index cdd82a02..67bf2a73 100644 --- a/logs/log.go +++ b/logs/log.go @@ -511,8 +511,8 @@ func SetLogFuncCall(b bool) { } // SetLogger sets a new logger. -func SetLogger(adaptername string, config string) error { - err := beeLogger.SetLogger(adaptername, config) +func SetLogger(adapter string, config ...string) error { + err := beeLogger.SetLogger(adapter, config...) if err != nil { return err } From 8344a60552bd010385cc208157a215e6cb253705 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 17:49:39 +0800 Subject: [PATCH 60/81] add to upper case --- logs/log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/log.go b/logs/log.go index 67bf2a73..7b65dbc3 100644 --- a/logs/log.go +++ b/logs/log.go @@ -475,7 +475,7 @@ var beeLoggerMap = struct { func GetLogger(prefixes ...string) *log.Logger { prefix := append(prefixes, "")[0] if prefix != "" { - prefix = fmt.Sprintf(`[%s] `, prefix) + prefix = fmt.Sprintf(`[%s] `, strings.ToUpper(prefix)) } beeLoggerMap.RLock() l, ok := beeLoggerMap.logs[prefix] From 0814eefa6293f21f487ebe3e3085b844435d9053 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 18:21:52 +0800 Subject: [PATCH 61/81] refactor writeMsg function --- logs/es/es.go | 2 +- logs/log.go | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/logs/es/es.go b/logs/es/es.go index ceebe71a..22f4f650 100644 --- a/logs/es/es.go +++ b/logs/es/es.go @@ -76,5 +76,5 @@ func (el *esLogger) Flush() { } func init() { - logs.Register(logs.AdaterEs, NewES) + logs.Register(logs.AdapterEs, NewES) } diff --git a/logs/log.go b/logs/log.go index 7b65dbc3..32e441f4 100644 --- a/logs/log.go +++ b/logs/log.go @@ -56,14 +56,16 @@ const ( LevelInformational LevelDebug ) +const levelCustom = -1 +// Name for adapter with beego official support const ( AdapterConsole = "console" AdapterFile = "file" AdapterMultiFile = "multifile" AdapterMail = "stmp" AdapterConn = "conn" - AdaterEs = "es" + AdapterEs = "es" ) // Legacy loglevel constants to ensure backwards compatibility. @@ -75,7 +77,7 @@ const ( LevelWarn = LevelWarning ) -type loggerType func() Logger +type newLoggerFunc func() Logger // Logger defines the behavior of a log provider. type Logger interface { @@ -85,12 +87,13 @@ type Logger interface { Flush() } -var adapters = make(map[string]loggerType) +var adapters = make(map[string]newLoggerFunc) +var levelPrefix = [LevelDebug + 1]string{"[M] ", "[A] ", "[C] ", "[E] ", "[W] ", "[N] ", "[I] ", "[D] "} // Register makes a log provide available by the provided name. // If Register is called twice with the same name or if driver is nil, // it panics. -func Register(name string, log loggerType) { +func Register(name string, log newLoggerFunc) { if log == nil { panic("logs: Register provide is nil") } @@ -222,14 +225,18 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) { p = p[0 : len(p)-1] } // set LevelCritical to ensure all log message will be write out - err = bl.writeMsg(LevelCritical, string(p)) + err = bl.writeMsg(levelCustom, string(p)) if err == nil { return len(p), err } return 0, err } -func (bl *BeeLogger) writeMsg(logLevel int, msg string) error { +func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error { + if logLevel != levelCustom { + msg = levelPrefix[logLevel] + msg + } + msg = fmt.Sprintf(msg, v...) when := time.Now() if bl.enableFuncCallDepth { _, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth) @@ -561,7 +568,6 @@ func Informational(f interface{}, v ...interface{}) { // Info compatibility alias for Warning() func Info(f interface{}, v ...interface{}) { - fmt.Print() beeLogger.Info(formatLog(f, v...)) } From d8bed89c442838ddcbfc75b6c1c645d5219c79ef Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 19:15:14 +0800 Subject: [PATCH 62/81] set console as default logger --- logs/log.go | 98 ++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/logs/log.go b/logs/log.go index 32e441f4..0f5fa052 100644 --- a/logs/log.go +++ b/logs/log.go @@ -56,7 +56,10 @@ const ( LevelInformational LevelDebug ) -const levelCustom = -1 + +// levelLogLogger is defined to implement log.Logger +// the real log level will be LevelEmergency +const levelLoggerImpl = -1 // Name for adapter with beego official support const ( @@ -68,9 +71,7 @@ const ( AdapterEs = "es" ) -// Legacy loglevel constants to ensure backwards compatibility. -// -// Deprecated: will be removed in 1.5.0. +// Legacy log level constants to ensure backwards compatibility. const ( LevelInfo = LevelInformational LevelTrace = LevelDebug @@ -108,10 +109,11 @@ func Register(name string, log newLoggerFunc) { type BeeLogger struct { lock sync.Mutex level int - msgChanLen int64 + init bool enableFuncCallDepth bool loggerFuncCallDepth int asynchronous bool + msgChanLen int64 msgChan chan *logMsg signalChan chan string wg sync.WaitGroup @@ -143,11 +145,17 @@ func NewLogger(channelLens ...int64) *BeeLogger { bl.msgChanLen = 0 } bl.signalChan = make(chan string, 1) + bl.setLogger(AdapterConsole) return bl } // Async set the log to asynchronous and start the goroutine func (bl *BeeLogger) Async() *BeeLogger { + bl.lock.Lock() + defer bl.lock.Unlock() + if bl.asynchronous { + return bl + } bl.asynchronous = true bl.msgChan = make(chan *logMsg, bl.msgChanLen) logMsgPool = &sync.Pool{ @@ -162,11 +170,8 @@ func (bl *BeeLogger) Async() *BeeLogger { // SetLogger provides a given logger adapter into BeeLogger with config string. // config need to be correct JSON as string: {"interval":360}. -func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error { +func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error { config := append(configs, "{}")[0] - bl.lock.Lock() - defer bl.lock.Unlock() - for _, l := range bl.outputs { if l.name == adapterName { return fmt.Errorf("logs: duplicate adaptername %q (you have set this logger before)", adapterName) @@ -188,6 +193,18 @@ func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error { return nil } +// SetLogger provides a given logger adapter into BeeLogger with config string. +// config need to be correct JSON as string: {"interval":360}. +func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error { + bl.lock.Lock() + defer bl.lock.Unlock() + if !bl.init { + bl.outputs = []*nameLogger{} + bl.init = true + } + return bl.setLogger(adapterName, configs...) +} + // DelLogger remove a logger adapter in BeeLogger. func (bl *BeeLogger) DelLogger(adapterName string) error { bl.lock.Lock() @@ -224,8 +241,8 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) { if p[len(p)-1] == '\n' { p = p[0 : len(p)-1] } - // set LevelCritical to ensure all log message will be write out - err = bl.writeMsg(levelCustom, string(p)) + // set levelLoggerImpl to ensure all log message will be write out + err = bl.writeMsg(levelLoggerImpl, string(p)) if err == nil { return len(p), err } @@ -233,7 +250,10 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) { } func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error { - if logLevel != levelCustom { + if logLevel == levelLoggerImpl { + // set to emergency to ensure all log will be print out correctly + logLevel = LevelEmergency + } else { msg = levelPrefix[logLevel] + msg } msg = fmt.Sprintf(msg, v...) @@ -313,8 +333,7 @@ func (bl *BeeLogger) Emergency(format string, v ...interface{}) { if LevelEmergency > bl.level { return } - msg := fmt.Sprintf("[M] "+format, v...) - bl.writeMsg(LevelEmergency, msg) + bl.writeMsg(LevelEmergency, format, v...) } // Alert Log ALERT level message. @@ -322,8 +341,7 @@ func (bl *BeeLogger) Alert(format string, v ...interface{}) { if LevelAlert > bl.level { return } - msg := fmt.Sprintf("[A] "+format, v...) - bl.writeMsg(LevelAlert, msg) + bl.writeMsg(LevelAlert, format, v...) } // Critical Log CRITICAL level message. @@ -331,8 +349,7 @@ func (bl *BeeLogger) Critical(format string, v ...interface{}) { if LevelCritical > bl.level { return } - msg := fmt.Sprintf("[C] "+format, v...) - bl.writeMsg(LevelCritical, msg) + bl.writeMsg(LevelCritical, format, v...) } // Error Log ERROR level message. @@ -340,17 +357,12 @@ func (bl *BeeLogger) Error(format string, v ...interface{}) { if LevelError > bl.level { return } - msg := fmt.Sprintf("[E] "+format, v...) - bl.writeMsg(LevelError, msg) + bl.writeMsg(LevelError, format, v...) } // Warning Log WARNING level message. func (bl *BeeLogger) Warning(format string, v ...interface{}) { - if LevelWarning > bl.level { - return - } - msg := fmt.Sprintf("[W] "+format, v...) - bl.writeMsg(LevelWarning, msg) + bl.Warn(format, v...) } // Notice Log NOTICE level message. @@ -358,17 +370,12 @@ func (bl *BeeLogger) Notice(format string, v ...interface{}) { if LevelNotice > bl.level { return } - msg := fmt.Sprintf("[N] "+format, v...) - bl.writeMsg(LevelNotice, msg) + bl.writeMsg(LevelNotice, format, v...) } // Informational Log INFORMATIONAL level message. func (bl *BeeLogger) Informational(format string, v ...interface{}) { - if LevelInformational > bl.level { - return - } - msg := fmt.Sprintf("[I] "+format, v...) - bl.writeMsg(LevelInformational, msg) + bl.Info(format, v...) } // Debug Log DEBUG level message. @@ -376,38 +383,31 @@ func (bl *BeeLogger) Debug(format string, v ...interface{}) { if LevelDebug > bl.level { return } - msg := fmt.Sprintf("[D] "+format, v...) - bl.writeMsg(LevelDebug, msg) + bl.writeMsg(LevelDebug, format, v...) } // Warn Log WARN level message. // compatibility alias for Warning() func (bl *BeeLogger) Warn(format string, v ...interface{}) { - if LevelWarning > bl.level { + if LevelWarn > bl.level { return } - msg := fmt.Sprintf("[W] "+format, v...) - bl.writeMsg(LevelWarning, msg) + bl.writeMsg(LevelWarn, format, v...) } // Info Log INFO level message. // compatibility alias for Informational() func (bl *BeeLogger) Info(format string, v ...interface{}) { - if LevelInformational > bl.level { + if LevelInfo > bl.level { return } - msg := fmt.Sprintf("[I] "+format, v...) - bl.writeMsg(LevelInformational, msg) + bl.writeMsg(LevelInfo, format, v...) } // Trace Log TRACE level message. // compatibility alias for Debug() func (bl *BeeLogger) Trace(format string, v ...interface{}) { - if LevelDebug > bl.level { - return - } - msg := fmt.Sprintf("[D] "+format, v...) - bl.writeMsg(LevelDebug, msg) + bl.Debug(format, v...) } // Flush flush all chan data. @@ -506,6 +506,10 @@ func Reset() { beeLogger.Reset() } +func Async() *BeeLogger { + return beeLogger.Async() +} + // SetLevel sets the global log level used by the simple logger. func SetLevel(l int) { beeLogger.SetLevel(l) @@ -548,7 +552,7 @@ func Error(f interface{}, v ...interface{}) { // Warning logs a message at warning level. func Warning(f interface{}, v ...interface{}) { - beeLogger.Warning(formatLog(f, v...)) + beeLogger.Warn(formatLog(f, v...)) } // Warn compatibility alias for Warning() @@ -563,7 +567,7 @@ func Notice(f interface{}, v ...interface{}) { // Informational logs a message at info level. func Informational(f interface{}, v ...interface{}) { - beeLogger.Informational(formatLog(f, v...)) + beeLogger.Info(formatLog(f, v...)) } // Info compatibility alias for Warning() From 06299fa47bf81f21a6989bf4a5819808b6c56b18 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 19:32:29 +0800 Subject: [PATCH 63/81] makes console as default logger --- logs/log.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/logs/log.go b/logs/log.go index 0f5fa052..cf0f6346 100644 --- a/logs/log.go +++ b/logs/log.go @@ -464,7 +464,11 @@ func (bl *BeeLogger) flush() { } // BeeLogger references the used application logger. -var beeLogger = NewLogger() +var beeLogger *BeeLogger + +func init() { + beeLogger = NewLogger() +} // GetLogger returns the default BeeLogger func GetBeeLogger() *BeeLogger { From 3e2ffa545f5717c7b8dc76a5a68126fcd43b8891 Mon Sep 17 00:00:00 2001 From: miraclesu Date: Thu, 24 Mar 2016 20:03:45 +0800 Subject: [PATCH 64/81] orm: fix postgres returning id error --- orm/db_postgres.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/orm/db_postgres.go b/orm/db_postgres.go index 7dbef95a..be4cd0bc 100644 --- a/orm/db_postgres.go +++ b/orm/db_postgres.go @@ -123,14 +123,16 @@ func (d *dbBasePostgres) ReplaceMarks(query *string) { } // make returning sql support for postgresql. -func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool) { - if mi.fields.pk.auto { - if query != nil { - *query = fmt.Sprintf(`%s RETURNING "%s"`, *query, mi.fields.pk.column) - } - has = true +func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) bool { + fi := mi.fields.pk + if fi.fieldType&IsPositiveIntegerField == 0 && fi.fieldType&IsIntegerField == 0 { + return false } - return + + if query != nil { + *query = fmt.Sprintf(`%s RETURNING "%s"`, *query, fi.column) + } + return true } // show table sql for postgresql. From f02ff0420d75a3d1d09e1e400e6bf0250848d6f7 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 20:22:42 +0800 Subject: [PATCH 65/81] no need to call Sprintf when no args --- logs/log.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/logs/log.go b/logs/log.go index cf0f6346..3d4a4d60 100644 --- a/logs/log.go +++ b/logs/log.go @@ -256,7 +256,9 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error } else { msg = levelPrefix[logLevel] + msg } - msg = fmt.Sprintf(msg, v...) + if len(v) > 0 { + msg = fmt.Sprintf(msg, v...) + } when := time.Now() if bl.enableFuncCallDepth { _, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth) From 52a0b657b7764530178ac36ca22af8df24e921e4 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 24 Mar 2016 20:27:00 +0800 Subject: [PATCH 66/81] for better performance --- logs/log.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/logs/log.go b/logs/log.go index 3d4a4d60..506e712d 100644 --- a/logs/log.go +++ b/logs/log.go @@ -597,6 +597,9 @@ func formatLog(f interface{}, v ...interface{}) string { switch f.(type) { case string: msg = f.(string) + if len(v) == 0 { + return msg + } if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") { //format string } else { @@ -604,7 +607,11 @@ func formatLog(f interface{}, v ...interface{}) string { msg += strings.Repeat(" %v", len(v)) } default: - msg = fmt.Sprint(f) + strings.Repeat(" %v", len(v)) + msg = fmt.Sprint(f) + if len(v) == 0 { + return msg + } + msg += strings.Repeat(" %v", len(v)) } return fmt.Sprintf(msg, v...) } From 3300db832bdbb37500c7d499b1a279d45172aa31 Mon Sep 17 00:00:00 2001 From: youngsterxyf Date: Thu, 24 Mar 2016 22:43:57 +0800 Subject: [PATCH 67/81] in `session` package, add a helpful variable `SLogger` to help subpackage logging information --- session/ledis/ledis_session.go | 2 +- session/mysql/sess_mysql.go | 10 ++++++++-- session/sess_file.go | 10 +++++----- session/session.go | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/session/ledis/ledis_session.go b/session/ledis/ledis_session.go index 68f37b08..6b201f56 100644 --- a/session/ledis/ledis_session.go +++ b/session/ledis/ledis_session.go @@ -100,7 +100,7 @@ func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error { nowLedis, err := ledis.Open(cfg) c, err = nowLedis.Select(lp.db) if err != nil { - println(err) + session.SLogger.Println(err) return nil } return nil diff --git a/session/mysql/sess_mysql.go b/session/mysql/sess_mysql.go index 969d26c9..93ea31ed 100644 --- a/session/mysql/sess_mysql.go +++ b/session/mysql/sess_mysql.go @@ -1,3 +1,4 @@ + // Copyright 2014 beego Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -111,11 +112,14 @@ func (st *SessionStore) SessionRelease(w http.ResponseWriter) { defer st.c.Close() b, err := session.EncodeGob(st.values) if err != nil { + session.SLogger.Println(err) return } - st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", + _, err = st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", b, time.Now().Unix(), st.sid) - + if err != nil { + session.SLogger.Println(err) + } } // Provider mysql session provider @@ -128,6 +132,7 @@ type Provider struct { func (mp *Provider) connectInit() *sql.DB { db, e := sql.Open("mysql", mp.savePath) if e != nil { + session.SLogger.Println(e) return nil } return db @@ -223,6 +228,7 @@ func (mp *Provider) SessionAll() int { var total int err := c.QueryRow("SELECT count(*) as num from " + TableName).Scan(&total) if err != nil { + session.SLogger.Println(err) return 0 } return total diff --git a/session/sess_file.go b/session/sess_file.go index 9265b030..dda56b3a 100644 --- a/session/sess_file.go +++ b/session/sess_file.go @@ -16,7 +16,6 @@ package session import ( "errors" - "fmt" "io" "io/ioutil" "net/http" @@ -82,6 +81,7 @@ func (fs *FileSessionStore) SessionID() string { func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { b, err := EncodeGob(fs.values) if err != nil { + SLogger.Println(err) return } _, err = os.Stat(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid)) @@ -123,7 +123,7 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) { err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777) if err != nil { - println(err.Error()) + SLogger.Println(err.Error()) } _, err = os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid)) var f *os.File @@ -191,7 +191,7 @@ func (fp *FileProvider) SessionAll() int { return a.visit(path, f, err) }) if err != nil { - fmt.Printf("filepath.Walk() returned %v\n", err) + SLogger.Printf("filepath.Walk() returned %v\n", err) return 0 } return a.total @@ -205,11 +205,11 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) { err := os.MkdirAll(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])), 0777) if err != nil { - println(err.Error()) + SLogger.Println(err.Error()) } err = os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777) if err != nil { - println(err.Error()) + SLogger.Println(err.Error()) } _, err = os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid)) var newf *os.File diff --git a/session/session.go b/session/session.go index 9fe99a17..09c200c5 100644 --- a/session/session.go +++ b/session/session.go @@ -32,8 +32,11 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io" + "log" "net/http" "net/url" + "os" "time" ) @@ -61,6 +64,8 @@ type Provider interface { var provides = make(map[string]Provider) +var SLogger = newSessionLog(os.Stderr) + // Register makes a session provide available by the provided name. // If Register is called twice with the same name or if driver is nil, // it panics. @@ -296,3 +301,15 @@ func (manager *Manager) isSecure(req *http.Request) bool { } return true } + +// Log implement the log.Logger +type sessionLog struct { + *log.Logger +} + +// NewLog set io.Writer to create a Logger for session. +func newSessionLog(out io.Writer) *sessionLog { + sl := new(sessionLog) + sl.Logger = log.New(out, "[SESSION]", 1e9) + return sl +} From 94bde3a77768f6285b852240d8669f37a86d7966 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 10:31:48 +0800 Subject: [PATCH 68/81] change to logs --- filter_test.go | 6 ------ router_test.go | 11 ++++++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/filter_test.go b/filter_test.go index d9928d8d..4ca4d2b8 100644 --- a/filter_test.go +++ b/filter_test.go @@ -20,14 +20,8 @@ import ( "testing" "github.com/astaxie/beego/context" - "github.com/astaxie/beego/logs" ) -func init() { - BeeLogger = logs.NewLogger(10000) - BeeLogger.SetLogger("console", "") -} - var FilterUser = func(ctx *context.Context) { ctx.Output.Body([]byte("i am " + ctx.Input.Param(":last") + ctx.Input.Param(":first"))) } diff --git a/router_test.go b/router_test.go index f26f0c86..9f11286c 100644 --- a/router_test.go +++ b/router_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" ) type TestController struct { @@ -94,7 +95,7 @@ func TestUrlFor(t *testing.T) { handler.Add("/api/list", &TestController{}, "*:List") handler.Add("/person/:last/:first", &TestController{}, "*:Param") if a := handler.URLFor("TestController.List"); a != "/api/list" { - Info(a) + logs.Info(a) t.Errorf("TestController.List must equal to /api/list") } if a := handler.URLFor("TestController.Param", ":last", "xie", ":first", "asta"); a != "/person/xie/asta" { @@ -120,24 +121,24 @@ func TestUrlFor2(t *testing.T) { handler.Add("/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", &TestController{}, "*:Param") handler.Add("/:year:int/:month:int/:title/:entid", &TestController{}) if handler.URLFor("TestController.GetURL", ":username", "astaxie") != "/v1/astaxie/edit" { - Info(handler.URLFor("TestController.GetURL")) + logs.Info(handler.URLFor("TestController.GetURL")) t.Errorf("TestController.List must equal to /v1/astaxie/edit") } if handler.URLFor("TestController.List", ":v", "za", ":id", "12", ":page", "123") != "/v1/za/cms_12_123.html" { - Info(handler.URLFor("TestController.List")) + logs.Info(handler.URLFor("TestController.List")) t.Errorf("TestController.List must equal to /v1/za/cms_12_123.html") } if handler.URLFor("TestController.Param", ":v", "za", ":id", "12", ":page", "123") != "/v1/za_cms/ttt_12_123.html" { - Info(handler.URLFor("TestController.Param")) + logs.Info(handler.URLFor("TestController.Param")) t.Errorf("TestController.List must equal to /v1/za_cms/ttt_12_123.html") } if handler.URLFor("TestController.Get", ":year", "1111", ":month", "11", ":title", "aaaa", ":entid", "aaaa") != "/1111/11/aaaa/aaaa" { - Info(handler.URLFor("TestController.Get")) + logs.Info(handler.URLFor("TestController.Get")) t.Errorf("TestController.Get must equal to /1111/11/aaaa/aaaa") } } From 56860d1feacaae15cd1cd53d5b600516bb978b61 Mon Sep 17 00:00:00 2001 From: youngsterxyf Date: Fri, 25 Mar 2016 10:48:59 +0800 Subject: [PATCH 69/81] not just export a variable --- session/ledis/ledis_session.go | 2 +- session/mysql/sess_mysql.go | 9 +-------- session/sess_file.go | 2 ++ session/session.go | 11 ++++++----- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/session/ledis/ledis_session.go b/session/ledis/ledis_session.go index 6b201f56..68f37b08 100644 --- a/session/ledis/ledis_session.go +++ b/session/ledis/ledis_session.go @@ -100,7 +100,7 @@ func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error { nowLedis, err := ledis.Open(cfg) c, err = nowLedis.Select(lp.db) if err != nil { - session.SLogger.Println(err) + println(err) return nil } return nil diff --git a/session/mysql/sess_mysql.go b/session/mysql/sess_mysql.go index 93ea31ed..838ec669 100644 --- a/session/mysql/sess_mysql.go +++ b/session/mysql/sess_mysql.go @@ -1,4 +1,3 @@ - // Copyright 2014 beego Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -112,14 +111,10 @@ func (st *SessionStore) SessionRelease(w http.ResponseWriter) { defer st.c.Close() b, err := session.EncodeGob(st.values) if err != nil { - session.SLogger.Println(err) return } - _, err = st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", + st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", b, time.Now().Unix(), st.sid) - if err != nil { - session.SLogger.Println(err) - } } // Provider mysql session provider @@ -132,7 +127,6 @@ type Provider struct { func (mp *Provider) connectInit() *sql.DB { db, e := sql.Open("mysql", mp.savePath) if e != nil { - session.SLogger.Println(e) return nil } return db @@ -228,7 +222,6 @@ func (mp *Provider) SessionAll() int { var total int err := c.QueryRow("SELECT count(*) as num from " + TableName).Scan(&total) if err != nil { - session.SLogger.Println(err) return 0 } return total diff --git a/session/sess_file.go b/session/sess_file.go index dda56b3a..91acfcd4 100644 --- a/session/sess_file.go +++ b/session/sess_file.go @@ -88,8 +88,10 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { var f *os.File if err == nil { f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0777) + SLogger.Println(err) } else if os.IsNotExist(err) { f, err = os.Create(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid)) + SLogger.Println(err) } else { return } diff --git a/session/session.go b/session/session.go index 09c200c5..2c4b9351 100644 --- a/session/session.go +++ b/session/session.go @@ -64,7 +64,8 @@ type Provider interface { var provides = make(map[string]Provider) -var SLogger = newSessionLog(os.Stderr) +// SLogger a helpful variable to log information about session +var SLogger = NewSessionLog(os.Stderr) // Register makes a session provide available by the provided name. // If Register is called twice with the same name or if driver is nil, @@ -303,13 +304,13 @@ func (manager *Manager) isSecure(req *http.Request) bool { } // Log implement the log.Logger -type sessionLog struct { +type Log struct { *log.Logger } -// NewLog set io.Writer to create a Logger for session. -func newSessionLog(out io.Writer) *sessionLog { - sl := new(sessionLog) +// NewSessionLog set io.Writer to create a Logger for session. +func NewSessionLog(out io.Writer) *Log { + sl := new(Log) sl.Logger = log.New(out, "[SESSION]", 1e9) return sl } From 2db8c753fd3fa8c28d134a74fd0002a63841f52f Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 10:56:15 +0800 Subject: [PATCH 70/81] bee fix --- cache/cache_test.go | 14 +++++++------- cache/memcache/memcache_test.go | 8 ++++---- cache/redis/redis_test.go | 8 ++++---- cache/ssdb/ssdb_test.go | 8 ++++---- context/input_test.go | 2 +- migration/migration.go | 34 ++++++++++++++++----------------- utils/captcha/captcha.go | 7 ++++--- utils/pagination/controller.go | 2 +- 8 files changed, 42 insertions(+), 41 deletions(-) diff --git a/cache/cache_test.go b/cache/cache_test.go index 9ceb606a..40a9d60a 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -26,7 +26,7 @@ func TestCache(t *testing.T) { t.Error("init err") } timeoutDuration := 10 * time.Second - if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -43,7 +43,7 @@ func TestCache(t *testing.T) { t.Error("check err") } - if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } @@ -68,7 +68,7 @@ func TestCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -78,7 +78,7 @@ func TestCache(t *testing.T) { t.Error("get err") } - if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { @@ -103,7 +103,7 @@ func TestFileCache(t *testing.T) { t.Error("init err") } timeoutDuration := 10 * time.Second - if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -135,7 +135,7 @@ func TestFileCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -146,7 +146,7 @@ func TestFileCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/memcache/memcache_test.go b/cache/memcache/memcache_test.go index 0c8c57f2..ce16f066 100644 --- a/cache/memcache/memcache_test.go +++ b/cache/memcache/memcache_test.go @@ -30,7 +30,7 @@ func TestMemcacheCache(t *testing.T) { t.Error("init err") } timeoutDuration := 10 * time.Second - if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -42,7 +42,7 @@ func TestMemcacheCache(t *testing.T) { if bm.IsExist("astaxie") { t.Error("check err") } - if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } @@ -71,7 +71,7 @@ func TestMemcacheCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -83,7 +83,7 @@ func TestMemcacheCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/redis/redis_test.go b/cache/redis/redis_test.go index 47c5acc6..1fcba81d 100644 --- a/cache/redis/redis_test.go +++ b/cache/redis/redis_test.go @@ -29,7 +29,7 @@ func TestRedisCache(t *testing.T) { t.Error("init err") } timeoutDuration := 10 * time.Second - if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -41,7 +41,7 @@ func TestRedisCache(t *testing.T) { if bm.IsExist("astaxie") { t.Error("check err") } - if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } @@ -70,7 +70,7 @@ func TestRedisCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -82,7 +82,7 @@ func TestRedisCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/ssdb/ssdb_test.go b/cache/ssdb/ssdb_test.go index e03ba343..c389a357 100644 --- a/cache/ssdb/ssdb_test.go +++ b/cache/ssdb/ssdb_test.go @@ -19,7 +19,7 @@ func TestSsdbcacheCache(t *testing.T) { } timeoutDuration := 10 * time.Second //timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent - if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { + if err = ssdb.Put("ssdb", "ssdb", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if !ssdb.IsExist("ssdb") { @@ -27,7 +27,7 @@ func TestSsdbcacheCache(t *testing.T) { } // Get test done - if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { + if err = ssdb.Put("ssdb", "ssdb", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } @@ -36,7 +36,7 @@ func TestSsdbcacheCache(t *testing.T) { } //inc/dec test done - if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil { + if err = ssdb.Put("ssdb", "2", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if err = ssdb.Incr("ssdb"); err != nil { @@ -52,7 +52,7 @@ func TestSsdbcacheCache(t *testing.T) { } // test del - if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil { + if err = ssdb.Put("ssdb", "3", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 { diff --git a/context/input_test.go b/context/input_test.go index 24f6fd99..8887aec4 100644 --- a/context/input_test.go +++ b/context/input_test.go @@ -100,7 +100,7 @@ func TestSubDomain(t *testing.T) { /* TODO Fix this r, _ = http.NewRequest("GET", "http://127.0.0.1/", nil) - beegoInput.Request = r + beegoInput.Context.Request = r if beegoInput.SubDomains() != "" { t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains()) } diff --git a/migration/migration.go b/migration/migration.go index 1591bc50..c9ca1bc6 100644 --- a/migration/migration.go +++ b/migration/migration.go @@ -33,7 +33,7 @@ import ( "strings" "time" - "github.com/astaxie/beego" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/orm" ) @@ -90,7 +90,7 @@ func (m *Migration) Reset() { func (m *Migration) Exec(name, status string) error { o := orm.NewOrm() for _, s := range m.sqls { - beego.Info("exec sql:", s) + logs.Info("exec sql:", s) r := o.Raw(s) _, err := r.Exec() if err != nil { @@ -144,20 +144,20 @@ func Upgrade(lasttime int64) error { i := 0 for _, v := range sm { if v.created > lasttime { - beego.Info("start upgrade", v.name) + logs.Info("start upgrade", v.name) v.m.Reset() v.m.Up() err := v.m.Exec(v.name, "up") if err != nil { - beego.Error("execute error:", err) + logs.Error("execute error:", err) time.Sleep(2 * time.Second) return err } - beego.Info("end upgrade:", v.name) + logs.Info("end upgrade:", v.name) i++ } } - beego.Info("total success upgrade:", i, " migration") + logs.Info("total success upgrade:", i, " migration") time.Sleep(2 * time.Second) return nil } @@ -165,20 +165,20 @@ func Upgrade(lasttime int64) error { // Rollback rollback the migration by the name func Rollback(name string) error { if v, ok := migrationMap[name]; ok { - beego.Info("start rollback") + logs.Info("start rollback") v.Reset() v.Down() err := v.Exec(name, "down") if err != nil { - beego.Error("execute error:", err) + logs.Error("execute error:", err) time.Sleep(2 * time.Second) return err } - beego.Info("end rollback") + logs.Info("end rollback") time.Sleep(2 * time.Second) return nil } - beego.Error("not exist the migrationMap name:" + name) + logs.Error("not exist the migrationMap name:" + name) time.Sleep(2 * time.Second) return errors.New("not exist the migrationMap name:" + name) } @@ -191,23 +191,23 @@ func Reset() error { for j := len(sm) - 1; j >= 0; j-- { v := sm[j] if isRollBack(v.name) { - beego.Info("skip the", v.name) + logs.Info("skip the", v.name) time.Sleep(1 * time.Second) continue } - beego.Info("start reset:", v.name) + logs.Info("start reset:", v.name) v.m.Reset() v.m.Down() err := v.m.Exec(v.name, "down") if err != nil { - beego.Error("execute error:", err) + logs.Error("execute error:", err) time.Sleep(2 * time.Second) return err } i++ - beego.Info("end reset:", v.name) + logs.Info("end reset:", v.name) } - beego.Info("total success reset:", i, " migration") + logs.Info("total success reset:", i, " migration") time.Sleep(2 * time.Second) return nil } @@ -216,7 +216,7 @@ func Reset() error { func Refresh() error { err := Reset() if err != nil { - beego.Error("execute error:", err) + logs.Error("execute error:", err) time.Sleep(2 * time.Second) return err } @@ -265,7 +265,7 @@ func isRollBack(name string) bool { var maps []orm.Params num, err := o.Raw("select * from migrations where `name` = ? order by id_migration desc", name).Values(&maps) if err != nil { - beego.Info("get name has error", err) + logs.Info("get name has error", err) return false } if num <= 0 { diff --git a/utils/captcha/captcha.go b/utils/captcha/captcha.go index 1a4a6edc..42ac70d3 100644 --- a/utils/captcha/captcha.go +++ b/utils/captcha/captcha.go @@ -69,6 +69,7 @@ import ( "github.com/astaxie/beego" "github.com/astaxie/beego/cache" "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" "github.com/astaxie/beego/utils" ) @@ -139,7 +140,7 @@ func (c *Captcha) Handler(ctx *context.Context) { if err := c.store.Put(key, chars, c.Expiration); err != nil { ctx.Output.SetStatus(500) ctx.WriteString("captcha reload error") - beego.Error("Reload Create Captcha Error:", err) + logs.Error("Reload Create Captcha Error:", err) return } } else { @@ -154,7 +155,7 @@ func (c *Captcha) Handler(ctx *context.Context) { img := NewImage(chars, c.StdWidth, c.StdHeight) if _, err := img.WriteTo(ctx.ResponseWriter); err != nil { - beego.Error("Write Captcha Image Error:", err) + logs.Error("Write Captcha Image Error:", err) } } @@ -162,7 +163,7 @@ func (c *Captcha) Handler(ctx *context.Context) { func (c *Captcha) CreateCaptchaHTML() template.HTML { value, err := c.CreateCaptcha() if err != nil { - beego.Error("Create Captcha Error:", err) + logs.Error("Create Captcha Error:", err) return "" } diff --git a/utils/pagination/controller.go b/utils/pagination/controller.go index 1d99cac5..2f022d0c 100644 --- a/utils/pagination/controller.go +++ b/utils/pagination/controller.go @@ -18,7 +18,7 @@ import ( "github.com/astaxie/beego/context" ) -// SetPaginator Instantiates a Paginator and assigns it to context.Input.Data["paginator"]. +// SetPaginator Instantiates a Paginator and assigns it to context.Input.Data("paginator"). func SetPaginator(context *context.Context, per int, nums int64) (paginator *Paginator) { paginator = NewPaginator(context.Request, per, nums) context.Input.SetData("paginator", &paginator) From 6d0fe8c4f44ff2e89d4d8c00b4e1931e96eb395b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 11:05:20 +0800 Subject: [PATCH 71/81] go fmt cache file --- cache/redis/redis_test.go | 1 - cache/ssdb/ssdb_test.go | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cache/redis/redis_test.go b/cache/redis/redis_test.go index 1fcba81d..e7aa78cb 100644 --- a/cache/redis/redis_test.go +++ b/cache/redis/redis_test.go @@ -19,7 +19,6 @@ import ( "time" "github.com/garyburd/redigo/redis" - "github.com/astaxie/beego/cache" ) diff --git a/cache/ssdb/ssdb_test.go b/cache/ssdb/ssdb_test.go index c389a357..8083f52d 100644 --- a/cache/ssdb/ssdb_test.go +++ b/cache/ssdb/ssdb_test.go @@ -1,10 +1,11 @@ package ssdb import ( - "github.com/astaxie/beego/cache" "strconv" "testing" "time" + + "github.com/astaxie/beego/cache" ) func TestSsdbcacheCache(t *testing.T) { From 850dc59b6e2610a589b3fd11c48b5b857c42a57a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 11:13:39 +0800 Subject: [PATCH 72/81] should remove when 2.0 is released --- log.go | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 log.go diff --git a/log.go b/log.go new file mode 100644 index 00000000..214f6d14 --- /dev/null +++ b/log.go @@ -0,0 +1,108 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package beego + +import ( + "strings" + + "github.com/astaxie/beego/logs" +) + +// Log levels to control the logging output. +const ( + LevelEmergency = iota + LevelAlert + LevelCritical + LevelError + LevelWarning + LevelNotice + LevelInformational + LevelDebug +) + +// SetLevel sets the global log level used by the simple logger. +func SetLevel(l int) { + logs.SetLevel(l) +} + +// SetLogFuncCall set the CallDepth, default is 3 +func SetLogFuncCall(b bool) { + logs.SetLogFuncCall(b) +} + +// SetLogger sets a new logger. +func SetLogger(adaptername string, config string) error { + return logs.SetLogger(adaptername, config) +} + +// Emergency logs a message at emergency level. +func Emergency(v ...interface{}) { + logs.Emergency(generateFmtStr(len(v)), v...) +} + +// Alert logs a message at alert level. +func Alert(v ...interface{}) { + logs.Alert(generateFmtStr(len(v)), v...) +} + +// Critical logs a message at critical level. +func Critical(v ...interface{}) { + logs.Critical(generateFmtStr(len(v)), v...) +} + +// Error logs a message at error level. +func Error(v ...interface{}) { + logs.Error(generateFmtStr(len(v)), v...) +} + +// Warning logs a message at warning level. +func Warning(v ...interface{}) { + logs.Warning(generateFmtStr(len(v)), v...) +} + +// Warn compatibility alias for Warning() +func Warn(v ...interface{}) { + logs.Warn(generateFmtStr(len(v)), v...) +} + +// Notice logs a message at notice level. +func Notice(v ...interface{}) { + logs.Notice(generateFmtStr(len(v)), v...) +} + +// Informational logs a message at info level. +func Informational(v ...interface{}) { + logs.Informational(generateFmtStr(len(v)), v...) +} + +// Info compatibility alias for Warning() +func Info(v ...interface{}) { + logs.Info(generateFmtStr(len(v)), v...) +} + +// Debug logs a message at debug level. +func Debug(v ...interface{}) { + logs.Debug(generateFmtStr(len(v)), v...) +} + +// Trace logs a message at trace level. +// compatibility alias for Warning() +func Trace(v ...interface{}) { + logs.Trace(generateFmtStr(len(v)), v...) +} + +func generateFmtStr(n int) string { + return strings.Repeat("%v ", n) +} From fa4a231cd4248e80a08ef7965be0b0c421bf8784 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 11:46:19 +0800 Subject: [PATCH 73/81] duration change to second --- cache/cache_test.go | 4 ++-- cache/memcache/memcache_test.go | 2 +- cache/redis/redis_test.go | 4 ++-- cache/ssdb/ssdb_test.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cache/cache_test.go b/cache/cache_test.go index 40a9d60a..ec344cb1 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -25,7 +25,7 @@ func TestCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 * time.Second + timeoutDuration := 10 if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } @@ -102,7 +102,7 @@ func TestFileCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 * time.Second + timeoutDuration := 10 if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } diff --git a/cache/memcache/memcache_test.go b/cache/memcache/memcache_test.go index ce16f066..9b9582f7 100644 --- a/cache/memcache/memcache_test.go +++ b/cache/memcache/memcache_test.go @@ -29,7 +29,7 @@ func TestMemcacheCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 * time.Second + timeoutDuration := 10 if err = bm.Put("astaxie", "1", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } diff --git a/cache/redis/redis_test.go b/cache/redis/redis_test.go index e7aa78cb..91efbb3e 100644 --- a/cache/redis/redis_test.go +++ b/cache/redis/redis_test.go @@ -18,8 +18,8 @@ import ( "testing" "time" - "github.com/garyburd/redigo/redis" "github.com/astaxie/beego/cache" + "github.com/garyburd/redigo/redis" ) func TestRedisCache(t *testing.T) { @@ -27,7 +27,7 @@ func TestRedisCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 * time.Second + timeoutDuration := 10 if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { t.Error("set Error", err) } diff --git a/cache/ssdb/ssdb_test.go b/cache/ssdb/ssdb_test.go index 8083f52d..4fea6fd8 100644 --- a/cache/ssdb/ssdb_test.go +++ b/cache/ssdb/ssdb_test.go @@ -18,7 +18,7 @@ func TestSsdbcacheCache(t *testing.T) { if ssdb.IsExist("ssdb") { t.Error("check err") } - timeoutDuration := 10 * time.Second + timeoutDuration := 10 //timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent if err = ssdb.Put("ssdb", "ssdb", timeoutDuration*time.Second); err != nil { t.Error("set Error", err) From e59271662cb815ad644e92a50c81ed38bdb7be8a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 13:25:29 +0800 Subject: [PATCH 74/81] fix bee fix --- cache/cache_test.go | 18 +++++++++--------- cache/memcache/memcache_test.go | 10 +++++----- cache/redis/redis_test.go | 10 +++++----- cache/ssdb/ssdb_test.go | 10 +++++----- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cache/cache_test.go b/cache/cache_test.go index ec344cb1..9ceb606a 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -25,8 +25,8 @@ func TestCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 - if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { + timeoutDuration := 10 * time.Second + if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -43,7 +43,7 @@ func TestCache(t *testing.T) { t.Error("check err") } - if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { t.Error("set Error", err) } @@ -68,7 +68,7 @@ func TestCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -78,7 +78,7 @@ func TestCache(t *testing.T) { t.Error("get err") } - if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { @@ -102,8 +102,8 @@ func TestFileCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 - if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { + timeoutDuration := 10 * time.Second + if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -135,7 +135,7 @@ func TestFileCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -146,7 +146,7 @@ func TestFileCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/memcache/memcache_test.go b/cache/memcache/memcache_test.go index 9b9582f7..0c8c57f2 100644 --- a/cache/memcache/memcache_test.go +++ b/cache/memcache/memcache_test.go @@ -29,8 +29,8 @@ func TestMemcacheCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 - if err = bm.Put("astaxie", "1", timeoutDuration*time.Second); err != nil { + timeoutDuration := 10 * time.Second + if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -42,7 +42,7 @@ func TestMemcacheCache(t *testing.T) { if bm.IsExist("astaxie") { t.Error("check err") } - if err = bm.Put("astaxie", "1", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { t.Error("set Error", err) } @@ -71,7 +71,7 @@ func TestMemcacheCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -83,7 +83,7 @@ func TestMemcacheCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/redis/redis_test.go b/cache/redis/redis_test.go index 91efbb3e..6b81da4d 100644 --- a/cache/redis/redis_test.go +++ b/cache/redis/redis_test.go @@ -27,8 +27,8 @@ func TestRedisCache(t *testing.T) { if err != nil { t.Error("init err") } - timeoutDuration := 10 - if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { + timeoutDuration := 10 * time.Second + if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -40,7 +40,7 @@ func TestRedisCache(t *testing.T) { if bm.IsExist("astaxie") { t.Error("check err") } - if err = bm.Put("astaxie", 1, timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { t.Error("set Error", err) } @@ -69,7 +69,7 @@ func TestRedisCache(t *testing.T) { } //test string - if err = bm.Put("astaxie", "author", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie") { @@ -81,7 +81,7 @@ func TestRedisCache(t *testing.T) { } //test GetMulti - if err = bm.Put("astaxie1", "author1", timeoutDuration*time.Second); err != nil { + if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { t.Error("set Error", err) } if !bm.IsExist("astaxie1") { diff --git a/cache/ssdb/ssdb_test.go b/cache/ssdb/ssdb_test.go index 4fea6fd8..dd474960 100644 --- a/cache/ssdb/ssdb_test.go +++ b/cache/ssdb/ssdb_test.go @@ -18,9 +18,9 @@ func TestSsdbcacheCache(t *testing.T) { if ssdb.IsExist("ssdb") { t.Error("check err") } - timeoutDuration := 10 + timeoutDuration := 10 * time.Second //timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent - if err = ssdb.Put("ssdb", "ssdb", timeoutDuration*time.Second); err != nil { + if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { t.Error("set Error", err) } if !ssdb.IsExist("ssdb") { @@ -28,7 +28,7 @@ func TestSsdbcacheCache(t *testing.T) { } // Get test done - if err = ssdb.Put("ssdb", "ssdb", timeoutDuration*time.Second); err != nil { + if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { t.Error("set Error", err) } @@ -37,7 +37,7 @@ func TestSsdbcacheCache(t *testing.T) { } //inc/dec test done - if err = ssdb.Put("ssdb", "2", timeoutDuration*time.Second); err != nil { + if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil { t.Error("set Error", err) } if err = ssdb.Incr("ssdb"); err != nil { @@ -53,7 +53,7 @@ func TestSsdbcacheCache(t *testing.T) { } // test del - if err = ssdb.Put("ssdb", "3", timeoutDuration*time.Second); err != nil { + if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil { t.Error("set Error", err) } if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 { From 826f81f47951b568088dd709a0407d32474c7f5d Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 15:04:52 +0800 Subject: [PATCH 75/81] remove from init method --- log.go | 3 +++ logs/log.go | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/log.go b/log.go index 214f6d14..e9412f92 100644 --- a/log.go +++ b/log.go @@ -32,6 +32,9 @@ const ( LevelDebug ) +// BeeLogger references the used application logger. +var BeeLogger = logs.GetBeeLogger() + // SetLevel sets the global log level used by the simple logger. func SetLevel(l int) { logs.SetLevel(l) diff --git a/logs/log.go b/logs/log.go index 506e712d..11d54ef8 100644 --- a/logs/log.go +++ b/logs/log.go @@ -120,6 +120,8 @@ type BeeLogger struct { outputs []*nameLogger } +const defaultAsyncMsgLen = 1e3 + type nameLogger struct { Logger name string @@ -157,6 +159,9 @@ func (bl *BeeLogger) Async() *BeeLogger { return bl } bl.asynchronous = true + if bl.msgChanLen <= 0 { + bl.msgChanLen = defaultAsyncMsgLen + } bl.msgChan = make(chan *logMsg, bl.msgChanLen) logMsgPool = &sync.Pool{ New: func() interface{} { @@ -250,6 +255,11 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) { } func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error { + if !beeLogger.init { + bl.lock.Lock() + bl.setLogger(AdapterConsole) + bl.lock.Unlock() + } if logLevel == levelLoggerImpl { // set to emergency to ensure all log will be print out correctly logLevel = LevelEmergency @@ -465,12 +475,8 @@ func (bl *BeeLogger) flush() { } } -// BeeLogger references the used application logger. -var beeLogger *BeeLogger - -func init() { - beeLogger = NewLogger() -} +// beeLogger references the used application logger. +var beeLogger *BeeLogger = NewLogger() // GetLogger returns the default BeeLogger func GetBeeLogger() *BeeLogger { From 45f239012855c4b363dc07ab929ad021dfd97db7 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 25 Mar 2016 15:13:28 +0800 Subject: [PATCH 76/81] logger changed --- logs/log.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/logs/log.go b/logs/log.go index 11d54ef8..107c3b20 100644 --- a/logs/log.go +++ b/logs/log.go @@ -143,8 +143,8 @@ func NewLogger(channelLens ...int64) *BeeLogger { bl.level = LevelDebug bl.loggerFuncCallDepth = 2 bl.msgChanLen = append(channelLens, 0)[0] - if bl.msgChanLen < 0 { - bl.msgChanLen = 0 + if bl.msgChanLen <= 0 { + bl.msgChanLen = defaultAsyncMsgLen } bl.signalChan = make(chan string, 1) bl.setLogger(AdapterConsole) @@ -159,9 +159,6 @@ func (bl *BeeLogger) Async() *BeeLogger { return bl } bl.asynchronous = true - if bl.msgChanLen <= 0 { - bl.msgChanLen = defaultAsyncMsgLen - } bl.msgChan = make(chan *logMsg, bl.msgChanLen) logMsgPool = &sync.Pool{ New: func() interface{} { From 3ca44071e62e31ad1f4e0bbd8750dc95ca2662af Mon Sep 17 00:00:00 2001 From: miraclesu Date: Sat, 26 Mar 2016 21:51:05 +0800 Subject: [PATCH 77/81] orm: insert specified values for insertMulti --- orm/db.go | 6 ++---- orm/orm_test.go | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/orm/db.go b/orm/db.go index af05e686..8c3b82c2 100644 --- a/orm/db.go +++ b/orm/db.go @@ -386,16 +386,14 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul // } if i == 1 { - vus, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz) + vus, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) if err != nil { return cnt, err } values = make([]interface{}, bulk*len(vus)) nums += copy(values, vus) - } else { - - vus, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz) + vus, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, nil, tz) if err != nil { return cnt, err } diff --git a/orm/orm_test.go b/orm/orm_test.go index 2df93729..3f6e1566 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2032,9 +2032,26 @@ func TestInsertAuto(t *testing.T) { Email: "auto@gmail.com", } - sid, err := dORM.Insert(su) + nid, err := dORM.Insert(su) throwFail(t, err) - throwFail(t, AssertIs(id, sid)) + throwFail(t, AssertIs(nid, id)) + + users := []User{ + {ID: int(id + 100), UserName: "auto_100"}, + {ID: int(id + 110), UserName: "auto_110"}, + {ID: int(id + 120), UserName: "auto_120"}, + } + num, err := dORM.InsertMulti(100, users) + throwFail(t, err) + throwFail(t, AssertIs(num, 3)) + + u = &User{ + UserName: "auto_121", + } + + nid, err = dORM.Insert(u) + throwFail(t, err) + throwFail(t, AssertIs(nid, id+120+1)) } func TestUintPk(t *testing.T) { From 1794c52d651cfc04b0655976ae3458f0c4d3df5c Mon Sep 17 00:00:00 2001 From: miraclesu Date: Sun, 27 Mar 2016 15:06:57 +0800 Subject: [PATCH 78/81] orm: fix postgres sequence value --- orm/db.go | 47 ++++++++++++++++++++++++++++++++++------------ orm/db_postgres.go | 19 +++++++++++++++++++ orm/types.go | 1 + 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/orm/db.go b/orm/db.go index 8c3b82c2..efc90e6e 100644 --- a/orm/db.go +++ b/orm/db.go @@ -71,7 +71,7 @@ type dbBase struct { var _ dbBaser = new(dbBase) // get struct columns values as interface slice. -func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, skipAuto bool, insert bool, names *[]string, tz *time.Location) (values []interface{}, err error) { +func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, skipAuto bool, insert bool, names *[]string, tz *time.Location) (values []interface{}, autoFields []string, err error) { if names == nil { ns := make([]string, 0, len(cols)) names = &ns @@ -90,11 +90,11 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, } value, err := d.collectFieldValue(mi, fi, ind, insert, tz) if err != nil { - return nil, err + return nil, nil, err } // ignore empty value auto field - if fi.auto { + if insert && fi.auto { if fi.fieldType&IsPositiveIntegerField > 0 { if vu, ok := value.(uint64); !ok || vu == 0 { continue @@ -104,6 +104,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, continue } } + autoFields = append(autoFields, fi.column) } *names, values = append(*names, column), append(values, value) @@ -278,7 +279,7 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, // insert struct with prepared statement and given struct reflect value. func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { - values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz) + values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz) if err != nil { return 0, err } @@ -305,7 +306,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo if len(cols) > 0 { var err error whereCols = make([]string, 0, len(cols)) - args, err = d.collectValues(mi, ind, cols, false, false, &whereCols, tz) + args, _, err = d.collectValues(mi, ind, cols, false, false, &whereCols, tz) if err != nil { return err } @@ -355,12 +356,20 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo // execute insert sql dbQuerier with given struct reflect.Value. func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { names := make([]string, 0, len(mi.fields.dbcols)) - values, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) + values, autoFields, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) if err != nil { return 0, err } - return d.InsertValue(q, mi, false, names, values) + id, err := d.InsertValue(q, mi, false, names, values) + if err != nil { + return 0, err + } + + if len(autoFields) > 0 { + err = d.ins.setval(q, mi, autoFields) + } + return id, err } // multi-insert sql with given slice struct reflect.Value. @@ -374,7 +383,7 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul // typ := reflect.Indirect(mi.addrField).Type() - length := sind.Len() + length, autoFields := sind.Len(), make([]string, 0, 1) for i := 1; i <= length; i++ { @@ -386,14 +395,18 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul // } if i == 1 { - vus, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) + var ( + vus []interface{} + err error + ) + vus, autoFields, err = d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) if err != nil { return cnt, err } values = make([]interface{}, bulk*len(vus)) nums += copy(values, vus) } else { - vus, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, nil, tz) + vus, _, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, nil, tz) if err != nil { return cnt, err } @@ -415,7 +428,12 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul } } - return cnt, nil + var err error + if len(autoFields) > 0 { + err = d.ins.setval(q, mi, autoFields) + } + + return cnt, err } // execute insert sql with given struct and given values. @@ -475,7 +493,7 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. setNames = make([]string, 0, len(cols)) } - setValues, err := d.collectValues(mi, ind, cols, true, false, &setNames, tz) + setValues, _, err := d.collectValues(mi, ind, cols, true, false, &setNames, tz) if err != nil { return 0, err } @@ -1565,6 +1583,11 @@ func (d *dbBase) HasReturningID(*modelInfo, *string) bool { return false } +// sync auto key +func (d *dbBase) setval(db dbQuerier, mi *modelInfo, autoFields []string) error { + return nil +} + // convert time from db. func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) { *t = t.In(tz) diff --git a/orm/db_postgres.go b/orm/db_postgres.go index be4cd0bc..8fbcb88d 100644 --- a/orm/db_postgres.go +++ b/orm/db_postgres.go @@ -135,6 +135,25 @@ func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) bool { return true } +// sync auto key +func (d *dbBasePostgres) setval(db dbQuerier, mi *modelInfo, autoFields []string) error { + if len(autoFields) == 0 { + return nil + } + + Q := d.ins.TableQuote() + for _, name := range autoFields { + query := fmt.Sprintf("SELECT setval(pg_get_serial_sequence('%s', '%s'), (SELECT MAX(%s%s%s) FROM %s%s%s));", + mi.table, name, + Q, name, Q, + Q, mi.table, Q) + if _, err := db.Exec(query); err != nil { + return err + } + } + return nil +} + // show table sql for postgresql. func (d *dbBasePostgres) ShowTablesQuery() string { return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')" diff --git a/orm/types.go b/orm/types.go index 41933dd1..cb55e71a 100644 --- a/orm/types.go +++ b/orm/types.go @@ -420,4 +420,5 @@ type dbBaser interface { ShowColumnsQuery(string) string IndexExists(dbQuerier, string, string) bool collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error) + setval(dbQuerier, *modelInfo, []string) error } From fb77464d69cb7cce2e0420482efb8e03f90fd272 Mon Sep 17 00:00:00 2001 From: miraclesu Date: Sun, 27 Mar 2016 15:07:51 +0800 Subject: [PATCH 79/81] golink: map range only key stlye --- error_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/error_test.go b/error_test.go index f6e40c80..2fb8f962 100644 --- a/error_test.go +++ b/error_test.go @@ -41,7 +41,7 @@ func (ec *errorTestController) Get() { func TestErrorCode_01(t *testing.T) { registerDefaultErrorHandler() - for k, _ := range ErrorMaps { + for k := range ErrorMaps { r, _ := http.NewRequest("GET", "/error?code="+k, nil) w := httptest.NewRecorder() From f05bb2ecd33f4f38d21da165e122fcf2011964db Mon Sep 17 00:00:00 2001 From: JessonChan Date: Mon, 28 Mar 2016 15:18:51 +0800 Subject: [PATCH 80/81] add function of beego/logs --- logs/log.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/logs/log.go b/logs/log.go index 107c3b20..695691b2 100644 --- a/logs/log.go +++ b/logs/log.go @@ -152,13 +152,16 @@ func NewLogger(channelLens ...int64) *BeeLogger { } // Async set the log to asynchronous and start the goroutine -func (bl *BeeLogger) Async() *BeeLogger { +func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger { bl.lock.Lock() defer bl.lock.Unlock() if bl.asynchronous { return bl } bl.asynchronous = true + if len(msgLen) > 0 && msgLen[0] > 0 { + bl.msgChanLen = msgLen[0] + } bl.msgChan = make(chan *logMsg, bl.msgChanLen) logMsgPool = &sync.Pool{ New: func() interface{} { @@ -515,8 +518,8 @@ func Reset() { beeLogger.Reset() } -func Async() *BeeLogger { - return beeLogger.Async() +func Async(msgLen ...int64) *BeeLogger { + return beeLogger.Async(msgLen...) } // SetLevel sets the global log level used by the simple logger. @@ -524,12 +527,22 @@ func SetLevel(l int) { beeLogger.SetLevel(l) } +// EnableFuncCallDepth enable log funcCallDepth +func EnableFuncCallDepth(b bool) { + beeLogger.enableFuncCallDepth = b +} + // SetLogFuncCall set the CallDepth, default is 3 func SetLogFuncCall(b bool) { beeLogger.EnableFuncCallDepth(b) beeLogger.SetLogFuncCallDepth(3) } +// SetLogFuncCallDepth set log funcCallDepth +func SetLogFuncCallDepth(d int) { + beeLogger.loggerFuncCallDepth = d +} + // SetLogger sets a new logger. func SetLogger(adapter string, config ...string) error { err := beeLogger.SetLogger(adapter, config...) From 221306fff4a2614a6717e53f471f03fc275ac30a Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 29 Mar 2016 10:05:56 +0800 Subject: [PATCH 81/81] file rotate bug --- logs/file.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/logs/file.go b/logs/file.go index 159d4970..5901143b 100644 --- a/logs/file.go +++ b/logs/file.go @@ -60,14 +60,11 @@ type fileLogWriter struct { // newFileWriter create a FileLogWriter returning as LoggerInterface. func newFileWriter() Logger { w := &fileLogWriter{ - Filename: "", - MaxLines: 1000000, - MaxSize: 1 << 28, //256 MB - Daily: true, - MaxDays: 7, - Rotate: true, - Level: LevelTrace, - Perm: 0660, + Daily: true, + MaxDays: 7, + Rotate: true, + Level: LevelTrace, + Perm: 0660, } return w } @@ -259,8 +256,8 @@ func (w *fileLogWriter) deleteOldLog() { } }() - if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.MaxDays) { - if strings.HasPrefix(filepath.Base(path), w.fileNameOnly) && + if !info.IsDir() && info.ModTime().Add(24*time.Hour*time.Duration(w.MaxDays)).Before(time.Now()) { + if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) && strings.HasSuffix(filepath.Base(path), w.suffix) { os.Remove(path) }