TODO: sql to time.Time Type

This commit is contained in:
eson 2020-09-07 15:13:50 +08:00
parent 83dcdf86c9
commit d3689a0c8b
3 changed files with 170 additions and 56 deletions

View File

@ -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"`
}

View File

@ -20,4 +20,4 @@ do
projectworkspace=$src/bin/$projectname
cd $path && mkdir $projectworkspace -p && go build -o $projectworkspace/$projectname
cd $src
done
done

1
go.mod
View File

@ -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