From df07afb74452a3c617db218712c1e42276041fc5 Mon Sep 17 00:00:00 2001 From: hoteas Date: Tue, 25 May 2021 05:08:17 +0800 Subject: [PATCH] use logrus to project default log tools --- LICENSE | 32 ++--- application.go | 221 ++++++++++++++++++---------------- common/const.go | 16 --- common/context_base.go | 12 +- common/error.go | 18 +-- common/func.go | 81 ------------- common/slice.go | 68 +++++------ const.go | 4 + context.go | 30 ++--- db/db.go | 267 +++++++++++++++++++++-------------------- example/main.go | 17 ++- log/logrus.go | 114 ++++++++++++++++++ session.go | 54 ++++----- type.go | 2 +- var.go | 12 +- 15 files changed, 491 insertions(+), 457 deletions(-) delete mode 100644 common/const.go create mode 100644 const.go create mode 100644 log/logrus.go diff --git a/LICENSE b/LICENSE index 4ed90b9..96e642d 100644 --- a/LICENSE +++ b/LICENSE @@ -10,7 +10,7 @@ AND DISTRIBUTION "License" shall mean the terms and conditions for use, reproduction, and distribution -as defined by Sections 1 through 9 of this document. +as defined by Sections 1 through 9 of that document. @@ -21,7 +21,7 @@ owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct +For the purposes of that definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. @@ -29,7 +29,7 @@ of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions -granted by this License. +granted by that License. @@ -55,7 +55,7 @@ below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative +original work of authorship. For the purposes of that License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. @@ -65,7 +65,7 @@ bind by name) to the interfaces of, the Work and Derivative Works thereof. of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized -to submit on behalf of the copyright owner. For the purposes of this definition, +to submit on behalf of the copyright owner. For the purposes of that definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and @@ -80,15 +80,15 @@ owner as "Not a Contribution." of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. -2. Grant of Copyright License. Subject to the terms and conditions of this +2. Grant of Copyright License. Subject to the terms and conditions of that License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. -3. Grant of Patent License. Subject to the terms and conditions of this License, +3. Grant of Patent License. Subject to the terms and conditions of that License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) patent +no-charge, royalty-free, irrevocable (except as stated in that section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) @@ -97,7 +97,7 @@ Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You -under this License for that Work shall terminate as of the date such litigation +under that License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or @@ -105,7 +105,7 @@ Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy -of this License; and +of that License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and @@ -133,11 +133,11 @@ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise -complies with the conditions stated in this License. +complies with the conditions stated in that License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the -Licensor shall be under the terms and conditions of this License, without +Licensor shall be under the terms and conditions of that License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. @@ -154,14 +154,14 @@ KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your -exercise of permissions under this License. +exercise of permissions under that License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any -character arising as a result of this License or out of the use or inability +character arising as a result of that License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility @@ -170,7 +170,7 @@ of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations -and/or rights consistent with this License. However, in accepting such obligations, +and/or rights consistent with that License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims @@ -191,7 +191,7 @@ Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. +you may not use that file except in compliance with the License. You may obtain a copy of the License at diff --git a/application.go b/application.go index 70c8bb7..92d3612 100644 --- a/application.go +++ b/application.go @@ -4,6 +4,7 @@ import ( . "./cache" . "./common" . "./db" + . "./log" "bytes" "database/sql" "encoding/json" @@ -21,7 +22,8 @@ type Application struct { MethodRouter Router ContextBase - Log logrus.Logger + Log *logrus.Logger + WebConnectLog *logrus.Logger Port string //端口号 TLSPort string //ssl访问端口号 connectListener []func(this *Context) bool //所有的访问监听,true按原计划继续使用,false表示有监听器处理 @@ -29,44 +31,44 @@ type Application struct { configPath string Config Map Db HoTimeDB - Server *http.Server + *http.Server CacheIns sessionLong CacheIns sessionShort CacheIns http.Handler } -func (this *Application) ServeHTTP(w http.ResponseWriter, req *http.Request) { - this.handler(w, req) +func (that *Application) ServeHTTP(w http.ResponseWriter, req *http.Request) { + that.handler(w, req) } -//启动实例 -func (this *Application) Run(router Router) { +// Run 启动实例 +func (that *Application) Run(router Router) { //如果没有设置配置自动生成配置 - if this.configPath == "" || len(this.Config) == 0 { - this.SetConfig() + if that.configPath == "" || len(that.Config) == 0 { + that.SetConfig() } //防止手动设置缓存误伤 - if this.CacheIns == nil { - this.SetCache(CacheIns(&CacheMemory{})) + if that.CacheIns == nil { + that.SetCache(CacheIns(&CacheMemory{})) } //防止手动设置session误伤 - //if this.sessionShort == nil && this.sessionLong == nil { - // if this.connectDbFunc == nil { - // this.SetSession(CacheIns(&CacheMemory{}), nil) + //if that.sessionShort == nil && that.sessionLong == nil { + // if that.connectDbFunc == nil { + // that.SetSession(CacheIns(&CacheMemory{}), nil) // } else { - // this.SetSession(CacheIns(&CacheMemory{}), CacheIns(&CacheDb{Db: &this.Db, Time: this.Config.GetInt64("cacheLongTime")})) + // that.SetSession(CacheIns(&CacheMemory{}), CacheIns(&CacheDb{Db: &that.Db, Time: that.Config.GetInt64("cacheLongTime")})) // } // //} - this.Router = router + that.Router = router //重新设置MethodRouter//直达路由 - this.MethodRouter = MethodRouter{} + that.MethodRouter = MethodRouter{} modeRouterStrict := true - if this.Config.Get("modeRouterStrict").(bool) == false { + if that.Config.GetBool("modeRouterStrict") == false { modeRouterStrict = false } if router != nil { @@ -84,7 +86,7 @@ func (this *Application) Run(router Router) { if !modeRouterStrict { mk = strings.ToLower(mk) } - this.MethodRouter["/"+pk+"/"+ck+"/"+mk] = mv + that.MethodRouter["/"+pk+"/"+ck+"/"+mk] = mv } } } @@ -92,137 +94,139 @@ func (this *Application) Run(router Router) { } } - //this.Port = port - this.Port = this.Config.GetString("port") - this.TLSPort = this.Config.GetString("tlsPort") + //that.Port = port + that.Port = that.Config.GetString("port") + that.TLSPort = that.Config.GetString("tlsPort") - if this.connectDbFunc != nil && (this.Db.DB == nil || this.Db.DB.Ping() != nil) { - this.Db.SetConnect(this.connectDbFunc) + if that.connectDbFunc != nil && (that.Db.DB == nil || that.Db.DB.Ping() != nil) { + that.Db.SetConnect(that.connectDbFunc) } - if this.CacheIns == nil { - this.CacheIns = CacheIns(&CacheMemory{Map: Map{}, Time: this.Config.GetInt64("cacheShortTime")}) + if that.CacheIns == nil { + that.CacheIns = CacheIns(&CacheMemory{Map: Map{}, Time: that.Config.GetInt64("cacheShortTime")}) } //异常处理 defer func() { if err := recover(); err != nil { - //this.SetError(errors.New(fmt.Sprint(err)), LOG_FMT) - LogFmt(err, 2, LOG_ERROR) + //that.SetError(errors.New(fmt.Sprint(err)), LOG_FMT) + that.Log.Warn(err) - this.Run(router) + that.Run(router) } }() - this.Server = &http.Server{} + that.Server = &http.Server{} if !IsRun { IsRun = true } ch := make(chan int) - if ObjToCeilInt(this.Port) != 0 { + if ObjToCeilInt(that.Port) != 0 { go func() { - App[this.Port] = this - this.Server.Handler = this + App[that.Port] = that + that.Server.Handler = that //启动服务 - this.Server.Addr = ":" + this.Port - err := this.Server.ListenAndServe() - LogFmt(err, 2) + that.Server.Addr = ":" + that.Port + err := that.Server.ListenAndServe() + that.Log.Error(err) ch <- 1 }() } - if ObjToCeilInt(this.TLSPort) != 0 { + if ObjToCeilInt(that.TLSPort) != 0 { go func() { - App[this.TLSPort] = this - this.Server.Handler = this + App[that.TLSPort] = that + that.Server.Handler = that //启动服务 - this.Server.Addr = ":" + this.TLSPort - err := this.Server.ListenAndServeTLS(this.Config.GetString("tlsCert"), this.Config.GetString("tlsKey")) - LogFmt(err, 2) + that.Server.Addr = ":" + that.TLSPort + err := that.Server.ListenAndServeTLS(that.Config.GetString("tlsCert"), that.Config.GetString("tlsKey")) + that.Log.Error(err) ch <- 2 }() } - if ObjToCeilInt(this.Port) == 0 && ObjToCeilInt(this.TLSPort) == 0 { - LogFmt("没有端口启用", 2, LOG_INFO) + if ObjToCeilInt(that.Port) == 0 && ObjToCeilInt(that.TLSPort) == 0 { + that.Log.Error("没有端口启用") return } value := <-ch - LogFmt("启动服务失败 : "+ObjToStr(value), 2, LOG_ERROR) + that.Log.Error("启动服务失败 : " + ObjToStr(value)) } -//启动实例 -func (this *Application) SetConnectDB(connect func(err ...*Error) (master, slave *sql.DB)) { +// SetConnectDB 启动实例 +func (that *Application) SetConnectDB(connect func(err ...*Error) (master, slave *sql.DB)) { - this.connectDbFunc = connect - this.Db.SetConnect(this.connectDbFunc) + that.connectDbFunc = connect + that.Db.SetConnect(that.connectDbFunc) } -//设置配置文件路径全路径或者相对路径 -func (this *Application) SetSession(short CacheIns, Long CacheIns) { - this.sessionLong = Long - this.sessionShort = short +// SetSession 设置配置文件路径全路径或者相对路径 +func (that *Application) SetSession(short CacheIns, Long CacheIns) { + that.sessionLong = Long + that.sessionShort = short } -//默认配置缓存和session实现 -func (this *Application) SetDefault(connect func(err ...*Error) (*sql.DB, *sql.DB)) { - this.SetConfig() +// SetDefault 默认配置缓存和session实现 +func (that *Application) SetDefault(connect func(err ...*Error) (*sql.DB, *sql.DB)) { + that.SetConfig() if connect != nil { - this.connectDbFunc = connect - this.Db.SetConnect(this.connectDbFunc) + that.connectDbFunc = connect + that.Db.SetConnect(that.connectDbFunc) } } -//设置配置文件路径全路径或者相对路径 -func (this *Application) SetCache(cache CacheIns) { +// SetCache 设置配置文件路径全路径或者相对路径 +func (that *Application) SetCache(cache CacheIns) { - this.CacheIns = cache + that.CacheIns = cache } -//设置配置文件路径全路径或者相对路径 -func (this *Application) SetConfig(configPath ...string) { +// SetConfig 设置配置文件路径全路径或者相对路径 +func (that *Application) SetConfig(configPath ...string) { + + that.Log = GetLog("", true) if len(configPath) != 0 { - this.configPath = configPath[0] + that.configPath = configPath[0] } - if this.configPath == "" { - this.configPath = "config/config.json" + if that.configPath == "" { + that.configPath = "config/config.json" } //加载配置文件 - btes, err := ioutil.ReadFile(this.configPath) - this.Config = DeepCopyMap(Config).(Map) + btes, err := ioutil.ReadFile(that.configPath) + that.Config = DeepCopyMap(Config).(Map) if err == nil { cmap := Map{} //文件是否损坏 - cmap.JsonToMap(string(btes), &this.Error) + cmap.JsonToMap(string(btes), &that.Error) for k, v := range cmap { - this.Config[k] = v //程序配置 + that.Config[k] = v //程序配置 Config[k] = v //系统配置 } } else { - LogFmt("配置文件不存在,或者配置出错,使用缺省默认配置", 2) + that.Log.Error("配置文件不存在,或者配置出错,使用缺省默认配置") } //文件如果损坏则不写入配置防止配置文件数据丢失 - if this.Error.GetError() == nil { + if that.Error.GetError() == nil { var configByte bytes.Buffer - err = json.Indent(&configByte, []byte(this.Config.ToJsonString()), "", "\t") + err = json.Indent(&configByte, []byte(that.Config.ToJsonString()), "", "\t") //判断配置文件是否序列有变化有则修改配置,五则不变 //fmt.Println(len(btes)) if len(btes) != 0 && configByte.String() == string(btes) { @@ -230,22 +234,26 @@ func (this *Application) SetConfig(configPath ...string) { } //写入配置说明 var configNoteByte bytes.Buffer - json.Indent(&configNoteByte, []byte(ConfigNote.ToJsonString()), "", "\t") + _ = json.Indent(&configNoteByte, []byte(ConfigNote.ToJsonString()), "", "\t") - os.MkdirAll(filepath.Dir(this.configPath), os.ModeDir) - err = ioutil.WriteFile(this.configPath, configByte.Bytes(), os.ModeAppend) + _ = os.MkdirAll(filepath.Dir(that.configPath), os.ModeDir) + err = ioutil.WriteFile(that.configPath, configByte.Bytes(), os.ModeAppend) if err != nil { - this.Error.SetError(err) + that.Error.SetError(err) } - ioutil.WriteFile(filepath.Dir(this.configPath)+"/confignote.json", configNoteByte.Bytes(), os.ModeAppend) + _ = ioutil.WriteFile(filepath.Dir(that.configPath)+"/configNote.json", configNoteByte.Bytes(), os.ModeAppend) } + that.Log = GetLog(that.Config.GetString("logFile"), true) + if that.Config.GetBool("webConnectLogShow") { + that.WebConnectLog = GetLog(that.Config.GetString("webConnectLogFile"), false) + } } -//连接判断,返回true继续传输至控制层,false则停止传输 -func (this *Application) SetConnectListener(lis func(this *Context) bool) { - this.connectListener = append(this.connectListener, lis) +// SetConnectListener 连接判断,返回true继续传输至控制层,false则停止传输 +func (that *Application) SetConnectListener(lis func(this *Context) bool) { + that.connectListener = append(that.connectListener, lis) } //网络错误 @@ -254,7 +262,7 @@ func (this *Application) SetConnectListener(lis func(this *Context) bool) { //} //序列化链接 -func (this *Application) urlSer(url string) (string, []string) { +func (that *Application) urlSer(url string) (string, []string) { q := strings.Index(url, "?") if q == -1 { q = len(url) @@ -275,9 +283,9 @@ func (this *Application) urlSer(url string) (string, []string) { //访问 -func (this *Application) handler(w http.ResponseWriter, req *http.Request) { +func (that *Application) handler(w http.ResponseWriter, req *http.Request) { - _, s := this.urlSer(req.RequestURI) + _, s := that.urlSer(req.RequestURI) //获取cookie // 如果cookie存在直接将sessionId赋值为cookie.Value // 如果cookie不存在就查找传入的参数中是否有token @@ -285,7 +293,7 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { // 如果token存在就判断token是否在Session中有保存 // 如果有取出token并复制给cookie // 没有保存就生成随机的session - cookie, err := req.Cookie(this.Config.GetString("sessionName")) + cookie, err := req.Cookie(that.Config.GetString("sessionName")) sessionId := Md5(strconv.Itoa(Rand(10))) token := req.FormValue("token") //isFirst:=false @@ -296,7 +304,7 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { //else{ // isFirst=true; //} - http.SetCookie(w, &http.Cookie{Name: this.Config.GetString("sessionName"), Value: sessionId, Path: "/"}) + http.SetCookie(w, &http.Cookie{Name: that.Config.GetString("sessionName"), Value: sessionId, Path: "/"}) } else { sessionId = cookie.Value } @@ -307,31 +315,31 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { } //访问实例 context := Context{SessionIns: SessionIns{SessionId: sessionId, - LongCache: this.sessionLong, - ShortCache: this.sessionShort, + LongCache: that.sessionLong, + ShortCache: that.sessionShort, }, - CacheIns: this.CacheIns, - Resp: w, Req: req, Application: this, RouterString: s, Config: this.Config, Db: &this.Db, HandlerStr: unescapeUrl} + CacheIns: that.CacheIns, + Resp: w, Req: req, Application: that, RouterString: s, Config: that.Config, Db: &that.Db, HandlerStr: unescapeUrl} //header默认设置 header := w.Header() header.Set("Content-Type", "text/html; charset=utf-8") //url去掉参数并序列化 - context.HandlerStr, context.RouterString = this.urlSer(context.HandlerStr) + context.HandlerStr, context.RouterString = that.urlSer(context.HandlerStr) //跨域设置 - this.crossDomain(&context) + that.crossDomain(&context) //是否展示日志 - if this.Config.GetInt("connectLogShow") != 0 { - LogFmt(Substr(context.Req.RemoteAddr, 0, strings.Index(context.Req.RemoteAddr, ":"))+" "+context.HandlerStr, 0, LOG_INFO) + if that.WebConnectLog != nil { + that.WebConnectLog.Infoln(Substr(context.Req.RemoteAddr, 0, strings.Index(context.Req.RemoteAddr, ":")) + " " + context.HandlerStr) } //访问拦截true继续false暂停 - connectListenerLen := len(this.connectListener) + connectListenerLen := len(that.connectListener) if connectListenerLen != 0 { for i := 0; i < connectListenerLen; i++ { - if !this.connectListener[i](&context) { + if !that.connectListener[i](&context) { context.View() return @@ -342,9 +350,9 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { //接口服务 //if len(s) == 3 { // //如果满足规则则路由到对应控制器去 - // if this.Router[s[0]] != nil && this.Router[s[0]][s[1]] != nil && this.Router[s[0]][s[1]][s[2]] != nil { + // if that.Router[s[0]] != nil && that.Router[s[0]][s[1]] != nil && that.Router[s[0]][s[1]][s[2]] != nil { // //控制层 - // this.Router[s[0]][s[1]][s[2]](&context) + // that.Router[s[0]][s[1]][s[2]](&context) // //header.Set("Content-Type", "text/html; charset=utf-8") // context.View() // return @@ -352,25 +360,25 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { // //} //验证接口严格模式 - modeRouterStrict := this.Config.Get("modeRouterStrict").(bool) + modeRouterStrict := that.Config.GetBool("modeRouterStrict") tempHandlerStr := context.HandlerStr if !modeRouterStrict { tempHandlerStr = strings.ToLower(tempHandlerStr) } //执行接口 - if this.MethodRouter[tempHandlerStr] != nil { - this.MethodRouter[tempHandlerStr](&context) + if that.MethodRouter[tempHandlerStr] != nil { + that.MethodRouter[tempHandlerStr](&context) context.View() return } //url赋值 - path := this.Config.GetString("tpt") + tempHandlerStr + path := that.Config.GetString("tpt") + tempHandlerStr //判断是否为默认 if path[len(path)-1] == '/' { - defFile := this.Config.GetSlice("defFile") + defFile := that.Config.GetSlice("defFile") for i := 0; i < len(defFile); i++ { temp := path + defFile.GetString(i) @@ -394,7 +402,7 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { //设置header delete(header, "Content-Type") - if this.Config.GetInt("debug") != 1 { + if that.Config.GetInt("debug") != 1 { header.Set("Cache-Control", "public") } @@ -407,7 +415,7 @@ func (this *Application) handler(w http.ResponseWriter, req *http.Request) { } -func (this *Application) crossDomain(context *Context) { +func (that *Application) crossDomain(context *Context) { //没有跨域设置 if context.Config.GetString("crossDomain") == "" { return @@ -421,7 +429,7 @@ func (this *Application) crossDomain(context *Context) { header.Set("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,Access-Token") if context.Config.GetString("crossDomain") != "auto" { - header.Set("Access-Control-Allow-Origin", this.Config.GetString("crossDomain")) + header.Set("Access-Control-Allow-Origin", that.Config.GetString("crossDomain")) return } @@ -450,6 +458,7 @@ func (this *Application) crossDomain(context *Context) { } } +//Init 初始化application func Init(config string) Application { appIns := Application{} //手动模式, @@ -459,7 +468,7 @@ func Init(config string) Application { return appIns } -//后期整改 +// SetDB 智能数据库设置 func SetDB(appIns *Application) { db := appIns.Config.GetMap("db") dbSqlite := db.GetMap("sqlite") diff --git a/common/const.go b/common/const.go deleted file mode 100644 index c2a00d0..0000000 --- a/common/const.go +++ /dev/null @@ -1,16 +0,0 @@ -package common - -type LOG_MODE int - -const ( - LOG_NIL = 0 - LOG_FMT = 1 - //LOG_FILE = 2 - - LOG_INFO LOG_MODE = 0 - LOG_WARN LOG_MODE = 1 - LOG_ERROR LOG_MODE = 2 -) - -//session储存头 -const HEAD_SESSION_ADD = "session#" diff --git a/common/context_base.go b/common/context_base.go index c8156cc..1b7957a 100644 --- a/common/context_base.go +++ b/common/context_base.go @@ -1,17 +1,19 @@ package common -import "time" +import ( + "time" +) type ContextBase struct { Error - tag int64 + tag string } //唯一标志 -func (this *ContextBase) GetTag() int64 { +func (this *ContextBase) GetTag() string { - if this.tag == int64(0) { - this.tag = time.Now().UnixNano() + if this.tag == "" { + this.tag = ObjToStr(time.Now().Unix()) + ":" + ObjToStr(Random()) } return this.tag } diff --git a/common/error.go b/common/error.go index 96bb454..39647df 100644 --- a/common/error.go +++ b/common/error.go @@ -1,25 +1,17 @@ package common -//框架层处理错误 +// Error 框架层处理错误 type Error struct { error - err error } -func (this *Error) GetError() error { +func (that *Error) GetError() error { - return this.error + return that.error } -func (this *Error) SetError(err error, loglevel ...int) { - - this.error = nil - if err == nil { - this.error = err - this.err = err - return - } - this.error = err +func (that *Error) SetError(err error) { + that.error = err return } diff --git a/common/func.go b/common/func.go index ac1443a..c9f9e83 100644 --- a/common/func.go +++ b/common/func.go @@ -3,7 +3,6 @@ package common import ( "crypto/md5" "encoding/hex" - "fmt" "math" "strings" ) @@ -25,86 +24,6 @@ import ( // return res //} -//func LogError(logMsg interface{}) { -// -// logFmt(fmt.Sprintln(logMsg), 2, LOG_ERROR) -//} -//func LogWarn(logMsg interface{}) { -// -// logFmt(fmt.Sprintln(logMsg), 2, LOG_WARN) -//} -//func LogInfo(logMsg ...interface{}) { -// -// logFmt(fmt.Sprintln(logMsg), 2, LOG_INFO) -//} -// -//func LogFmt(logMsg interface{}, loglevel ...LOG_MODE) { -// -// logFmt(logMsg, 2, loglevel...) -//} -// -////日志打印以及存储到文件 -//func logFmt(logMsg interface{}, printLevel int, loglevel ...LOG_MODE) { -// -// if Config.GetInt("logLevel") == int(LOG_NIL) { -// return -// } -// -// lev := LOG_INFO -// if len(loglevel) != 0 { -// lev = loglevel[0] -// } -// gofile := "" -// -// if Config.GetInt("debug") != 0 && printLevel != 0 { -// _, file, line, ok := runtime.Caller(printLevel) -// if ok { -// gofile = " " + file + ":" + ObjToStr(line) -// } -// } -// -// logStr := "" -// -// if lev == LOG_INFO { -// logStr = "info:" -// } -// if printLevel == 0 { -// logStr = "connect:" -// } -// -// if lev == LOG_WARN { -// logStr = "warn:" -// } -// -// if lev == LOG_ERROR { -// logStr = "error:" -// } -// -// logStr = fmt.Sprintln(time.Now().Format("2006/01/02 15:04:05"), logStr, logMsg, gofile) -// //打印日志 -// fmt.Print(logStr) -// //不需要存储到文件 -// if Config.GetString("logFile") == "" { -// return -// } -// //存储到文件 -// logFilePath := time.Now().Format(Config.GetString("logFile")) -// -// os.MkdirAll(filepath.Dir(logFilePath), os.ModeAppend) -// //os.Create(logFilePath) -// f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE, 0644) -// if err != nil { -// return -// } -// f.Write([]byte(logStr)) -// f.Close() -// -//} -//日志打印以及存储到文件 -func LogFmt(logMsg interface{}, printLevel int, loglevel ...LOG_MODE) { - fmt.Println(logMsg) -} - //字符串首字符大写 func StrFirstToUpper(str string) string { if len(str) == 0 { diff --git a/common/slice.go b/common/slice.go index b38dcd1..05b1f95 100644 --- a/common/slice.go +++ b/common/slice.go @@ -6,79 +6,79 @@ import ( type Slice []interface{} -//获取string -func (this Slice) GetString(key int, err ...*Error) string { +// GetString 获取string +func (that Slice) GetString(key int, err ...*Error) string { if len(err) != 0 { err[0].SetError(nil) } - return ObjToStr((this)[key]) + return ObjToStr((that)[key]) } -//获取Int -func (this Slice) GetInt(key int, err ...*Error) int { - v := ObjToInt((this)[key], err...) +// GetInt 获取Int +func (that Slice) GetInt(key int, err ...*Error) int { + v := ObjToInt((that)[key], err...) return v } -//获取Int -func (this Slice) GetInt64(key int, err ...*Error) int64 { - v := ObjToInt64((this)[key], err...) +// GetInt64 获取Int +func (that Slice) GetInt64(key int, err ...*Error) int64 { + v := ObjToInt64((that)[key], err...) return v } -//获取向上取整Int64 -func (this Slice) GetCeilInt64(key int, err ...*Error) int64 { - v := ObjToCeilInt64((this)[key], err...) +// GetCeilInt64 获取向上取整Int64 +func (that Slice) GetCeilInt64(key int, err ...*Error) int64 { + v := ObjToCeilInt64((that)[key], err...) return v } -//获取向上取整Int -func (this Slice) GetCeilInt(key int, err ...*Error) int { - v := ObjToCeilInt((this)[key], err...) +// GetCeilInt 获取向上取整Int +func (that Slice) GetCeilInt(key int, err ...*Error) int { + v := ObjToCeilInt((that)[key], err...) return v } -//获取向上取整float64 -func (this Slice) GetCeilFloat64(key int, err ...*Error) float64 { - v := ObjToCeilFloat64((this)[key], err...) +// GetCeilFloat64 获取向上取整float64 +func (that Slice) GetCeilFloat64(key int, err ...*Error) float64 { + v := ObjToCeilFloat64((that)[key], err...) return v } -//获取Float64 -func (this Slice) GetFloat64(key int, err ...*Error) float64 { - v := ObjToFloat64((this)[key], err...) +// GetFloat64 获取Float64 +func (that Slice) GetFloat64(key int, err ...*Error) float64 { + v := ObjToFloat64((that)[key], err...) return v } -func (this Slice) GetSlice(key int, err ...*Error) Slice { - v := ObjToSlice((this)[key], err...) +func (that Slice) GetSlice(key int, err ...*Error) Slice { + v := ObjToSlice((that)[key], err...) return v } -func (this Slice) GetBool(key int, err ...*Error) bool { +func (that Slice) GetBool(key int, err ...*Error) bool { //var v Slice - v := ObjToBool((this)[key], err...) + v := ObjToBool((that)[key], err...) return v } -func (this Slice) GetMap(key int, err ...*Error) Map { +func (that Slice) GetMap(key int, err ...*Error) Map { //var v Map - v := ObjToMap((this)[key], err...) + v := ObjToMap((that)[key], err...) return v } -func (this Slice) Get(key int, err ...*Error) interface{} { +func (that Slice) Get(key int, err ...*Error) interface{} { - if key < len(this) { - return this[key] + if key < len(that) { + return that[key] } e := errors.New("没有存储key及对应的数据") if len(err) != 0 { @@ -87,10 +87,10 @@ func (this Slice) Get(key int, err ...*Error) interface{} { return nil } -func (this Slice) Put(key int, value interface{}) { - this[key] = value +func (that Slice) Put(key int, value interface{}) { + that[key] = value } -func (this Slice) ToJsonString() string { - return ObjToStr(this) +func (that Slice) ToJsonString() string { + return ObjToStr(that) } diff --git a/const.go b/const.go new file mode 100644 index 0000000..7874cd3 --- /dev/null +++ b/const.go @@ -0,0 +1,4 @@ +package hotime + +//session储存头 +const HEAD_SESSION_ADD = "session#" diff --git a/context.go b/context.go index d427bb8..2b452e2 100644 --- a/context.go +++ b/context.go @@ -9,10 +9,10 @@ import ( ) type Context struct { + *Application ContextBase Resp http.ResponseWriter Req *http.Request - Application *Application RouterString []string Config Map Db *HoTimeDB @@ -22,22 +22,22 @@ type Context struct { HandlerStr string //复写请求url } -//唯一标志 -func (this *Context) Mtd(router [3]string) Map { - this.Application.Router[router[0]][router[1]][router[2]](this) - d := this.RespData - this.RespData = nil +// Mtd 唯一标志 +func (that *Context) Mtd(router [3]string) Map { + that.Application.Router[router[0]][router[1]][router[2]](that) + d := that.RespData + that.RespData = nil return d } //打印 -func (this *Context) Display(statu int, data interface{}) { +func (that *Context) Display(statu int, data interface{}) { resp := Map{"statu": statu} if statu != 0 { temp := Map{} - tpe := this.Config.GetMap("error").GetString(ObjToStr(statu)) + tpe := that.Config.GetMap("error").GetString(ObjToStr(statu)) if tpe == "" { //logFmt(errors.New("找不到对应的错误码"), 2, LOG_WARN) } @@ -49,19 +49,19 @@ func (this *Context) Display(statu int, data interface{}) { resp["result"] = data } - this.RespData = resp + that.RespData = resp - //this.Data=d; + //that.Data=d; } -func (this *Context) View() { - if this.RespData == nil { +func (that *Context) View() { + if that.RespData == nil { return } - d, err := json.Marshal(this.RespData) + d, err := json.Marshal(that.RespData) if err != nil { return } - this.RespData = nil - this.Resp.Write(d) + that.RespData = nil + that.Resp.Write(d) } diff --git a/db/db.go b/db/db.go index 6e9b20f..2920dcf 100644 --- a/db/db.go +++ b/db/db.go @@ -22,27 +22,28 @@ type HoTimeDB struct { ConnectFunc func(err ...*Error) (*sql.DB, *sql.DB) LastErr Error limit Slice - Tx *sql.Tx //事务对象 + *sql.Tx //事务对象 SlaveDB *sql.DB } -//设置数据库配置连接 -func (this *HoTimeDB) SetConnect(connect func(err ...*Error) (master, slave *sql.DB), err ...*Error) { - this.ConnectFunc = connect - this.InitDb() +// SetConnect 设置数据库配置连接 +func (that *HoTimeDB) SetConnect(connect func(err ...*Error) (master, slave *sql.DB), err ...*Error) { + that.ConnectFunc = connect + _ = that.InitDb(err...) + } -//设置数据库配置连接 -func (this *HoTimeDB) GetType() string { - return this.Type +// GetType 设置数据库配置连接 +func (that *HoTimeDB) GetType() string { + return that.Type } -//事务,如果action返回true则执行成功;false则回滚 -func (this *HoTimeDB) Action(action func(db HoTimeDB) bool) bool { - db := HoTimeDB{DB: this.DB, CacheIns: this.CacheIns, DBCached: this.DBCached} +// Action 事务,如果action返回true则执行成功;false则回滚 +func (that *HoTimeDB) Action(action func(db HoTimeDB) bool) bool { + db := HoTimeDB{DB: that.DB, CacheIns: that.CacheIns, DBCached: that.DBCached} tx, err := db.Begin() if err != nil { - this.LastErr.SetError(err) + that.LastErr.SetError(err) return false } @@ -51,66 +52,74 @@ func (this *HoTimeDB) Action(action func(db HoTimeDB) bool) bool { result := action(db) if !result { - db.Tx.Rollback() + err = db.Tx.Rollback() + if err != nil { + that.LastErr.SetError(err) + return false + } return result } - db.Tx.Commit() + err = db.Tx.Commit() + if err != nil { + that.LastErr.SetError(err) + return false + } return result } -func (this *HoTimeDB) InitDb(err ...*Error) Error { +func (that *HoTimeDB) InitDb(err ...*Error) Error { if len(err) != 0 { - this.LastErr = *(err[0]) + that.LastErr = *(err[0]) } - this.DB, this.SlaveDB = this.ConnectFunc(&this.LastErr) - if this.DB == nil { - return this.LastErr + that.DB, that.SlaveDB = that.ConnectFunc(&that.LastErr) + if that.DB == nil { + return that.LastErr } - e := this.DB.Ping() + e := that.DB.Ping() - this.LastErr.SetError(e) + that.LastErr.SetError(e) - if this.SlaveDB != nil { - e := this.SlaveDB.Ping() - this.LastErr.SetError(e) + if that.SlaveDB != nil { + e := that.SlaveDB.Ping() + that.LastErr.SetError(e) } - return this.LastErr + return that.LastErr } -func (this *HoTimeDB) Page(page, pageRow int) *HoTimeDB { +func (that *HoTimeDB) Page(page, pageRow int) *HoTimeDB { page = (page - 1) * pageRow if page < 0 { page = 1 } - this.limit = Slice{page, pageRow} - return this + that.limit = Slice{page, pageRow} + return that } -func (this *HoTimeDB) PageSelect(table string, qu ...interface{}) []Map { +func (that *HoTimeDB) PageSelect(table string, qu ...interface{}) []Map { if len(qu) == 1 { - qu = append(qu, Map{"LIMIT": this.limit}) + qu = append(qu, Map{"LIMIT": that.limit}) } if len(qu) == 2 { temp := qu[1].(Map) - temp["LIMIT"] = this.limit + temp["LIMIT"] = that.limit qu[1] = temp } if len(qu) == 3 { temp := qu[2].(Map) - temp["LIMIT"] = this.limit + temp["LIMIT"] = that.limit qu[2] = temp } //fmt.Println(qu) - data := this.Select(table, qu...) + data := that.Select(table, qu...) return data } -//数据库数据解析 -func (this *HoTimeDB) Row(resl *sql.Rows) []Map { +// Row 数据库数据解析 +func (that *HoTimeDB) Row(resl *sql.Rows) []Map { dest := make([]Map, 0) strs, _ := resl.Columns() @@ -122,7 +131,11 @@ func (this *HoTimeDB) Row(resl *sql.Rows) []Map { for j := 0; j < len(a); j++ { b[j] = &a[j] } - resl.Scan(b...) + err := resl.Scan(b...) + if err != nil { + that.LastErr.SetError(err) + return nil + } for j := 0; j < len(a); j++ { if a[j] != nil && reflect.ValueOf(a[j]).Type().String() == "[]uint8" { lis[strs[j]] = string(a[j].([]byte)) @@ -134,9 +147,9 @@ func (this *HoTimeDB) Row(resl *sql.Rows) []Map { //防止int被误读为float64 jlis, e := json.Marshal(lis) if e != nil { - this.LastErr.SetError(e) + that.LastErr.SetError(e) } else { - lis.JsonToMap(string(jlis), &this.LastErr) + lis.JsonToMap(string(jlis), &that.LastErr) } dest = append(dest, lis) @@ -201,25 +214,25 @@ func (this *HoTimeDB) Row(resl *sql.Rows) []Map { // //} -func (this *HoTimeDB) backupSave(path string, tt string, code int) { +func (that *HoTimeDB) backupSave(path string, tt string, code int) { fd, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) defer fd.Close() str := "\r\n" if code == 0 || code == 2 { - str += this.backupDdl(tt) + str += that.backupDdl(tt) } if code == 0 || code == 1 { str += "insert into `" + tt + "`\r\n\r\n(" - str += this.backupCol(tt) + str += that.backupCol(tt) } - fd.Write([]byte(str)) + _, _ = fd.Write([]byte(str)) } -func (this *HoTimeDB) backupDdl(tt string) string { +func (that *HoTimeDB) backupDdl(tt string) string { - data := this.Query("show create table " + tt) + data := that.Query("show create table " + tt) if len(data) == 0 { return "" } @@ -227,9 +240,9 @@ func (this *HoTimeDB) backupDdl(tt string) string { return ObjToStr(data[0]["Create Table"]) + ";\r\n\r\n" } -func (this *HoTimeDB) backupCol(tt string) string { +func (that *HoTimeDB) backupCol(tt string) string { str := "" - data := this.Select(tt, "*") + data := that.Select(tt, "*") lthData := len(data) @@ -239,7 +252,7 @@ func (this *HoTimeDB) backupCol(tt string) string { lthCol := len(data[0]) col := make([]string, lthCol) tempLthData := 0 - for k, _ := range data[0] { + for k := range data[0] { if tempLthData == lthCol-1 { str += "`" + k + "`)" @@ -281,89 +294,89 @@ func (this *HoTimeDB) backupCol(tt string) string { return str } -func (this *HoTimeDB) md5(query string, args ...interface{}) string { +func (that *HoTimeDB) md5(query string, args ...interface{}) string { strByte, _ := json.Marshal(args) str := Md5(query + ":" + string(strByte)) return str } -func (this *HoTimeDB) Query(query string, args ...interface{}) []Map { +func (that *HoTimeDB) Query(query string, args ...interface{}) []Map { //fmt.Println(query) var err error var resl *sql.Rows - this.LastQuery = query - this.LastData = args + that.LastQuery = query + that.LastData = args //主从数据库切换,只有select语句有从数据库 - db := this.DB - if this.SlaveDB != nil { - db = this.SlaveDB + db := that.DB + if that.SlaveDB != nil { + db = that.SlaveDB } if db == nil { err = errors.New("没有初始化数据库") - this.LastErr.SetError(err) + that.LastErr.SetError(err) return nil } - if this.Tx != nil { - resl, err = this.Tx.Query(query, args...) + if that.Tx != nil { + resl, err = that.Tx.Query(query, args...) } else { resl, err = db.Query(query, args...) } - this.LastErr.SetError(err) + that.LastErr.SetError(err) if err != nil { if err = db.Ping(); err != nil { - this.LastErr.SetError(err) - this.InitDb() - if this.LastErr.GetError() != nil { + that.LastErr.SetError(err) + _ = that.InitDb() + if that.LastErr.GetError() != nil { return nil } - return this.Query(query, args...) + return that.Query(query, args...) } return nil } - return this.Row(resl) + return that.Row(resl) } -func (this *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, Error) { +func (that *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, Error) { - this.LastQuery = query - this.LastData = args + that.LastQuery = query + that.LastData = args var e error var resl sql.Result - if this.DB == nil { + if that.DB == nil { err := errors.New("没有初始化数据库") - this.LastErr.SetError(err) - return nil, this.LastErr + that.LastErr.SetError(err) + return nil, that.LastErr } - if this.Tx != nil { - resl, e = this.Tx.Exec(query, args...) + if that.Tx != nil { + resl, e = that.Tx.Exec(query, args...) } else { - resl, e = this.DB.Exec(query, args...) + resl, e = that.DB.Exec(query, args...) } - this.LastErr.SetError(e) + that.LastErr.SetError(e) //判断是否连接断开了 if e != nil { - if e = this.DB.Ping(); e != nil { - this.LastErr.SetError(e) - this.InitDb() - if this.LastErr.GetError() != nil { - return resl, this.LastErr + if e = that.DB.Ping(); e != nil { + that.LastErr.SetError(e) + _ = that.InitDb() + if that.LastErr.GetError() != nil { + return resl, that.LastErr } - return this.Exec(query, args...) + return that.Exec(query, args...) } } - return resl, this.LastErr + return resl, that.LastErr } //func (this *HoTimeDB)copy(data []Map)[]Map{ @@ -384,7 +397,8 @@ func (this *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, Error // return res // //} -func (this *HoTimeDB) Select(table string, qu ...interface{}) []Map { + +func (that *HoTimeDB) Select(table string, qu ...interface{}) []Map { query := "SELECT" where := Map{} @@ -446,15 +460,15 @@ func (this *HoTimeDB) Select(table string, qu ...interface{}) []Map { where = qu[intWhere].(Map) } - temp, resWhere := this.where(where) + temp, resWhere := that.where(where) query += temp qs = append(qs, resWhere...) - md5 := this.md5(query, qs...) + md5 := that.md5(query, qs...) - if this.DBCached && this.CacheIns != nil { + if that.DBCached && that.CacheIns != nil { //如果缓存有则从缓存取 - cacheData := this.Cache(table + ":" + md5) + cacheData := that.Cache(table + ":" + md5) if cacheData.Data != nil { return cacheData.ToMapArray() @@ -462,23 +476,23 @@ func (this *HoTimeDB) Select(table string, qu ...interface{}) []Map { } //无缓存则数据库取 - res := this.Query(query, qs...) + res := that.Query(query, qs...) if res == nil { res = []Map{} } //缓存 - if this.DBCached && this.CacheIns != nil { + if that.DBCached && that.CacheIns != nil { - this.Cache(table+":"+md5, res) + _ = that.Cache(table+":"+md5, res) } return res } -func (this *HoTimeDB) Get(table string, qu ...interface{}) Map { +func (that *HoTimeDB) Get(table string, qu ...interface{}) Map { //fmt.Println(qu) if len(qu) == 1 { qu = append(qu, Map{"LIMIT": 1}) @@ -494,19 +508,16 @@ func (this *HoTimeDB) Get(table string, qu ...interface{}) Map { qu[2] = temp } //fmt.Println(qu) - data := this.Select(table, qu...) + data := that.Select(table, qu...) if len(data) == 0 { return nil } return data[0] } -/** -** 计数 - */ -func (this *HoTimeDB) Count(table string, qu ...interface{}) int { - req := []interface{}{} - +// Count 计数 +func (that *HoTimeDB) Count(table string, qu ...interface{}) int { + var req = []interface{}{} if len(qu) == 2 { req = append(req, qu[0]) req = append(req, "COUNT(*)") @@ -517,7 +528,7 @@ func (this *HoTimeDB) Count(table string, qu ...interface{}) int { } //req=append(req,qu...) - data := this.Select(table, req...) + data := that.Select(table, req...) //fmt.Println(data) if len(data) == 0 { return 0 @@ -533,7 +544,7 @@ var condition = []string{"AND", "OR"} var vcond = []string{"GROUP", "ORDER", "LIMIT"} //where语句解析 -func (this *HoTimeDB) where(data Map) (string, []interface{}) { +func (that *HoTimeDB) where(data Map) (string, []interface{}) { where := "" @@ -545,7 +556,7 @@ func (this *HoTimeDB) where(data Map) (string, []interface{}) { if condition[i] == k { - tw, ts := this.cond(k, v.(Map)) + tw, ts := that.cond(k, v.(Map)) where += tw res = append(res, ts...) @@ -563,7 +574,7 @@ func (this *HoTimeDB) where(data Map) (string, []interface{}) { y++ } if x == len(condition) && y == len(vcond) { - tv, vv := this.varCond(k, v) + tv, vv := that.varCond(k, v) where += tv res = append(res, vv...) @@ -617,7 +628,7 @@ func (this *HoTimeDB) where(data Map) (string, []interface{}) { } -func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { +func (that *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { where := "" res := make([]interface{}, 0) length := len(k) @@ -635,7 +646,7 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { res = append(res, v) case "[!]": k = strings.Replace(k, "[!]", "", -1) - where, res = this.notIn(k, v, where, res) + where, res = that.notIn(k, v, where, res) case "[#]": k = strings.Replace(k, "[#]", "", -1) where += " " + k + "=" + ObjToStr(v) @@ -692,7 +703,7 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { default: if reflect.ValueOf(v).Type().String() == "hotime.Slice" { where += "`" + k + "` IN (" - res = append(res, (v.(Slice))...) + res = append(res, v.(Slice)...) if len(v.(Slice)) == 0 { where += ") " } else { @@ -725,7 +736,7 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { //fmt.Println(v) where += "`" + k + "` IN (" - res = append(res, (v.(Slice))...) + res = append(res, v.(Slice)...) for i := 0; i < len(v.(Slice)); i++ { if i+1 != len(v.(Slice)) { where += "?," @@ -736,7 +747,7 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { } } else if reflect.ValueOf(v).Type().String() == "[]interface {}" { where += "`" + k + "` IN (" - res = append(res, (v.([]interface{}))...) + res = append(res, v.([]interface{})...) for i := 0; i < len(v.([]interface{})); i++ { if i+1 != len(v.([]interface{})) { where += "?," @@ -757,7 +768,7 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) { } // this.Db.Update("user",hotime.Map{"ustate":"1"},hotime.Map{"AND":hotime.Map{"OR":hotime.Map{"uid":4,"uname":"dasda"}},"ustate":1}) -func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interface{}) (string, []interface{}) { +func (that *HoTimeDB) notIn(k string, v interface{}, where string, res []interface{}) (string, []interface{}) { //where:="" //fmt.Println(reflect.ValueOf(v).Type().String()) if v == nil { @@ -766,7 +777,7 @@ func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interfa } else if reflect.ValueOf(v).Type().String() == "hotime.Slice" { where += "`" + k + "` NOT IN (" - res = append(res, (v.(Slice))...) + res = append(res, v.(Slice)...) for i := 0; i < len(v.(Slice)); i++ { if i+1 != len(v.(Slice)) { where += "?," @@ -777,7 +788,7 @@ func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interfa } } else if reflect.ValueOf(v).Type().String() == "[]interface {}" { where += "`" + k + "` NOT IN (" - res = append(res, (v.([]interface{}))...) + res = append(res, v.([]interface{})...) for i := 0; i < len(v.([]interface{})); i++ { if i+1 != len(v.([]interface{})) { where += "?," @@ -796,7 +807,7 @@ func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interfa return where, res } -func (this *HoTimeDB) cond(tag string, data Map) (string, []interface{}) { +func (that *HoTimeDB) cond(tag string, data Map) (string, []interface{}) { where := " " res := make([]interface{}, 0) lens := len(data) @@ -807,7 +818,7 @@ func (this *HoTimeDB) cond(tag string, data Map) (string, []interface{}) { if condition[i] == k { - tw, ts := this.cond(k, v.(Map)) + tw, ts := that.cond(k, v.(Map)) if lens--; lens <= 0 { //fmt.Println(lens) where += "(" + tw + ") " @@ -823,7 +834,7 @@ func (this *HoTimeDB) cond(tag string, data Map) (string, []interface{}) { if x == len(condition) { - tv, vv := this.varCond(k, v) + tv, vv := that.varCond(k, v) res = append(res, vv...) if lens--; lens <= 0 { @@ -838,8 +849,8 @@ func (this *HoTimeDB) cond(tag string, data Map) (string, []interface{}) { return where, res } -//更新数据 -func (this *HoTimeDB) Update(table string, data Map, where Map) int64 { +// Update 更新数据 +func (that *HoTimeDB) Update(table string, data Map, where Map) int64 { query := "UPDATE " + table + " SET " //UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson' @@ -861,13 +872,13 @@ func (this *HoTimeDB) Update(table string, data Map, where Map) int64 { } } - temp, resWhere := this.where(where) + temp, resWhere := that.where(where) //fmt.Println(resWhere) query += temp qs = append(qs, resWhere...) - res, err := this.Exec(query, qs...) + res, err := that.Exec(query, qs...) rows := int64(0) if err.GetError() == nil && res != nil { @@ -876,22 +887,22 @@ func (this *HoTimeDB) Update(table string, data Map, where Map) int64 { //如果更新成功,则删除缓存 if rows != 0 { - if this.DBCached && this.CacheIns != nil { - this.Cache(table+"*", nil) + if that.DBCached && that.CacheIns != nil { + _ = that.Cache(table+"*", nil) } } return rows } -func (this *HoTimeDB) Delete(table string, data map[string]interface{}) int64 { +func (that *HoTimeDB) Delete(table string, data map[string]interface{}) int64 { query := "DELETE FROM " + table + " " - temp, resWhere := this.where(data) + temp, resWhere := that.where(data) query += temp - res, err := this.Exec(query, resWhere...) + res, err := that.Exec(query, resWhere...) rows := int64(0) if err.GetError() == nil && res != nil { rows, _ = res.RowsAffected() @@ -899,8 +910,8 @@ func (this *HoTimeDB) Delete(table string, data map[string]interface{}) int64 { //如果删除成功,删除对应缓存 if rows != 0 { - if this.DBCached && this.CacheIns != nil { - this.Cache(table+"*", nil) + if that.DBCached && that.CacheIns != nil { + _ = that.Cache(table+"*", nil) } } //return 0 @@ -908,8 +919,8 @@ func (this *HoTimeDB) Delete(table string, data map[string]interface{}) int64 { return rows } -//插入新数据 -func (this *HoTimeDB) Insert(table string, data map[string]interface{}) int64 { +// Insert 插入新数据 +func (that *HoTimeDB) Insert(table string, data map[string]interface{}) int64 { values := make([]interface{}, 0) queryString := " (" @@ -931,18 +942,18 @@ func (this *HoTimeDB) Insert(table string, data map[string]interface{}) int64 { } query := "INSERT INTO " + table + queryString + "VALUES" + valueString - res, err := this.Exec(query, values...) + res, err := that.Exec(query, values...) id := int64(0) if err.GetError() == nil && res != nil { - //id, this.LastErr.err = res.LastInsertId() + //id, that.LastErr.err = res.LastInsertId() } //如果插入成功,删除缓存 if id != 0 { - if this.DBCached && this.CacheIns != nil { - this.Cache(table+"*", nil) + if that.DBCached && that.CacheIns != nil { + _ = that.Cache(table+"*", nil) } } diff --git a/example/main.go b/example/main.go index 219bb55..cde3eaa 100644 --- a/example/main.go +++ b/example/main.go @@ -6,11 +6,8 @@ import ( "../../hotime/common" "database/sql" "fmt" - - //"go.hoteas.com/hotime/cache" "golang.org/x/net/websocket" "time" - //"go.hoteas.com/hotime/cache" ) func main() { @@ -27,18 +24,18 @@ func main() { //手动模式, appIns.SetConfig("example/config/config.json") //redis缓存接入 - //ca:=cache.CacheIns(&cache.CacheRedis{Host:appIns.Config.GetString("redisHost"),Pwd:appIns.Config.GetString("redisPwd"),Time:appIns.Config.GetCeilInt64("cacheLongTime")}) - //ca.Cache("xyzm","dasdas") - //ca.Cache("xyzn","dasdas") - //ca.Cache("xyzo","dasdas") - //ca.Cache("xyz*",nil) + ca := cache.CacheIns(&cache.CacheRedis{Host: appIns.Config.GetString("redisHost"), Pwd: appIns.Config.GetString("redisPwd"), Time: appIns.Config.GetCeilInt64("cacheLongTime")}) + ca.Cache("xyzm", "dasdas") + ca.Cache("xyzn", "dasdas") + ca.Cache("xyzo", "dasdas") + ca.Cache("xyz*", nil) //fmt.Println(ca.Cache("xyzm").Data) //mysql //mysql.SetDB(&appIns) //自动选择数据库 dbInterface := cache.HoTimeDBInterface(&appIns.Db) appIns.SetSession(cache.CacheIns(&cache.CacheMemory{}), cache.CacheIns(&cache.CacheDb{Db: dbInterface, Time: appIns.Config.GetInt64("cacheTime")})) - //appIns.SetCache(cache.CacheIns(&cache.CacheMemory{})) + appIns.SetCache(cache.CacheIns(&cache.CacheMemory{})) //快捷模式 appIns.SetDefault(func(err ...*common.Error) (*sql.DB, *sql.DB) { @@ -56,6 +53,8 @@ func main() { "index": hotime.Ctr{ "test": func(this *hotime.Context) { fmt.Println(this.Db.GetTag()) + this.Application.Log.Error("dasdasdas") + this.Log.Error("dadasdasd") //x:=this.Db.Action(func(db hotime.HoTimeDB) bool { // // db.Insert("user",hotime.Map{"unickname":"dasdas"}) diff --git a/log/logrus.go b/log/logrus.go new file mode 100644 index 0000000..544c388 --- /dev/null +++ b/log/logrus.go @@ -0,0 +1,114 @@ +package log + +import ( + "fmt" + log "github.com/sirupsen/logrus" + "os" + "path/filepath" + "runtime" + "strings" + "time" +) + +func GetLog(path string, showCodeLine bool) *log.Logger { + + hook := MyHook{ + Field: "line", + Skip: 5, + Path: path, ShowCodeLine: showCodeLine, + } + + loger := log.New() + loger.SetFormatter(&log.TextFormatter{}) + loger.AddHook(&hook) + loger.Print("dasdasdas") + return loger +} + +// MyHook ... +type MyHook struct { + Path string //存储日志的位置 + ShowCodeLine bool //输出代码文件名称和日志行 + Field string + Skip int + levels []log.Level +} + +// Levels 只定义 error 和 panic 等级的日志,其他日志等级不会触发 hook +func (that *MyHook) Levels() []log.Level { + return log.AllLevels +} + +// Fire 将异常日志写入到指定日志文件中 +func (that *MyHook) Fire(entry *log.Entry) error { + if that.ShowCodeLine { + entry.Data[that.Field] = findCaller(that.Skip) + } + //不需要存储到文件 + if that.Path == "" { + return nil + } + //存储到文件 + logFilePath := time.Now().Format(that.Path) + + err := os.MkdirAll(filepath.Dir(logFilePath), os.ModeAppend) + if err != nil { + return err + } + //os.Create(logFilePath) + f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE, 0644) + if err != nil { + return err + } + bte, _ := entry.Bytes() + _, err = f.Write(bte) + if err != nil { + return err + } + + err = f.Close() + if err != nil { + return err + } + + return nil +} + +// 对caller进行递归查询, 直到找到非logrus包产生的第一个调用. +// 因为filename我获取到了上层目录名, 因此所有logrus包的调用的文件名都是 logrus/... +// 因此通过排除logrus开头的文件名, 就可以排除所有logrus包的自己的函数调用 +func findCaller(skip int) string { + file := "" + line := 0 + for i := 0; i < 10; i++ { + file, line = getCaller(skip + i) + if !strings.HasPrefix(file, "logrus") { + break + } + } + return fmt.Sprintf("%s:%d", file, line) +} + +// 这里其实可以获取函数名称的: fnName := runtime.FuncForPC(pc).Name() +// 但是我觉得有 文件名和行号就够定位问题, 因此忽略了caller返回的第一个值:pc +// 在标准库log里面我们可以选择记录文件的全路径或者文件名, 但是在使用过程成并发最合适的, +// 因为文件的全路径往往很长, 而文件名在多个包中往往有重复, 因此这里选择多取一层, 取到文件所在的上层目录那层. +func getCaller(skip int) (string, int) { + _, file, line, ok := runtime.Caller(skip) + //fmt.Println(file) + //fmt.Println(line) + if !ok { + return "", 0 + } + n := 0 + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + n++ + if n >= 2 { + file = file[i+1:] + break + } + } + } + return file, line +} diff --git a/session.go b/session.go index 4e3558c..9a569e3 100644 --- a/session.go +++ b/session.go @@ -14,63 +14,63 @@ type SessionIns struct { ContextBase } -func (this *SessionIns) set() { +func (that *SessionIns) set() { - if this.ShortCache != nil { - this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map) + if that.ShortCache != nil { + that.ShortCache.Cache(HEAD_SESSION_ADD+that.SessionId, that.Map) } - if this.LongCache != nil { - this.LongCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map) + if that.LongCache != nil { + that.LongCache.Cache(HEAD_SESSION_ADD+that.SessionId, that.Map) } } -func (this *SessionIns) Session(key string, data ...interface{}) *Obj { +func (that *SessionIns) Session(key string, data ...interface{}) *Obj { - if this.Map == nil { - this.get() + if that.Map == nil { + that.get() } if len(data) != 0 { if data[0] == nil { - delete(this.Map, key) - this.set() + delete(that.Map, key) + that.set() } else { - this.Map[key] = data[0] - this.set() + that.Map[key] = data[0] + that.set() } return &Obj{Data: nil} } - return &Obj{Data: this.Map.Get(key)} + return &Obj{Data: that.Map.Get(key)} } -func (this *SessionIns) get() { +func (that *SessionIns) get() { - if this.ShortCache != nil { - this.Map = this.ShortCache.Cache(HEAD_SESSION_ADD + this.SessionId).ToMap() - if this.Map != nil { + if that.ShortCache != nil { + that.Map = that.ShortCache.Cache(HEAD_SESSION_ADD + that.SessionId).ToMap() + if that.Map != nil { return } } - if this.LongCache != nil { - this.Map = this.LongCache.Cache(HEAD_SESSION_ADD + this.SessionId).ToMap() - if this.Map != nil { - if this.ShortCache != nil { - this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map) + if that.LongCache != nil { + that.Map = that.LongCache.Cache(HEAD_SESSION_ADD + that.SessionId).ToMap() + if that.Map != nil { + if that.ShortCache != nil { + that.ShortCache.Cache(HEAD_SESSION_ADD+that.SessionId, that.Map) } return } } - this.Map = Map{} - this.ShortCache.Cache(HEAD_SESSION_ADD+this.SessionId, this.Map) + that.Map = Map{} + that.ShortCache.Cache(HEAD_SESSION_ADD+that.SessionId, that.Map) return } -func (this *SessionIns) Init(short CacheIns, long CacheIns) { - this.ShortCache = short - this.LongCache = long +func (that *SessionIns) Init(short CacheIns, long CacheIns) { + that.ShortCache = short + that.LongCache = long } diff --git a/type.go b/type.go index d8b35d6..ca64b9e 100644 --- a/type.go +++ b/type.go @@ -1,6 +1,6 @@ package hotime -//控制器 +// Ctr 控制器 type Ctr map[string]Method type Proj map[string]Ctr type Router map[string]Proj diff --git a/var.go b/var.go index 043e345..bbb4ab0 100644 --- a/var.go +++ b/var.go @@ -10,8 +10,7 @@ var App = map[string]*Application{} //整个项目 //var Db = HoTimeDB{} //数据库实例 var Config = Map{ - "debug": 1, //debug 0关闭1开启 - "logLevel": LOG_FMT, + "debug": 1, //debug 0关闭1开启 "db": Map{ "sqlite": Map{ "path": "config/data.db", @@ -38,9 +37,11 @@ var Config = Map{ } var ConfigNote = Map{ - "logLevel": "默认0,必须,0关闭,1打印,日志等级", - "logFile": "无默认,非必须,如果需要存储日志文件时使用,保存格式为:a/b/c/20060102150405.txt,将生成:a/b/c/年月日时分秒.txt,按需设置", - "debug": "默认1,必须,0关闭,其他开启,0用于生产环境;其他值用于开发测试,会显示更多内容并能够辅助研发,自动生成配置文件、代码等功能,web无缓存", //debug 0关闭1开启 + "logLevel": "默认0,必须,0关闭,1打印,日志等级", + "logFile": "无默认,非必须,如果需要存储日志文件时使用,保存格式为:a/b/c/20060102150405.txt,将生成:a/b/c/年月日时分秒.txt,按需设置", + "webConnectLogShow": "默认true,非必须,访问日志如果需要web访问链接、访问ip、访问时间打印,false为关闭true开启此功能", + "webConnectLogFile": "无默认,非必须,webConnectLogShow开启之后才能使用,如果需要存储日志文件时使用,保存格式为:a/b/c/20060102150405.txt,将生成:a/b/c/年月日时分秒.txt,按需设置", + "debug": "默认1,必须,0关闭,其他开启,0用于生产环境;其他值用于开发测试,会显示更多内容并能够辅助研发,自动生成配置文件、代码等功能,web无缓存", //debug 0关闭1开启 "db": Map{ "注释": "配置即启用,非必须,默认使用sqlite数据库", "mysql": Map{ @@ -100,7 +101,6 @@ var ConfigNote = Map{ "defFile": "默认访问index.html或者index.htm文件,必须,默认访问文件类型", "crossDomain": "默认空 非必须,空字符串为不开启,如果需要跨域设置,auto为智能开启所有网站允许跨域,http://www.baidu.com为指定域允许跨域", //是否开启跨域 "modeRouterStrict": "默认false,必须,路由严格模式false,为大小写忽略必须匹配,true必须大小写匹配", //路由严格模式/a/b/c - "connectLogShow": "默认true,非必须,访问日志如果需要web访问链接、访问ip、访问时间打印,false为关闭true开启此功能", "sessionName": "默认HOTIME,必须,设置session的cookie名", "port": "默认80,必须,web服务开启Http端口,0为不启用http服务,默认80", "tlsPort": "默认443,非必须,web服务https端口,0为不启用https服务",