From d3689a0c8b2e33ad3d0e85b26960a480725fb852 Mon Sep 17 00:00:00 2001 From: eson Date: Mon, 7 Sep 2020 15:13:50 +0800 Subject: [PATCH] TODO: sql to time.Time Type --- autostore_test.go | 223 ++++++++++++++++++++++++++++++++++------------ build.sh | 2 +- go.mod | 1 + 3 files changed, 170 insertions(+), 56 deletions(-) diff --git a/autostore_test.go b/autostore_test.go index 286fb56..7e4a808 100644 --- a/autostore_test.go +++ b/autostore_test.go @@ -3,11 +3,14 @@ package intimate import ( "database/sql" "encoding/binary" + "encoding/json" "fmt" "log" "reflect" "strconv" "testing" + + "github.com/davecgh/go-spew/spew" ) type Store struct { @@ -120,14 +123,9 @@ func (queue *Queue) Pop() (result interface{}, err error) { for i := 0; i < obj.NumField(); i++ { field := obj.Field(i) convert(*fields[i].(*interface{}), field, columntypes[i]) - // if field.Type().Kind() == reflect.Ptr { - // field.Elem().Set(reflect.ValueOf(*fields[i].(*interface{}))) - // continue - // } - // field.Set(reflect.ValueOf(*fields[i].(*interface{}))) } - return obj.Interface(), err + return obj.Addr().Interface(), err } func TestAutoStore(t *testing.T) { @@ -135,90 +133,204 @@ func TestAutoStore(t *testing.T) { store := NewStore(uri) queue := store.Table("streamer").Queue(TSreamer{}, "operator = 0") - t.Error(queue.Pop()) + re, _ := queue.Pop() + + pstreamer := re.(*TSreamer) + m := make(map[string]interface{}) + json.Unmarshal(pstreamer.Iface.([]byte), &m) + spew.Println(re.(*TSreamer), m) streamer := &TSreamer{} streamer.Uid = 2 - streamer.UserID = &sql.NullString{String: "xixi", Valid: true} + streamer.UserID = &sql.NullString{String: "hehe", Valid: true} streamer.Name = "streamer" streamer.Operator = 0 + streamer.Bit = 0b11 streamer.Ext = &sql.NullString{String: "ext", Valid: true} - err := store.Table("streamer").Insert(streamer) + + tag := make(map[string]interface{}) + tag["json"] = true + tag["name"] = "test" + btag, err := json.Marshal(tag) + if err != nil { + t.Error(err) + } + streamer.Iface = btag + + err = store.Table("streamer").Insert(streamer) if err != nil { t.Error(err) } } - -func convert(dest interface{}, field reflect.Value, columntype *sql.ColumnType) error { - - log.Println("type:", field.Type(), ",kind:", field.Kind(), ",field:", field) - if field.Kind() == reflect.Ptr { - fn := field.Type().Elem().Name() // New 一个 field.Type().Elem() . 然后判断 columntype 转化 成 NullString Time - field = field.Elem() // - log.Println("type:", fn, ",kind:", field.Kind(), ",field:", field) - } - - if field.Kind() == reflect.Interface { - - } - - // log.Println(field.Kind(), field, reflect.TypeOf(field).Elem().Name(), columntype.ScanType().Kind()) - - switch fv := field.Kind(); fv { +func assign(field reflect.Value, dest interface{}) (bool, error) { + switch field.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if dest == nil { - return fmt.Errorf("converting NULL to %s is unsupported", field.Kind()) - } - log.Println(binary.Varint(dest.([]byte))) s := asString(dest) i64, err := strconv.ParseInt(s, 10, field.Type().Bits()) if err != nil { err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) + return false, fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) } field.SetInt(i64) - return nil + return false, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if dest == nil { - return fmt.Errorf("converting NULL to %s is unsupported", field.Kind()) - } + s := asString(dest) u64, err := strconv.ParseUint(s, 10, field.Type().Bits()) if err != nil { err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) + return false, fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) } field.SetUint(u64) - return nil + return false, nil case reflect.Float32, reflect.Float64: - if dest == nil { - return fmt.Errorf("converting NULL to %s is unsupported", field.Kind()) - } s := asString(dest) f64, err := strconv.ParseFloat(s, field.Type().Bits()) if err != nil { err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) + return false, fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) } field.SetFloat(f64) - return nil + return false, nil case reflect.String: - if dest == nil { - return fmt.Errorf("converting NULL to %s is unsupported", field.Kind()) - } - switch v := dest.(type) { - case string: - field.SetString(v) - return nil - case []byte: - field.SetString(string(v)) - return nil - } - default: + field.SetString(string(dest.([]byte))) + return false, nil + case reflect.Interface: + return true, nil + } - // log.Println(fv, columntype.ScanType().Kind()) + return false, fmt.Errorf("") +} +func convert(dest interface{}, field reflect.Value, columntype *sql.ColumnType) error { + + log.Println("type:", field.Type(), ",kind:", field.Kind(), ",field:", field, "scanType:", columntype.ScanType(), "databaseType:", columntype.DatabaseTypeName()) + if field.Kind() == reflect.Ptr { + fn := field.Type().Elem() // New 一个 field.Type().Elem() . 然后判断 columntype 转化 成 NullString Time + field.Set(reflect.New(fn)) + field = field.Elem() + log.Println("type:", fn.Name(), ",kind:", field.Kind(), ",fieldtype:", field.Type()) + } + + // log.Println(field.Kind(), field, reflect.TypeOf(field).Elem().Name(), columntype.ScanType().Kind()) + + if dest == nil { + return fmt.Errorf("converting NULL to %s is unsupported", field.Kind()) + } + + switch columntype.DatabaseTypeName() { + case "TINYINT": + fallthrough + case "SMALLINT": + fallthrough + case "MEDIUMINT": + fallthrough + case "INT": + fallthrough + case "BIGINT": + + isdefault, err := assign(field, dest) + if err != nil { + return err + } + if isdefault { + s := asString(dest) + i64, err := strconv.ParseInt(s, 10, 64) + if err != nil { + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) + } + // reflect.New(reflect.TypeOf(i64)) + field.Set(reflect.ValueOf(i64)) + } + return nil + + case "FLOAT": + fallthrough + case "DOUBLE": + fallthrough + case "DECIMAL": + isdefault, err := assign(field, dest) + if err != nil { + return err + } + if isdefault { + s := asString(dest) + f64, err := strconv.ParseFloat(s, 64) + if err != nil { + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", dest, s, field.Kind(), err) + } + field.Set(reflect.ValueOf(f64)) + } + return nil + + case "BINARY": + fallthrough + case "VARBINARY": + fallthrough + case "TINYBLOB": + fallthrough + case "BLOB": + fallthrough + case "MEDIUMBLOB": + fallthrough + case "LONGBLOB": + fallthrough + case "JSON": + isdefault, err := assign(field, dest) + if err != nil { + return err + } + if isdefault { + field.Set(reflect.ValueOf(dest.([]byte))) + } + case "CHAR": + fallthrough + case "VARCHAR": + fallthrough + case "TINYTEXT": + fallthrough + case "TEXT": + fallthrough + case "MEDIUMTEXT": + fallthrough + case "LONGTEXT": + isdefault, err := assign(field, dest) + if err != nil { + return err + } + if isdefault { + field.Set(reflect.ValueOf(string(dest.([]byte)))) + } + return nil + case "BIT": + var bits []byte = make([]byte, 8) + copy(bits, dest.([]byte)) + switch field.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + field.SetInt(int64(binary.LittleEndian.Uint64(bits))) + return nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + field.SetUint(binary.LittleEndian.Uint64(bits)) + return nil + case reflect.Interface: + field.Set(reflect.ValueOf(binary.LittleEndian.Uint64(bits))) + return nil + } + + return nil + } + + // log.Println(fv, columntype.ScanType().Kind()) + + if iscan, ok := field.Addr().Interface().(sql.Scanner); ok { + err := iscan.Scan(dest) + if err != nil { + return err + } + return nil } return nil @@ -344,5 +456,6 @@ type TSreamer struct { UserID *sql.NullString `field:"userid"` Ext *sql.NullString `field:"ext"` Iface interface{} `field:"tag"` + Bit uint64 `field:"bit"` Operator int `field:"operator"` } diff --git a/build.sh b/build.sh index f92ccd4..19765fe 100644 --- a/build.sh +++ b/build.sh @@ -20,4 +20,4 @@ do projectworkspace=$src/bin/$projectname cd $path && mkdir $projectworkspace -p && go build -o $projectworkspace/$projectname cd $src -done +done \ No newline at end of file diff --git a/go.mod b/go.mod index ca8b0a7..1107f9c 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/474420502/focus v0.12.0 github.com/474420502/gcurl v0.4.5 github.com/474420502/requests v1.9.1 + github.com/davecgh/go-spew v1.1.1 github.com/go-sql-driver/mysql v1.5.0 github.com/lestrrat-go/libxml2 v0.0.0-20200215080510-6483566f52cb github.com/tebeka/selenium v0.9.9