From 5d911472d2768fdd26b04297281d46dc301fcc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=95=86=E8=AE=AF=E5=9C=A8=E7=BA=BF?= Date: Sat, 16 Aug 2014 20:11:20 +0800 Subject: [PATCH 01/15] bugfix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 商讯在线 --- lru_cacher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lru_cacher.go b/lru_cacher.go index a81c4ccc..8c912879 100644 --- a/lru_cacher.go +++ b/lru_cacher.go @@ -24,7 +24,7 @@ type LRUCacher struct { } func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher { - return NewLRUCacher2(store, 0, maxElementSize) + return NewLRUCacher2(store, 3600*time.Second, maxElementSize) } func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher { From 8164f74b645ef750cbe46f27ad967d172178a105 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Mon, 18 Aug 2014 16:02:24 +0800 Subject: [PATCH 02/15] update func (session *Session) cacheFind, if no cache hit, continue instead of return error --- session.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/session.go b/session.go index ac2027a0..8d611255 100644 --- a/session.go +++ b/session.go @@ -848,8 +848,9 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in for j := 0; j < len(temps); j++ { bean := temps[j] if bean == nil { - session.Engine.LogError("[xorm:cacheFind] cache error:", tableName, ides[j], bean) - return errors.New("cache error") + session.Engine.LogWarn("[xorm:cacheFind] cache no hit:", tableName, ides[j]) + // return errors.New("cache error") // !nashtsai! no need to return error, but continue instead + continue } if sliceValue.Kind() == reflect.Slice { if t.Kind() == reflect.Ptr { From c5a437680d54370a6173915e8bf7877fb3e6b0d8 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 18 Aug 2014 21:20:18 +0800 Subject: [PATCH 03/15] bug fixed for Desc & Asc --- session.go | 7 +------ statement.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/session.go b/session.go index 8d611255..aa3aec73 100644 --- a/session.go +++ b/session.go @@ -219,12 +219,7 @@ func (session *Session) OrderBy(order string) *Session { // Method Desc provide desc order by query condition, the input parameters are columns. func (session *Session) Desc(colNames ...string) *Session { - if session.Statement.OrderStr != "" { - session.Statement.OrderStr += ", " - } - newColNames := col2NewCols(colNames...) - sqlStr := strings.Join(newColNames, session.Engine.Quote(" DESC, ")) - session.Statement.OrderStr += session.Engine.Quote(sqlStr) + " DESC" + session.Statement.Desc(colNames...) return session } diff --git a/statement.go b/statement.go index 74daf9fb..332f87cb 100644 --- a/statement.go +++ b/statement.go @@ -2,6 +2,7 @@ package xorm import ( "encoding/json" + "errors" "fmt" "reflect" "strings" @@ -771,6 +772,27 @@ func col2NewCols(columns ...string) []string { return newColumns } +func (statement *Statement) col2NewColsWithQuote(columns ...string) []string { + newColumns := make([]string, 0) + for _, col := range columns { + strings.Replace(col, "`", "", -1) + strings.Replace(col, statement.Engine.QuoteStr(), "", -1) + ccols := strings.Split(col, ",") + for _, c := range ccols { + fields := strings.Split(strings.TrimSpace(c), ".") + if len(fields) == 1 { + newColumns = append(newColumns, statement.Engine.Quote(fields[0])) + } else if len(fields) == 2 { + newColumns = append(newColumns, statement.Engine.Quote(fields[0])+"."+ + statement.Engine.Quote(fields[1])) + } else { + panic(errors.New("unwanted colnames")) + } + } + } + return newColumns +} + // Generate "Distince col1, col2 " statment func (statement *Statement) Distinct(columns ...string) *Statement { statement.IsDistinct = true @@ -851,10 +873,34 @@ func (statement *Statement) Limit(limit int, start ...int) *Statement { // Generate "Order By order" statement func (statement *Statement) OrderBy(order string) *Statement { + if statement.OrderStr != "" { + statement.OrderStr += ", " + } statement.OrderStr = order return statement } +func (statement *Statement) Desc(colNames ...string) *Statement { + if statement.OrderStr != "" { + statement.OrderStr += ", " + } + newColNames := statement.col2NewColsWithQuote(colNames...) + sqlStr := strings.Join(newColNames, " DESC, ") + statement.OrderStr += sqlStr + " DESC" + return statement +} + +// Method Asc provide asc order by query condition, the input parameters are columns. +func (statement *Statement) Asc(colNames ...string) *Statement { + if statement.OrderStr != "" { + statement.OrderStr += ", " + } + newColNames := statement.col2NewColsWithQuote(colNames...) + sqlStr := strings.Join(newColNames, " ASC, ") + statement.OrderStr += sqlStr + " ASC" + return statement +} + //The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN func (statement *Statement) Join(join_operator, tablename, condition string) *Statement { if statement.JoinStr != "" { From 917bd37518bbc618b85f05b6782d60908cd05d0b Mon Sep 17 00:00:00 2001 From: Alfred Hall Date: Mon, 18 Aug 2014 13:38:24 +0000 Subject: [PATCH 04/15] All cols not being reset, causes problems when using the session again after AllCols() Signed-off-by: Alfred Hall --- statement.go | 1 + 1 file changed, 1 insertion(+) diff --git a/statement.go b/statement.go index 332f87cb..e7a253d6 100644 --- a/statement.go +++ b/statement.go @@ -88,6 +88,7 @@ func (statement *Statement) Init() { statement.UseAutoTime = true statement.IsDistinct = false statement.allUseBool = false + statement.useAllCols = false statement.mustColumnMap = make(map[string]bool) statement.checkVersion = true statement.inColumns = make(map[string]*inParam) From 6958d6d3dcd3d0d8a39815c625edf543f1ccdad8 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Tue, 19 Aug 2014 10:38:57 +0800 Subject: [PATCH 05/15] guard uninitialized time in func (engine *Engine) TZTime(t time.Time) --- engine.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/engine.go b/engine.go index bf041410..85eb488f 100644 --- a/engine.go +++ b/engine.go @@ -1396,8 +1396,16 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) { return results, lastError } +var ( + NULL_TIME time.Time +) + func (engine *Engine) TZTime(t time.Time) time.Time { - return t.In(engine.TZLocation) + + if NULL_TIME != t { // if time is not initialized it's not suitable for Time.In() + return t.In(engine.TZLocation) + } + return t } func (engine *Engine) NowTime(sqlTypeName string) interface{} { From a71c330f16d308ee4b89b632787aeae0bb0d5e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=95=86=E8=AE=AF=E5=9C=A8=E7=BA=BF?= Date: Wed, 20 Aug 2014 00:26:28 +0800 Subject: [PATCH 06/15] fix bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 商讯在线 --- mysql_dialect.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/mysql_dialect.go b/mysql_dialect.go index b9911138..479e6347 100644 --- a/mysql_dialect.go +++ b/mysql_dialect.go @@ -56,24 +56,20 @@ func (db *mysql) SqlType(c *core.Column) string { case core.Enum: //mysql enum res = core.Enum res += "(" - for v, k := range c.EnumOptions { - if k > 0 { - res += fmt.Sprintf(",'%v'", v) - } else { - res += fmt.Sprintf("'%v'", v) - } + opts := "" + for v, _ := range c.EnumOptions { + opts += fmt.Sprintf(",'%v'", v) } + res += strings.TrimLeft(opts,",") res += ")" case core.Set: //mysql set res = core.Set res += "(" - for v, k := range c.SetOptions { - if k > 0 { - res += fmt.Sprintf(",'%v'", v) - } else { - res += fmt.Sprintf("'%v'", v) - } + opts := "" + for v, _ := range c.SetOptions { + opts += fmt.Sprintf(",'%v'", v) } + res += strings.TrimLeft(opts,",") res += ")" default: res = t From 0c227ead0f1efb5626c301ccd65f297e4ca86239 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Wed, 20 Aug 2014 09:38:52 +0800 Subject: [PATCH 07/15] add log level support to simple logger --- engine.go | 2 +- logger.go | 62 ++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/engine.go b/engine.go index 85eb488f..413c482a 100644 --- a/engine.go +++ b/engine.go @@ -37,7 +37,7 @@ type Engine struct { ShowDebug bool ShowWarn bool - Logger ILogger // io.Writer + Logger core.ILogger TZLocation *time.Location } diff --git a/logger.go b/logger.go index f9d529a1..5ae18906 100644 --- a/logger.go +++ b/logger.go @@ -6,41 +6,51 @@ import ( "log" ) -// logger interface, log/syslog conform with this interface -type ILogger interface { - Debug(m string) (err error) - Err(m string) (err error) - Info(m string) (err error) - Warning(m string) (err error) -} +type LogLevel int + +const ( + LOG_ERR LogLevel = iota + 3 + LOG_WARNING + LOG_INFO = iota + 6 + LOG_DEBUG +) + +const ( + DEFAULT_LOG_PREFIX = "[xorm]" + DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds + DEFAULT_LOG_LEVEL = LOG_INFO +) type SimpleLogger struct { - DEBUG *log.Logger - ERR *log.Logger - INFO *log.Logger - WARN *log.Logger + DEBUG *log.Logger + ERR *log.Logger + INFO *log.Logger + WARN *log.Logger + LogLevel LogLevel } func NewSimpleLogger(out io.Writer) *SimpleLogger { - return &SimpleLogger{ - DEBUG: log.New(out, "[xorm] [debug] ", log.Ldate|log.Lmicroseconds), - ERR: log.New(out, "[xorm] [error] ", log.Ldate|log.Lmicroseconds), - INFO: log.New(out, "[xorm] [info] ", log.Ldate|log.Lmicroseconds), - WARN: log.New(out, "[xorm] [warn] ", log.Ldate|log.Lmicroseconds), - } + return NewSimpleLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG) } func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger { + return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL) +} + +func NewSimpleLogger3(out io.Writer, prefix string, flag int, logLevel LogLevel) *SimpleLogger { return &SimpleLogger{ - DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), log.Ldate|log.Lmicroseconds), - ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), log.Ldate|log.Lmicroseconds), - INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), log.Ldate|log.Lmicroseconds), - WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), log.Ldate|log.Lmicroseconds), + DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag), + ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), + INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), + WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), + LogLevel: LOG_INFO, } } func (s *SimpleLogger) Debug(m string) (err error) { - s.DEBUG.Println(m) + if s.LogLevel >= LOG_DEBUG { + s.DEBUG.Println(m) + } return } @@ -50,11 +60,15 @@ func (s *SimpleLogger) Err(m string) (err error) { } func (s *SimpleLogger) Info(m string) (err error) { - s.INFO.Println(m) + if s.LogLevel >= LOG_INFO { + s.INFO.Println(m) + } return } func (s *SimpleLogger) Warning(m string) (err error) { - s.WARN.Println(m) + if s.LogLevel >= LOG_WARNING { + s.WARN.Println(m) + } return } From 9ae84a13fc6cdf311ef01a9dea5f93bd11e1ddf3 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Wed, 20 Aug 2014 09:46:18 +0800 Subject: [PATCH 08/15] add TODO comments --- engine.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/engine.go b/engine.go index 413c482a..e5beafaf 100644 --- a/engine.go +++ b/engine.go @@ -31,11 +31,14 @@ type Engine struct { mutex *sync.RWMutex Cacher core.Cacher + ShowSQL bool + + // !nashtsai! TODO ought to deprecate these but having logger to control its log level ShowInfo bool - ShowSQL bool ShowErr bool ShowDebug bool ShowWarn bool + // -- Logger core.ILogger TZLocation *time.Location From 55c9cb4c0769075dbb9b1f027b22e21c57fdd171 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Wed, 20 Aug 2014 09:48:04 +0800 Subject: [PATCH 09/15] fixed error usage in simple logger make default log level DEBUG --- logger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logger.go b/logger.go index 5ae18906..c691c1b2 100644 --- a/logger.go +++ b/logger.go @@ -18,7 +18,7 @@ const ( const ( DEFAULT_LOG_PREFIX = "[xorm]" DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds - DEFAULT_LOG_LEVEL = LOG_INFO + DEFAULT_LOG_LEVEL = LOG_DEBUG ) type SimpleLogger struct { @@ -43,7 +43,7 @@ func NewSimpleLogger3(out io.Writer, prefix string, flag int, logLevel LogLevel) ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), - LogLevel: LOG_INFO, + LogLevel: logLevel, } } From 90d1be45a296a7134e236e0f0efe0471f0478b16 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Wed, 20 Aug 2014 10:37:52 +0800 Subject: [PATCH 10/15] update ILogger interface, to reduce performance cost where string format or concat is done when it's need to write out --- engine.go | 14 ++--- logger.go | 151 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 123 insertions(+), 42 deletions(-) diff --git a/engine.go b/engine.go index e5beafaf..144968e5 100644 --- a/engine.go +++ b/engine.go @@ -188,7 +188,7 @@ func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { // logging error func (engine *Engine) LogError(contents ...interface{}) { if engine.ShowErr { - engine.Logger.Err(fmt.Sprint(contents...)) + engine.Logger.Err(contents...) } } @@ -201,39 +201,39 @@ func (engine *Engine) LogErrorf(format string, contents ...interface{}) { // logging info func (engine *Engine) LogInfo(contents ...interface{}) { if engine.ShowInfo { - engine.Logger.Info(fmt.Sprint(contents...)) + engine.Logger.Info(contents...) } } func (engine *Engine) LogInfof(format string, contents ...interface{}) { if engine.ShowErr { - engine.Logger.Info(fmt.Sprintf(format, contents...)) + engine.Logger.Infof(format, contents...) } } // logging debug func (engine *Engine) LogDebug(contents ...interface{}) { if engine.ShowDebug { - engine.Logger.Debug(fmt.Sprint(contents...)) + engine.Logger.Debug(contents...) } } func (engine *Engine) LogDebugf(format string, contents ...interface{}) { if engine.ShowDebug { - engine.Logger.Debug(fmt.Sprintf(format, contents...)) + engine.Logger.Debugf(format, contents...) } } // logging warn func (engine *Engine) LogWarn(contents ...interface{}) { if engine.ShowWarn { - engine.Logger.Warning(fmt.Sprint(contents...)) + engine.Logger.Warning(contents...) } } func (engine *Engine) LogWarnf(format string, contents ...interface{}) { if engine.ShowWarn { - engine.Logger.Warning(fmt.Sprintf(format, contents...)) + engine.Logger.Warningf(format, contents...) } } diff --git a/logger.go b/logger.go index c691c1b2..b9e9be9f 100644 --- a/logger.go +++ b/logger.go @@ -2,31 +2,24 @@ package xorm import ( "fmt" + "github.com/go-xorm/core" "io" "log" -) - -type LogLevel int - -const ( - LOG_ERR LogLevel = iota + 3 - LOG_WARNING - LOG_INFO = iota + 6 - LOG_DEBUG + "log/syslog" ) const ( DEFAULT_LOG_PREFIX = "[xorm]" DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds - DEFAULT_LOG_LEVEL = LOG_DEBUG + DEFAULT_LOG_LEVEL = core.LOG_DEBUG ) type SimpleLogger struct { - DEBUG *log.Logger - ERR *log.Logger - INFO *log.Logger - WARN *log.Logger - LogLevel LogLevel + DEBUG *log.Logger + ERR *log.Logger + INFO *log.Logger + WARN *log.Logger + level core.LogLevel } func NewSimpleLogger(out io.Writer) *SimpleLogger { @@ -37,38 +30,126 @@ func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger { return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL) } -func NewSimpleLogger3(out io.Writer, prefix string, flag int, logLevel LogLevel) *SimpleLogger { +func NewSimpleLogger3(out io.Writer, prefix string, flag int, l core.LogLevel) *SimpleLogger { return &SimpleLogger{ - DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag), - ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), - INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), - WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), - LogLevel: logLevel, + DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag), + ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), + INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), + WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), + level: l, } } -func (s *SimpleLogger) Debug(m string) (err error) { - if s.LogLevel >= LOG_DEBUG { - s.DEBUG.Println(m) +func (s *SimpleLogger) Err(v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level <= core.LOG_ERR { + s.ERR.Println(v...) } return } -func (s *SimpleLogger) Err(m string) (err error) { - s.ERR.Println(m) - return -} - -func (s *SimpleLogger) Info(m string) (err error) { - if s.LogLevel >= LOG_INFO { - s.INFO.Println(m) +func (s *SimpleLogger) Errf(format string, v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level <= core.LOG_ERR { + s.ERR.Printf(format, v...) } return } -func (s *SimpleLogger) Warning(m string) (err error) { - if s.LogLevel >= LOG_WARNING { - s.WARN.Println(m) +func (s *SimpleLogger) Debug(v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level <= core.LOG_DEBUG { + s.DEBUG.Println(v...) } return } + +func (s *SimpleLogger) Debugf(format string, v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level >= core.LOG_DEBUG { + s.DEBUG.Printf(format, v...) + } + return +} + +func (s *SimpleLogger) Info(v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level >= core.LOG_INFO { + s.INFO.Println(v...) + } + return +} + +func (s *SimpleLogger) Infof(format string, v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level >= core.LOG_INFO { + s.INFO.Printf(format, v...) + } + return +} + +func (s *SimpleLogger) Warning(v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level >= core.LOG_WARNING { + s.WARN.Println(v...) + } + return +} + +func (s *SimpleLogger) Warningf(format string, v ...interface{}) (err error) { + if s.level > core.LOG_OFF && s.level >= core.LOG_WARNING { + s.WARN.Printf(format, v...) + } + return +} + +func (s *SimpleLogger) Level() core.LogLevel { + return s.level +} + +func (s *SimpleLogger) SetLevel(l core.LogLevel) (err error) { + s.level = l + return +} + +type SyslogLogger struct { + w *syslog.Writer +} + +func NewSyslogLogger(w *syslog.Writer) *SyslogLogger { + return &SyslogLogger{w: w} +} + +func (s *SyslogLogger) Debug(v ...interface{}) (err error) { + return s.w.Debug(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Debugf(format string, v ...interface{}) (err error) { + return s.w.Debug(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Err(v ...interface{}) (err error) { + return s.w.Err(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Errf(format string, v ...interface{}) (err error) { + return s.w.Err(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Info(v ...interface{}) (err error) { + return s.w.Info(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Infof(format string, v ...interface{}) (err error) { + return s.w.Info(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Warning(v ...interface{}) (err error) { + return s.w.Warning(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Warningf(format string, v ...interface{}) (err error) { + return s.w.Warning(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Level() core.LogLevel { + return core.LOG_UNKNOWN +} + +// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created +func (s *SyslogLogger) SetLevel(l core.LogLevel) (err error) { + return fmt.Errorf("unable to set syslog level") +} From 4fdc045edce10989ba4c59452c9ff05117fc3f97 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 21 Aug 2014 11:40:55 +0800 Subject: [PATCH 11/15] move syslogger as condition compile --- logger.go | 53 ++-------------------------------------------- syslogger.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 51 deletions(-) create mode 100644 syslogger.go diff --git a/logger.go b/logger.go index b9e9be9f..da3ba019 100644 --- a/logger.go +++ b/logger.go @@ -2,10 +2,10 @@ package xorm import ( "fmt" - "github.com/go-xorm/core" "io" "log" - "log/syslog" + + "github.com/go-xorm/core" ) const ( @@ -104,52 +104,3 @@ func (s *SimpleLogger) SetLevel(l core.LogLevel) (err error) { s.level = l return } - -type SyslogLogger struct { - w *syslog.Writer -} - -func NewSyslogLogger(w *syslog.Writer) *SyslogLogger { - return &SyslogLogger{w: w} -} - -func (s *SyslogLogger) Debug(v ...interface{}) (err error) { - return s.w.Debug(fmt.Sprint(v...)) -} - -func (s *SyslogLogger) Debugf(format string, v ...interface{}) (err error) { - return s.w.Debug(fmt.Sprintf(format, v...)) -} - -func (s *SyslogLogger) Err(v ...interface{}) (err error) { - return s.w.Err(fmt.Sprint(v...)) -} - -func (s *SyslogLogger) Errf(format string, v ...interface{}) (err error) { - return s.w.Err(fmt.Sprintf(format, v...)) -} - -func (s *SyslogLogger) Info(v ...interface{}) (err error) { - return s.w.Info(fmt.Sprint(v...)) -} - -func (s *SyslogLogger) Infof(format string, v ...interface{}) (err error) { - return s.w.Info(fmt.Sprintf(format, v...)) -} - -func (s *SyslogLogger) Warning(v ...interface{}) (err error) { - return s.w.Warning(fmt.Sprint(v...)) -} - -func (s *SyslogLogger) Warningf(format string, v ...interface{}) (err error) { - return s.w.Warning(fmt.Sprintf(format, v...)) -} - -func (s *SyslogLogger) Level() core.LogLevel { - return core.LOG_UNKNOWN -} - -// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created -func (s *SyslogLogger) SetLevel(l core.LogLevel) (err error) { - return fmt.Errorf("unable to set syslog level") -} diff --git a/syslogger.go b/syslogger.go new file mode 100644 index 00000000..155029e9 --- /dev/null +++ b/syslogger.go @@ -0,0 +1,59 @@ +package xorm + +// +build !windows !nacl !plan9 + +import ( + "fmt" + "log/syslog" + + "github.com/go-xorm/core" +) + +type SyslogLogger struct { + w *syslog.Writer +} + +func NewSyslogLogger(w *syslog.Writer) *SyslogLogger { + return &SyslogLogger{w: w} +} + +func (s *SyslogLogger) Debug(v ...interface{}) (err error) { + return s.w.Debug(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Debugf(format string, v ...interface{}) (err error) { + return s.w.Debug(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Err(v ...interface{}) (err error) { + return s.w.Err(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Errf(format string, v ...interface{}) (err error) { + return s.w.Err(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Info(v ...interface{}) (err error) { + return s.w.Info(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Infof(format string, v ...interface{}) (err error) { + return s.w.Info(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Warning(v ...interface{}) (err error) { + return s.w.Warning(fmt.Sprint(v...)) +} + +func (s *SyslogLogger) Warningf(format string, v ...interface{}) (err error) { + return s.w.Warning(fmt.Sprintf(format, v...)) +} + +func (s *SyslogLogger) Level() core.LogLevel { + return core.LOG_UNKNOWN +} + +// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created +func (s *SyslogLogger) SetLevel(l core.LogLevel) (err error) { + return fmt.Errorf("unable to set syslog level") +} From 7765263e19a020c994ebea9fd691a6f399947bc9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 21 Aug 2014 11:41:37 +0800 Subject: [PATCH 12/15] bug fixed --- syslogger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syslogger.go b/syslogger.go index 155029e9..3e54c4ac 100644 --- a/syslogger.go +++ b/syslogger.go @@ -1,6 +1,6 @@ package xorm -// +build !windows !nacl !plan9 +// +build !windows,!nacl,!plan9 import ( "fmt" From 34558c9f6a9be1954a8673d75e05327672b24d2a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 21 Aug 2014 11:50:23 +0800 Subject: [PATCH 13/15] fixed build tag --- syslogger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syslogger.go b/syslogger.go index 3e54c4ac..5c78fecb 100644 --- a/syslogger.go +++ b/syslogger.go @@ -1,7 +1,7 @@ -package xorm - // +build !windows,!nacl,!plan9 +package xorm + import ( "fmt" "log/syslog" From 5f7bf04b0c1f57e75a028130b01f51fdf7d74cb7 Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Fri, 22 Aug 2014 00:47:19 +0800 Subject: [PATCH 14/15] performance optimization for Find(), 10000 times - MultiRead limit 100 from 24.57s to 5.29s --- session.go | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/session.go b/session.go index aa3aec73..009a758a 100644 --- a/session.go +++ b/session.go @@ -1180,16 +1180,15 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } } - for rawRows.Next() { - var newValue reflect.Value = newElemFunc() - if sliceValueSetFunc != nil { - err := session.row2Bean(rawRows, fields, fieldsCount, newValue.Interface()) - if err != nil { - return err - } - sliceValueSetFunc(&newValue) - } + var newValue reflect.Value = newElemFunc() + dataStruct := rValue(newValue.Interface()) + if dataStruct.Kind() != reflect.Struct { + return errors.New("Expected a pointer to a struct") } + + table := session.Engine.autoMapType(dataStruct) + + return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc) } else { resultsSlice, err := session.query(sqlStr, args...) if err != nil { @@ -1446,6 +1445,24 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c type Cell *interface{} +func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int, + table *core.Table, newElemFunc func() reflect.Value, + sliceValueSetFunc func(*reflect.Value)) error { + + for rows.Next() { + var newValue reflect.Value = newElemFunc() + bean := newValue.Interface() + dataStruct := rValue(bean) + err := session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table) + if err != nil { + return err + } + sliceValueSetFunc(&newValue) + + } + return nil +} + func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error { dataStruct := rValue(bean) if dataStruct.Kind() != reflect.Struct { @@ -1453,8 +1470,12 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i } table := session.Engine.autoMapType(dataStruct) + return session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table) +} - scanResults := make([]interface{}, len(fields)) +func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) error { + + scanResults := make([]interface{}, fieldsCount) for i := 0; i < len(fields); i++ { var cell interface{} scanResults[i] = &cell @@ -1480,7 +1501,7 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i } tempMap[strings.ToLower(key)] = idx - if fieldValue := session.getField(&dataStruct, key, table, idx); fieldValue != nil { + if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil { rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) //if row is null then ignore From 01b89af2ce3437dd12601361249b0b67fb30fcba Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Fri, 22 Aug 2014 16:39:59 +0800 Subject: [PATCH 15/15] maintain backward compatibility on engine's logging settings --- engine.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/engine.go b/engine.go index 144968e5..6eed30a0 100644 --- a/engine.go +++ b/engine.go @@ -177,6 +177,7 @@ func (engine *Engine) Ping() error { // logging sql func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { if engine.ShowSQL { + overrideLogLevel(LOG_INFO) if len(sqlArgs) > 0 { engine.Logger.Info(fmt.Sprintf("[sql] %v [args] %v", sqlStr, sqlArgs)) } else { @@ -186,27 +187,42 @@ func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { } // logging error +func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) { + logLevel := engine.Logger.Level() + if logLevel == core.LOG_UNKNOWN { + // intend to left empty + } + else if logLevel < core.overrideLevel { // TODO can remove if deprecated engine.ShowErr + engine.Logger.SetLevel(LOG_ERR) // try override logger's log level + } + +} + func (engine *Engine) LogError(contents ...interface{}) { if engine.ShowErr { + overrideLogLevel(LOG_ERR) engine.Logger.Err(contents...) } } func (engine *Engine) LogErrorf(format string, contents ...interface{}) { if engine.ShowErr { - engine.Logger.Err(fmt.Sprintf(format, contents...)) + overrideLogLevel(LOG_ERR) + engine.Logger.Errf(format, contents...) } } // logging info func (engine *Engine) LogInfo(contents ...interface{}) { if engine.ShowInfo { + overrideLogLevel(LOG_INFO) engine.Logger.Info(contents...) } } func (engine *Engine) LogInfof(format string, contents ...interface{}) { if engine.ShowErr { + overrideLogLevel(LOG_INFO) engine.Logger.Infof(format, contents...) } } @@ -214,12 +230,14 @@ func (engine *Engine) LogInfof(format string, contents ...interface{}) { // logging debug func (engine *Engine) LogDebug(contents ...interface{}) { if engine.ShowDebug { + overrideLogLevel(LOG_DEBUG) engine.Logger.Debug(contents...) } } func (engine *Engine) LogDebugf(format string, contents ...interface{}) { if engine.ShowDebug { + overrideLogLevel(LOG_DEBUG) engine.Logger.Debugf(format, contents...) } } @@ -227,12 +245,14 @@ func (engine *Engine) LogDebugf(format string, contents ...interface{}) { // logging warn func (engine *Engine) LogWarn(contents ...interface{}) { if engine.ShowWarn { + overrideLogLevel(LOG_WARNING) engine.Logger.Warning(contents...) } } func (engine *Engine) LogWarnf(format string, contents ...interface{}) { if engine.ShowWarn { + overrideLogLevel(LOG_WARNING) engine.Logger.Warningf(format, contents...) } }