From a6cc0986897283170a53411cf6f40ae88a433ce2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 20 Nov 2017 16:14:27 +0800 Subject: [PATCH] QueryString and QueryInterface supports composite conditions (#784) --- engine.go | 8 +-- interface.go | 4 +- session_query.go | 131 ++++++++++++++++++++++++++--------------------- 3 files changed, 79 insertions(+), 64 deletions(-) diff --git a/engine.go b/engine.go index 4cf98b95..6c473dca 100644 --- a/engine.go +++ b/engine.go @@ -1376,17 +1376,17 @@ func (engine *Engine) Query(sqlorArgs ...interface{}) (resultsSlice []map[string } // QueryString runs a raw sql and return records as []map[string]string -func (engine *Engine) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) { +func (engine *Engine) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) { session := engine.NewSession() defer session.Close() - return session.QueryString(sqlStr, args...) + return session.QueryString(sqlorArgs...) } // QueryInterface runs a raw sql and return records as []map[string]interface{} -func (engine *Engine) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) { +func (engine *Engine) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) { session := engine.NewSession() defer session.Close() - return session.QueryInterface(sqlStr, args...) + return session.QueryInterface(sqlorArgs...) } // Insert one or more records diff --git a/interface.go b/interface.go index 70907b20..9a3b6da0 100644 --- a/interface.go +++ b/interface.go @@ -48,8 +48,8 @@ type Interface interface { OrderBy(order string) *Session Ping() error Query(sqlOrAgrs ...interface{}) (resultsSlice []map[string][]byte, err error) - QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) - QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) + QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) + QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) Rows(bean interface{}) (*Rows, error) SetExpr(string, string) *Session SQL(interface{}, ...interface{}) *Session diff --git a/session_query.go b/session_query.go index 260b52d8..5b4e0dc4 100644 --- a/session_query.go +++ b/session_query.go @@ -15,68 +15,73 @@ import ( "github.com/go-xorm/core" ) +func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) { + if len(sqlorArgs) > 0 { + return sqlorArgs[0].(string), sqlorArgs[1:], nil + } + + if session.statement.RawSQL != "" { + return session.statement.RawSQL, session.statement.RawParams, nil + } + + if len(session.statement.TableName()) <= 0 { + return "", nil, ErrTableNotFound + } + + var columnStr = session.statement.ColumnStr + if len(session.statement.selectStr) > 0 { + columnStr = session.statement.selectStr + } else { + if session.statement.JoinStr == "" { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1)) + } else { + columnStr = session.statement.genColumnStr() + } + } + } else { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1)) + } else { + columnStr = "*" + } + } + } + if columnStr == "" { + columnStr = "*" + } + } + + condSQL, condArgs, err := builder.ToSQL(session.statement.cond) + if err != nil { + return "", nil, err + } + + args := append(session.statement.joinArgs, condArgs...) + sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL) + if err != nil { + return "", nil, err + } + // for mssql and use limit + qs := strings.Count(sqlStr, "?") + if len(args)*2 == qs { + args = append(args, args...) + } + + return sqlStr, args, nil +} + // Query runs a raw sql and return records as []map[string][]byte func (session *Session) Query(sqlorArgs ...interface{}) ([]map[string][]byte, error) { if session.isAutoClose { defer session.Close() } - var sqlStr string - var args []interface{} - if len(sqlorArgs) == 0 { - if session.statement.RawSQL != "" { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } else { - if len(session.statement.TableName()) <= 0 { - return nil, ErrTableNotFound - } - - var columnStr = session.statement.ColumnStr - if len(session.statement.selectStr) > 0 { - columnStr = session.statement.selectStr - } else { - if session.statement.JoinStr == "" { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1)) - } else { - columnStr = session.statement.genColumnStr() - } - } - } else { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1)) - } else { - columnStr = "*" - } - } - } - if columnStr == "" { - columnStr = "*" - } - } - - condSQL, condArgs, err := builder.ToSQL(session.statement.cond) - if err != nil { - return nil, err - } - - args = append(session.statement.joinArgs, condArgs...) - sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL) - if err != nil { - return nil, err - } - // for mssql and use limit - qs := strings.Count(sqlStr, "?") - if len(args)*2 == qs { - args = append(args, args...) - } - } - } else { - sqlStr = sqlorArgs[0].(string) - args = sqlorArgs[1:] + sqlStr, args, err := session.genQuerySQL(sqlorArgs...) + if err != nil { + return nil, err } return session.queryBytes(sqlStr, args...) @@ -174,11 +179,16 @@ func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) } // QueryString runs a raw sql and return records as []map[string]string -func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) { +func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) { if session.isAutoClose { defer session.Close() } + sqlStr, args, err := session.genQuerySQL(sqlorArgs...) + if err != nil { + return nil, err + } + rows, err := session.queryRows(sqlStr, args...) if err != nil { return nil, err @@ -222,11 +232,16 @@ func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, er } // QueryInterface runs a raw sql and return records as []map[string]interface{} -func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) { +func (session *Session) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) { if session.isAutoClose { defer session.Close() } + sqlStr, args, err := session.genQuerySQL(sqlorArgs...) + if err != nil { + return nil, err + } + rows, err := session.queryRows(sqlStr, args...) if err != nil { return nil, err