From 1a7b21155bea2ad3039ec38c579bc154d6e1fba6 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 15 Oct 2018 13:03:43 +0800 Subject: [PATCH] Add query slice string (#1114) * add query slice string * fix tests --- session_query.go | 64 +++++++++++++++++++++++++++++++++++++++++++ session_query_test.go | 37 +++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/session_query.go b/session_query.go index 1d0b156b..6d597cc4 100644 --- a/session_query.go +++ b/session_query.go @@ -166,6 +166,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 { @@ -182,6 +210,22 @@ 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 +} + // QueryString runs a raw sql and return records as []map[string]string func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) { if session.isAutoClose { @@ -202,6 +246,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)) diff --git a/session_query_test.go b/session_query_test.go index 2c1fb617..5ce89a4a 100644 --- a/session_query_test.go +++ b/session_query_test.go @@ -224,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())