diff --git a/engine.go b/engine.go index 08a4bd66..dfe146d4 100644 --- a/engine.go +++ b/engine.go @@ -330,7 +330,7 @@ func (engine *Engine) DumpAll(w io.Writer) error { } for _, table := range tables { - _, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", "", "")+"\n\n") + _, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+"\n\n") if err != nil { return err } diff --git a/helpers.go b/helpers.go index 71b29074..4d20141c 100644 --- a/helpers.go +++ b/helpers.go @@ -70,28 +70,23 @@ func sliceEq(left, right []string) bool { return true } -func value2Bytes(rawValue *reflect.Value) (data []byte, err error) { +func reflect2value(rawValue *reflect.Value) (str string, err error) { aa := reflect.TypeOf((*rawValue).Interface()) vv := reflect.ValueOf((*rawValue).Interface()) - - var str string switch aa.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: str = strconv.FormatInt(vv.Int(), 10) - data = []byte(str) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: str = strconv.FormatUint(vv.Uint(), 10) - data = []byte(str) case reflect.Float32, reflect.Float64: str = strconv.FormatFloat(vv.Float(), 'f', -1, 64) - data = []byte(str) case reflect.String: str = vv.String() - data = []byte(str) case reflect.Array, reflect.Slice: switch aa.Elem().Kind() { case reflect.Uint8: - data = rawValue.Interface().([]byte) + data := rawValue.Interface().([]byte) + str = string(data) default: err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) } @@ -99,16 +94,13 @@ func value2Bytes(rawValue *reflect.Value) (data []byte, err error) { case reflect.Struct: if aa == core.TimeType { str = rawValue.Interface().(time.Time).Format(time.RFC3339Nano) - data = []byte(str) } else { err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) } case reflect.Bool: str = strconv.FormatBool(vv.Bool()) - data = []byte(str) case reflect.Complex128, reflect.Complex64: str = fmt.Sprintf("%v", vv.Complex()) - data = []byte(str) /* TODO: unsupported types below case reflect.Map: case reflect.Ptr: @@ -122,6 +114,40 @@ func value2Bytes(rawValue *reflect.Value) (data []byte, err error) { return } +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 value2String(rawValue *reflect.Value) (data string, err error) { + data, err = reflect2value(rawValue) + if err != nil { + return + } + return +} + +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 rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { fields, err := rows.Columns() if err != nil { diff --git a/mysql_dialect.go b/mysql_dialect.go index ee1f4e06..40d699ce 100644 --- a/mysql_dialect.go +++ b/mysql_dialect.go @@ -264,6 +264,7 @@ func (db *mysql) GetTables() ([]*core.Table, error) { } table.Name = name + table.StoreEngine = engine tables = append(tables, table) } return tables, nil diff --git a/session.go b/session.go index 5d127c74..8c80c575 100644 --- a/session.go +++ b/session.go @@ -1393,6 +1393,34 @@ func (session *Session) dropAll() error { return nil } +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 row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { result := make(map[string][]byte) scanResultContainers := make([]interface{}, len(fields)) @@ -1831,6 +1859,62 @@ func (session *Session) Query(sqlStr string, paramStr ...interface{}) (resultsSl return session.query(sqlStr, paramStr...) } + + + + +// ============================= +// for string +// ============================= +func (session *Session) query2(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) { + session.queryPreprocess(&sqlStr, paramStr...) + + if session.IsAutoCommit { + return query2(session.Db, sqlStr, paramStr...) + } + return txQuery2(session.Tx, sqlStr, paramStr...) +} + +func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err 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{}) (resultsSlice []map[string]string, err error) { + s, err := db.Prepare(sqlStr) + if err != nil { + return nil, err + } + defer s.Close() + rows, err := s.Query(params...) + if err != nil { + return nil, err + } + defer rows.Close() + return rows2Strings(rows) +} + +// Exec a raw sql and return records as []map[string]string +func (session *Session) Q(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) { + err = session.newDb() + if err != nil { + return nil, err + } + defer session.resetStatement() + if session.IsAutoClose { + defer session.Close() + } + return session.query2(sqlStr, paramStr...) +} + + + + // insert one or more beans func (session *Session) Insert(beans ...interface{}) (int64, error) { var affected int64 = 0