浏览代码

Add query slice string

* add query slice string

* fix tests
xormplus 7 年之前
父节点
当前提交
455c8e3714
共有 2 个文件被更改,包括 101 次插入0 次删除
  1. 63 0
      session_query.go
  2. 38 0
      session_query_test.go

+ 63 - 0
session_query.go

@@ -215,6 +215,34 @@ func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string,
 	return result, nil
 }
 
+func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) {
+	result := make([]string, 0, len(fields))
+	scanResultContainers := make([]interface{}, len(fields))
+	for i := 0; i < len(fields); i++ {
+		var scanResultContainer interface{}
+		scanResultContainers[i] = &scanResultContainer
+	}
+	if err := rows.Scan(scanResultContainers...); err != nil {
+		return nil, err
+	}
+
+	for i := 0; i < len(fields); i++ {
+		rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[i]))
+		// if row is null then as empty string
+		if rawValue.Interface() == nil {
+			result = append(result, "")
+			continue
+		}
+
+		if data, err := value2String(&rawValue); err == nil {
+			result = append(result, data)
+		} else {
+			return nil, err
+		}
+	}
+	return result, nil
+}
+
 func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
 	fields, err := rows.Columns()
 	if err != nil {
@@ -231,6 +259,21 @@ func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error)
 	return resultsSlice, nil
 }
 
+func rows2SliceString(rows *core.Rows) (resultsSlice [][]string, err error) {
+	fields, err := rows.Columns()
+	if err != nil {
+		return nil, err
+	}
+	for rows.Next() {
+		record, err := row2sliceStr(rows, fields)
+		if err != nil {
+			return nil, err
+		}
+		resultsSlice = append(resultsSlice, record)
+	}
+	return resultsSlice, nil
+}
+
 func (session *Session) QueryRows(sqlorArgs ...interface{}) (*core.Rows, error) {
 	if session.isAutoClose {
 		defer session.Close()
@@ -269,6 +312,26 @@ func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]stri
 	return rows2Strings(rows)
 }
 
+// QuerySliceString runs a raw sql and return records as [][]string
+func (session *Session) QuerySliceString(sqlorArgs ...interface{}) ([][]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
+	}
+	defer rows.Close()
+
+	return rows2SliceString(rows)
+}
+
 func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
 	resultsMap = make(map[string]interface{}, len(fields))
 	scanResultContainers := make([]interface{}, len(fields))

+ 38 - 0
session_query_test.go

@@ -11,6 +11,7 @@ import (
 	"time"
 
 	"github.com/go-xorm/builder"
+	"github.com/go-xorm/core"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -223,6 +224,43 @@ func TestQueryStringNoParam(t *testing.T) {
 	}
 }
 
+func TestQuerySliceStringNoParam(t *testing.T) {
+	assert.NoError(t, prepareEngine())
+
+	type GetVar6 struct {
+		Id  int64 `xorm:"autoincr pk"`
+		Msg bool  `xorm:"bit"`
+	}
+
+	assert.NoError(t, testEngine.Sync2(new(GetVar6)))
+
+	var data = GetVar6{
+		Msg: false,
+	}
+	_, err := testEngine.Insert(data)
+	assert.NoError(t, err)
+
+	records, err := testEngine.Table("get_var6").Limit(1).QuerySliceString()
+	assert.NoError(t, err)
+	assert.EqualValues(t, 1, len(records))
+	assert.EqualValues(t, "1", records[0][0])
+	if testEngine.Dialect().URI().DbType == core.POSTGRES {
+		assert.EqualValues(t, "false", records[0][1])
+	} else {
+		assert.EqualValues(t, "0", records[0][1])
+	}
+
+	records, err = testEngine.Table("get_var6").Where(builder.Eq{"id": 1}).QuerySliceString()
+	assert.NoError(t, err)
+	assert.EqualValues(t, 1, len(records))
+	assert.EqualValues(t, "1", records[0][0])
+	if testEngine.Dialect().URI().DbType == core.POSTGRES {
+		assert.EqualValues(t, "false", records[0][1])
+	} else {
+		assert.EqualValues(t, "0", records[0][1])
+	}
+}
+
 func TestQueryInterfaceNoParam(t *testing.T) {
 	assert.NoError(t, prepareEngine())