diff options
Diffstat (limited to 'vendor/github.com/go-xorm/xorm/session_raw.go')
-rw-r--r-- | vendor/github.com/go-xorm/xorm/session_raw.go | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/vendor/github.com/go-xorm/xorm/session_raw.go b/vendor/github.com/go-xorm/xorm/session_raw.go index 0f5a0a43..b44b1cd5 100644 --- a/vendor/github.com/go-xorm/xorm/session_raw.go +++ b/vendor/github.com/go-xorm/xorm/session_raw.go @@ -6,6 +6,10 @@ package xorm import ( "database/sql" + "fmt" + "reflect" + "strconv" + "time" "github.com/go-xorm/core" ) @@ -59,6 +63,60 @@ func (session *Session) innerQuery(sqlStr string, params ...interface{}) (*core. return stmt, rows, nil } +func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2map(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + +func value2Bytes(rawValue *reflect.Value) (data []byte, err error) { + var str string + str, err = reflect2value(rawValue) + if err != nil { + return + } + data = []byte(str) + return +} + +func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { + result := make(map[string][]byte) + 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 + } + + if data, err := value2Bytes(&rawValue); err == nil { + result[key] = data + } else { + return nil, err // !nashtsai! REVIEW, should return err or just error log? + } + } + return result, nil +} + func (session *Session) innerQuery2(sqlStr string, params ...interface{}) ([]map[string][]byte, error) { _, rows, err := session.innerQuery(sqlStr, params...) if rows != nil { @@ -80,6 +138,121 @@ func (session *Session) Query(sqlStr string, paramStr ...interface{}) ([]map[str return session.query(sqlStr, paramStr...) } +func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2mapStr(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + +func reflect2value(rawValue *reflect.Value) (str string, err error) { + aa := reflect.TypeOf((*rawValue).Interface()) + vv := reflect.ValueOf((*rawValue).Interface()) + switch aa.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + str = strconv.FormatInt(vv.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + str = strconv.FormatUint(vv.Uint(), 10) + case reflect.Float32, reflect.Float64: + str = strconv.FormatFloat(vv.Float(), 'f', -1, 64) + case reflect.String: + str = vv.String() + case reflect.Array, reflect.Slice: + switch aa.Elem().Kind() { + case reflect.Uint8: + data := rawValue.Interface().([]byte) + str = string(data) + default: + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + // time type + case reflect.Struct: + if aa.ConvertibleTo(core.TimeType) { + str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano) + } else { + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + case reflect.Bool: + str = strconv.FormatBool(vv.Bool()) + case reflect.Complex128, reflect.Complex64: + str = fmt.Sprintf("%v", vv.Complex()) + /* TODO: unsupported types below + case reflect.Map: + case reflect.Ptr: + case reflect.Uintptr: + case reflect.UnsafePointer: + case reflect.Chan, reflect.Func, reflect.Interface: + */ + default: + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + return +} + +func value2String(rawValue *reflect.Value) (data string, err error) { + data, err = reflect2value(rawValue) + if err != nil { + return + } + return +} + +func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) { + result := make(map[string]string) + 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 + } + + if data, err := value2String(&rawValue); err == nil { + result[key] = data + } else { + return nil, err // !nashtsai! REVIEW, should return err or just error log? + } + } + return result, nil +} + +func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) ([]map[string]string, error) { + rows, err := tx.Query(sqlStr, params...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2Strings(rows) +} + +func query2(db *core.DB, sqlStr string, params ...interface{}) ([]map[string]string, error) { + rows, err := db.Query(sqlStr, params...) + if err != nil { + return nil, err + } + defer rows.Close() + return rows2Strings(rows) +} + // QueryString runs a raw sql and return records as []map[string]string func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) { defer session.resetStatement() |