From 81d7f834b16c5b30dcbfc05452245f3038f50431 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 27 Oct 2015 14:45:48 +0800 Subject: [PATCH] small optimizations for statement string generation --- VERSION | 2 +- statement.go | 128 +++++++++++++++++++++++++-------------------------- xorm.go | 2 +- 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/VERSION b/VERSION index 23fab9b3..847eb09b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -xorm v0.4.4.1026 +xorm v0.4.4.1027 diff --git a/statement.go b/statement.go index b05f2b04..1e6c067f 100644 --- a/statement.go +++ b/statement.go @@ -5,6 +5,7 @@ package xorm import ( + "bytes" "database/sql/driver" "encoding/json" "errors" @@ -143,9 +144,11 @@ func (statement *Statement) Where(querystring string, args ...interface{}) *Stat // add Where & and statment func (statement *Statement) And(querystring string, args ...interface{}) *Statement { - if statement.WhereStr != "" { - statement.WhereStr = fmt.Sprintf("(%v) %s (%v)", statement.WhereStr, + if len(statement.WhereStr) > 0 { + var buf bytes.Buffer + fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr, statement.Engine.dialect.AndStr(), querystring) + statement.WhereStr = buf.String() } else { statement.WhereStr = querystring } @@ -155,9 +158,11 @@ func (statement *Statement) And(querystring string, args ...interface{}) *Statem // add Where & Or statment func (statement *Statement) Or(querystring string, args ...interface{}) *Statement { - if statement.WhereStr != "" { - statement.WhereStr = fmt.Sprintf("(%v) %s (%v)", statement.WhereStr, + if len(statement.WhereStr) > 0 { + var buf bytes.Buffer + fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr, statement.Engine.dialect.OrStr(), querystring) + statement.WhereStr = buf.String() } else { statement.WhereStr = querystring } @@ -727,12 +732,17 @@ func (statement *Statement) genInSql() (string, []interface{}) { return "", []interface{}{} } - inStrs := make([]string, 0, len(statement.inColumns)) + inStrs := make([]string, len(statement.inColumns), len(statement.inColumns)) args := make([]interface{}, 0) + var buf bytes.Buffer + var i int for _, params := range statement.inColumns { - inStrs = append(inStrs, fmt.Sprintf("(%v IN (%v))", + buf.Reset() + fmt.Fprintf(&buf, "(%v IN (%v))", statement.Engine.autoQuote(params.colName), - strings.Join(makeArray("?", len(params.args)), ","))) + strings.Join(makeArray("?", len(params.args)), ",")) + inStrs[i] = buf.String() + i++ args = append(args, params.args...) } @@ -745,7 +755,7 @@ func (statement *Statement) genInSql() (string, []interface{}) { func (statement *Statement) attachInSql() { inSql, inArgs := statement.genInSql() if len(inSql) > 0 { - if statement.ConditionStr != "" { + if len(statement.ConditionStr) > 0 { statement.ConditionStr += " " + statement.Engine.dialect.AndStr() + " " } statement.ConditionStr += inSql @@ -845,15 +855,6 @@ func (statement *Statement) MustCols(columns ...string) *Statement { return statement } -// Update use only: not update columns -/*func (statement *Statement) NotCols(columns ...string) *Statement { - newColumns := col2NewCols(columns...) - for _, nc := range newColumns { - statement.mustColumnMap[strings.ToLower(nc)] = false - } - return statement -}*/ - // indicates that use bool fields as update contents and query contiditions func (statement *Statement) UseBool(columns ...string) *Statement { if len(columns) > 0 { @@ -898,7 +899,7 @@ func (statement *Statement) Limit(limit int, start ...int) *Statement { // Generate "Order By order" statement func (statement *Statement) OrderBy(order string) *Statement { - if statement.OrderStr != "" { + if len(statement.OrderStr) > 0 { statement.OrderStr += ", " } statement.OrderStr += order @@ -906,44 +907,51 @@ func (statement *Statement) OrderBy(order string) *Statement { } func (statement *Statement) Desc(colNames ...string) *Statement { - if statement.OrderStr != "" { - statement.OrderStr += ", " + var buf bytes.Buffer + fmt.Fprintf(&buf, statement.OrderStr) + if len(statement.OrderStr) > 0 { + fmt.Fprint(&buf, ", ") } newColNames := statement.col2NewColsWithQuote(colNames...) - sqlStr := strings.Join(newColNames, " DESC, ") - statement.OrderStr += sqlStr + " DESC" + fmt.Fprintf(&buf, "%q DESC", strings.Join(newColNames, " DESC, ")) + statement.OrderStr = buf.String() 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 += ", " + var buf bytes.Buffer + fmt.Fprintf(&buf, statement.OrderStr) + if len(statement.OrderStr) > 0 { + fmt.Fprint(&buf, ", ") } newColNames := statement.col2NewColsWithQuote(colNames...) - sqlStr := strings.Join(newColNames, " ASC, ") - statement.OrderStr += sqlStr + " ASC" + fmt.Fprintf(&buf, "%q ASC", strings.Join(newColNames, " ASC, ")) + statement.OrderStr = buf.String() 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 string, tablename interface{}, condition string) *Statement { - var joinTable string + var buf bytes.Buffer + if len(statement.JoinStr) > 0 { + fmt.Fprintf(&buf, "%q %v JOIN ", statement.JoinStr, join_operator) + } else { + fmt.Fprintf(&buf, "%v JOIN ", join_operator) + } + switch tablename.(type) { case []string: t := tablename.([]string) - l := len(t) - if l > 1 { - table := t[0] - joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1]) - } else if l == 1 { - table := t[0] - joinTable = statement.Engine.Quote(table) + if len(t) > 1 { + fmt.Fprintf(&buf, "%q AS %q", statement.Engine.Quote(t[0]), statement.Engine.Quote(t[1])) + } else if len(t) == 1 { + fmt.Fprintf(&buf, statement.Engine.Quote(t[0])) } case []interface{}: t := tablename.([]interface{}) l := len(t) - table := "" + var table string if l > 0 { f := t[0] v := rValue(f) @@ -956,21 +964,17 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co } } if l > 1 { - joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(fmt.Sprintf("%v", t[1])) + fmt.Fprintf(&buf, "%q AS %q", statement.Engine.Quote(table), + statement.Engine.Quote(fmt.Sprintf("%v", t[1]))) } else if l == 1 { - joinTable = statement.Engine.Quote(table) + fmt.Fprintf(&buf, statement.Engine.Quote(table)) } default: - t := fmt.Sprintf("%v", tablename) - joinTable = statement.Engine.Quote(t) - } - if statement.JoinStr != "" { - statement.JoinStr = statement.JoinStr + fmt.Sprintf(" %v JOIN %v ON %v", join_operator, - joinTable, condition) - } else { - statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator, - joinTable, condition) + fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", tablename))) } + + fmt.Fprintf(&buf, " ON %v", condition) + statement.JoinStr = buf.String() return statement } @@ -1087,11 +1091,6 @@ func (s *Statement) genDelIndexSQL() []string { return sqls } -/* -func (s *Statement) genDropSQL() string { - return s.Engine.dialect.MustDropTa(s.TableName()) + ";" -}*/ - func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) { var table *core.Table if statement.RefTable == nil { @@ -1191,20 +1190,22 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) { var mssqlCondi string statement.processIdParam() - var whereStr string - if statement.WhereStr != "" { - if statement.ConditionStr != "" { - whereStr = fmt.Sprintf(" WHERE (%v)", statement.WhereStr) + + var buf bytes.Buffer + if len(statement.WhereStr) > 0 { + if len(statement.ConditionStr) > 0 { + fmt.Fprintf(&buf, " WHERE (%v)", statement.WhereStr) } else { - whereStr = fmt.Sprintf(" WHERE %v", statement.WhereStr) + fmt.Fprintf(&buf, " WHERE %v", statement.WhereStr) } if statement.ConditionStr != "" { - whereStr = fmt.Sprintf("%v %s (%v)", whereStr, dialect.AndStr(), - statement.ConditionStr) + fmt.Fprintf(&buf, " %s (%v)", dialect.AndStr(), statement.ConditionStr) } - } else if statement.ConditionStr != "" { - whereStr = fmt.Sprintf(" WHERE %v", statement.ConditionStr) + } else if len(statement.ConditionStr) > 0 { + fmt.Fprintf(&buf, " WHERE %v", statement.ConditionStr) } + var whereStr = buf.String() + var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName()) if statement.TableAlias != "" { if dialect.DBType() == core.ORACLE { @@ -1248,10 +1249,9 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) { } // !nashtsai! REVIEW Sprintf is considered slowest mean of string concatnation, better to work with builder pattern - a = fmt.Sprintf("SELECT %v%v%v%v%v", top, distinct, columnStr, - fromStr, whereStr) - if mssqlCondi != "" { - if whereStr != "" { + a = fmt.Sprintf("SELECT %v%v%v%v%v", top, distinct, columnStr, fromStr, whereStr) + if len(mssqlCondi) > 0 { + if len(whereStr) > 0 { a += " AND " + mssqlCondi } else { a += " WHERE " + mssqlCondi diff --git a/xorm.go b/xorm.go index e791565f..c372e2a9 100644 --- a/xorm.go +++ b/xorm.go @@ -17,7 +17,7 @@ import ( ) const ( - Version string = "0.4.4.1026" + Version string = "0.4.4.1027" ) func regDrvsNDialects() bool {