From ae6235169ce747378bb3722e06642a8ba23e4b92 Mon Sep 17 00:00:00 2001 From: Edison-Hsu Date: Thu, 28 Jul 2016 12:34:00 +0800 Subject: [PATCH] add QueryMapInterface function in engine.go Query a raw sql and return records as []map[string]interface{} --- engine.go | 7 +++++++ helpers.go | 41 +++++++++++++++++++++++++++++++++++++++++ session.go | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/engine.go b/engine.go index 1f83ec94..2e389055 100644 --- a/engine.go +++ b/engine.go @@ -1486,6 +1486,13 @@ func (engine *Engine) QueryMapString(sql string, paramStr ...interface{}) (resul return session.Query2(sql, paramStr...) } +// Query a raw sql and return records as []map[string]interface{} +func (engine *Engine) QueryMapInterface(sql string, paramStr ...interface{}) (resultsSlice []map[string]interface{}, err error) { + session := engine.NewSession() + defer session.Close() + return session.QueryInterfaces(sql, paramStr...) +} + // Insert one or more records func (engine *Engine) Insert(beans ...interface{}) (int64, error) { session := engine.NewSession() diff --git a/helpers.go b/helpers.go index 9a461c0e..f04c35f6 100644 --- a/helpers.go +++ b/helpers.go @@ -377,6 +377,22 @@ func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { return resultsSlice, nil } +func rows2interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2mapInterface(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { result := make(map[string][]byte) scanResultContainers := make([]interface{}, len(fields)) @@ -433,6 +449,31 @@ func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, return result, nil } +func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) { + result := make(map[string]interface{}) + 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 ii, key := range fields { + rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) + //if row is null then ignore + if rawValue.Interface() == nil { + //fmt.Println("ignore ...", key, rawValue) + continue + } + + result[key] = scanResultContainers[ii] + } + return result, nil +} + func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) { rows, err := tx.Query(sqlStr, params...) if err != nil { diff --git a/session.go b/session.go index a7dc9fb8..b978ba87 100644 --- a/session.go +++ b/session.go @@ -2118,6 +2118,16 @@ func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSl return session.txQuery(session.Tx, sqlStr, paramStr...) } +func (session *Session) queryInterfaces(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]interface{}, err error) { + + session.queryPreprocess(&sqlStr, paramStr...) + + if session.IsAutoCommit { + return session.innerQuery3(sqlStr, paramStr...) + } + return session.txQueryInterface(session.Tx, sqlStr, paramStr...) +} + func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { rows, err := tx.Query(sqlStr, params...) if err != nil { @@ -2128,6 +2138,16 @@ func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{ return rows2maps(rows) } +func (session *Session) txQueryInterface(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]interface{}, err error) { + rows, err := tx.Query(sqlStr, params...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2interfaces(rows) +} + func (session *Session) innerQuery(sqlStr string, params ...interface{}) (*core.Stmt, *core.Rows, error) { var callback func() (*core.Stmt, *core.Rows, error) if session.prepareStmt { @@ -2169,6 +2189,17 @@ func (session *Session) innerQuery2(sqlStr string, params ...interface{}) ([]map return rows2maps(rows) } +func (session *Session) innerQuery3(sqlStr string, params ...interface{}) ([]map[string]interface{}, error) { + _, rows, err := session.innerQuery(sqlStr, params...) + if rows != nil { + defer rows.Close() + } + if err != nil { + return nil, err + } + return rows2interfaces(rows) +} + // Query a raw sql and return records as []map[string][]byte func (session *Session) Query(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) { defer session.resetStatement() @@ -2179,6 +2210,16 @@ func (session *Session) Query(sqlStr string, paramStr ...interface{}) (resultsSl return session.query(sqlStr, paramStr...) } +// for interfaces +func (session *Session) QueryInterfaces(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]interface{}, err error) { + defer session.resetStatement() + if session.IsAutoClose { + defer session.Close() + } + + return session.queryInterfaces(sqlStr, paramStr...) +} + // ============================= // for string // =============================