Browse Source

Query now could work with Where, In, SQL and other condition methods

xormplus 8 years ago
parent
commit
1ba0d4c630
4 changed files with 115 additions and 5 deletions
  1. 2 2
      engine.go
  2. 63 2
      session_query.go
  3. 49 0
      session_query_test.go
  4. 1 1
      session_raw_test.go

+ 2 - 2
engine.go

@@ -1378,10 +1378,10 @@ func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error)
 }
 
 // Query a raw sql and return records as []map[string][]byte
-func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
+func (engine *Engine) Query(sqlorArgs ...interface{}) (resultsSlice []map[string][]byte, err error) {
 	session := engine.NewSession()
 	defer session.Close()
-	return session.QueryBytes(sql, paramStr...)
+	return session.QueryBytes(sqlorArgs...)
 }
 
 // QueryString runs a raw sql and return records as []map[string]string

+ 63 - 2
session_query.go

@@ -8,17 +8,78 @@ import (
 	"fmt"
 	"reflect"
 	"strconv"
+	"strings"
 	"time"
 
+	"github.com/go-xorm/builder"
 	"github.com/xormplus/core"
 )
 
-// Query runs a raw sql and return records as []map[string][]byte
-func (session *Session) QueryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
+// QueryBytes runs a raw sql and return records as []map[string][]byte
+func (session *Session) QueryBytes(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:]
+	}
+
 	return session.queryBytes(sqlStr, args...)
 }
 

+ 49 - 0
session_query_test.go

@@ -134,3 +134,52 @@ func TestQueryInterface(t *testing.T) {
 	assert.EqualValues(t, 28, toInt64(records[0]["age"]))
 	assert.EqualValues(t, 1.5, toFloat64(records[0]["money"]))
 }
+
+func TestQueryNoParams(t *testing.T) {
+	assert.NoError(t, prepareEngine())
+
+	type QueryNoParams struct {
+		Id      int64  `xorm:"autoincr pk"`
+		Msg     string `xorm:"varchar(255)"`
+		Age     int
+		Money   float32
+		Created time.Time `xorm:"created"`
+	}
+
+	testEngine.ShowSQL(true)
+
+	assert.NoError(t, testEngine.Sync2(new(QueryNoParams)))
+
+	var q = QueryNoParams{
+		Msg:   "message",
+		Age:   20,
+		Money: 3000,
+	}
+	cnt, err := testEngine.Insert(&q)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 1, cnt)
+
+	assertResult := func(t *testing.T, results []map[string][]byte) {
+		assert.EqualValues(t, 1, len(results))
+		id, err := strconv.ParseInt(string(results[0]["id"]), 10, 64)
+		assert.NoError(t, err)
+		assert.EqualValues(t, 1, id)
+		assert.Equal(t, "message", string(results[0]["msg"]))
+
+		age, err := strconv.Atoi(string(results[0]["age"]))
+		assert.NoError(t, err)
+		assert.EqualValues(t, 20, age)
+
+		money, err := strconv.ParseFloat(string(results[0]["money"]), 32)
+		assert.NoError(t, err)
+		assert.EqualValues(t, 3000, money)
+	}
+
+	results, err := testEngine.Table("query_no_params").Limit(10).Query()
+	assert.NoError(t, err)
+	assertResult(t, results)
+
+	results, err = testEngine.SQL("select * from query_no_params").Query()
+	assert.NoError(t, err)
+	assertResult(t, results)
+}

+ 1 - 1
session_raw_test.go

@@ -11,7 +11,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-func TestQuery(t *testing.T) {
+func TestExecAndQuery(t *testing.T) {
 	assert.NoError(t, prepareEngine())
 
 	type UserinfoQuery struct {