github.com/RevenueMonster/sqlike@v1.0.6/sql/schema/schema.go (about) 1 package schema 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "sync" 8 "time" 9 10 "cloud.google.com/go/civil" 11 "github.com/RevenueMonster/sqlike/reflext" 12 "github.com/RevenueMonster/sqlike/sql/driver" 13 sqltype "github.com/RevenueMonster/sqlike/sql/type" 14 "github.com/RevenueMonster/sqlike/sqlike/columns" 15 "github.com/google/uuid" 16 "github.com/paulmach/orb" 17 gouuid "github.com/satori/go.uuid" 18 "golang.org/x/text/currency" 19 "golang.org/x/text/language" 20 ) 21 22 // DataTyper : 23 type DataTyper interface { 24 DataType(info driver.Info, sf reflext.StructFielder) columns.Column 25 } 26 27 // DataTypeFunc : 28 type DataTypeFunc func(sf reflext.StructFielder) columns.Column 29 30 // Builder : 31 type Builder struct { 32 mutex *sync.Mutex 33 typeMap map[interface{}]sqltype.Type 34 builders map[sqltype.Type]DataTypeFunc 35 } 36 37 // NewBuilder : 38 func NewBuilder() *Builder { 39 sb := &Builder{ 40 mutex: new(sync.Mutex), 41 typeMap: make(map[interface{}]sqltype.Type), 42 builders: make(map[sqltype.Type]DataTypeFunc), 43 } 44 sb.SetDefaultTypes() 45 return sb 46 } 47 48 // SetType : 49 func (sb *Builder) SetType(it interface{}, t sqltype.Type) { 50 sb.mutex.Lock() 51 defer sb.mutex.Unlock() 52 sb.typeMap[it] = t 53 } 54 55 // SetTypeBuilder : 56 func (sb *Builder) SetTypeBuilder(t sqltype.Type, builder DataTypeFunc) { 57 sb.mutex.Lock() 58 defer sb.mutex.Unlock() 59 sb.builders[t] = builder 60 } 61 62 // LookUpType : 63 func (sb *Builder) LookUpType(t reflect.Type) (typ sqltype.Type, exists bool) { 64 t = reflext.Deref(t) 65 typ, exists = sb.typeMap[t] 66 return 67 } 68 69 // GetColumn : 70 func (sb *Builder) GetColumn(info driver.Info, sf reflext.StructFielder) (columns.Column, error) { 71 t := reflext.Deref(sf.Type()) 72 v := reflect.New(t) 73 if x, ok := v.Interface().(DataTyper); ok { 74 return x.DataType(info, sf), nil 75 } 76 77 if x, ok := sb.typeMap[t]; ok { 78 return sb.builders[x](sf), nil 79 } 80 81 if x, ok := sb.typeMap[t.Kind()]; ok { 82 return sb.builders[x](sf), nil 83 } 84 85 return columns.Column{}, fmt.Errorf("schema: invalid data type support %v", t) 86 } 87 88 // SetDefaultTypes : 89 func (sb *Builder) SetDefaultTypes() { 90 sb.SetType(reflect.TypeOf([]byte{}), sqltype.Byte) 91 sb.SetType(reflect.TypeOf(uuid.UUID{}), sqltype.UUID) 92 sb.SetType(reflect.TypeOf(gouuid.UUID{}), sqltype.UUID) 93 sb.SetType(reflect.TypeOf(language.Tag{}), sqltype.String) 94 sb.SetType(reflect.TypeOf(currency.Unit{}), sqltype.Char) 95 sb.SetType(reflect.TypeOf(time.Time{}), sqltype.DateTime) 96 sb.SetType(reflect.TypeOf(time.Location{}), sqltype.String) 97 sb.SetType(reflect.TypeOf(civil.Date{}), sqltype.Date) 98 sb.SetType(reflect.TypeOf(civil.Time{}), sqltype.Time) 99 sb.SetType(reflect.TypeOf(json.RawMessage{}), sqltype.JSON) 100 sb.SetType(reflect.TypeOf(orb.Point{}), sqltype.Point) 101 sb.SetType(reflect.TypeOf(orb.LineString{}), sqltype.LineString) 102 sb.SetType(reflect.TypeOf(orb.Polygon{}), sqltype.Polygon) 103 sb.SetType(reflect.TypeOf(orb.MultiPoint{}), sqltype.MultiPoint) 104 sb.SetType(reflect.TypeOf(orb.MultiLineString{}), sqltype.MultiLineString) 105 sb.SetType(reflect.TypeOf(orb.MultiPolygon{}), sqltype.MultiPolygon) 106 sb.SetType(reflect.String, sqltype.String) 107 sb.SetType(reflect.Bool, sqltype.Bool) 108 sb.SetType(reflect.Int, sqltype.Int) 109 sb.SetType(reflect.Int8, sqltype.Int8) 110 sb.SetType(reflect.Int16, sqltype.Int16) 111 sb.SetType(reflect.Int32, sqltype.Int32) 112 sb.SetType(reflect.Int64, sqltype.Int64) 113 sb.SetType(reflect.Uint, sqltype.Uint) 114 sb.SetType(reflect.Uint8, sqltype.Uint8) 115 sb.SetType(reflect.Uint16, sqltype.Uint16) 116 sb.SetType(reflect.Uint32, sqltype.Uint32) 117 sb.SetType(reflect.Uint64, sqltype.Uint64) 118 sb.SetType(reflect.Float32, sqltype.Float32) 119 sb.SetType(reflect.Float64, sqltype.Float64) 120 sb.SetType(reflect.Struct, sqltype.Struct) 121 sb.SetType(reflect.Array, sqltype.Array) 122 sb.SetType(reflect.Slice, sqltype.Slice) 123 sb.SetType(reflect.Map, sqltype.Map) 124 }