github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xdatabase/xsql/types.go (about) 1 package xsql 2 3 import ( 4 "database/sql/driver" 5 "errors" 6 "net" 7 "strings" 8 ) 9 10 // StringArray present a slice of array which store in database in string mode, 11 // but in application is string slice mode, this will translate automatically. 12 type StringArray []string 13 14 func (a StringArray) String() string { 15 return strings.Join(a, ",") 16 } 17 18 func (a *StringArray) Scan(src interface{}) error { 19 switch x := src.(type) { 20 case string: 21 *a = strings.Split(x, ",") 22 return nil 23 case []byte: 24 *a = strings.Split(string(x), ",") 25 return nil 26 default: 27 return nil 28 } 29 } 30 31 func (a StringArray) Value() (driver.Value, error) { 32 x := strings.Join(a, ",") 33 return x, nil 34 } 35 36 // Enum present a selectable of value which store in database in int mode, 37 // but in application is string mode, this will translate automatically. 38 type Enum struct { 39 value string 40 valueMap map[string]int 41 keyMap map[int]string 42 } 43 44 func NewEnum(valueMap map[string]int, defs ...string) *Enum { 45 def := "" 46 if len(defs) > 0 { 47 def = defs[0] 48 } 49 keyMap := make(map[int]string) 50 for v, i := range valueMap { 51 keyMap[i] = v 52 } 53 return &Enum{ 54 value: def, 55 valueMap: valueMap, 56 keyMap: keyMap, 57 } 58 } 59 60 func (a *Enum) String() string { 61 return a.value 62 } 63 64 func (a *Enum) fromInt(i int) { 65 a.value = a.keyMap[i] 66 } 67 68 func (a *Enum) Scan(src interface{}) error { 69 switch x := src.(type) { 70 case int: 71 a.fromInt(x) 72 return nil 73 case int64: 74 a.fromInt(int(x)) 75 return nil 76 case int32: 77 a.fromInt(int(x)) 78 return nil 79 default: 80 return nil 81 } 82 } 83 84 func (a Enum) Value() (driver.Value, error) { 85 return a.valueMap[a.value], nil 86 } 87 88 // IPV4 present a selectable of ipv4 address which store in database in int mode, 89 // but in application is ipv4 mode, this will translate automatically. 90 type IPV4 struct { 91 ipStr string 92 ip net.IP 93 } 94 95 func NewIPV4(ip string) (*IPV4, error) { 96 ipaddr := net.ParseIP(ip) 97 if ipaddr == nil { 98 return nil, errors.New("err: parse ipv4 failed: " + ip) 99 } 100 return &IPV4{ip: ipaddr, ipStr: ip}, nil 101 } 102 103 func (a IPV4) toUint32() uint32 { 104 return uint32(a.ip[0])<<24 + uint32(a.ip[1])<<16 + uint32(a.ip[2])<<8 + uint32(a.ip[3]) 105 } 106 107 func (a *IPV4) fromUint32(u uint32) error { 108 a.ip[0] = uint8(u >> 24) 109 a.ip[1] = uint8(u >> 16) 110 a.ip[2] = uint8(u >> 8) 111 a.ip[3] = uint8(u) 112 a.ipStr = a.ip.String() 113 return nil 114 } 115 116 func (a IPV4) IP() net.IP { 117 return a.ip 118 } 119 120 func (a IPV4) String() string { 121 return a.ipStr 122 } 123 124 func (a *IPV4) Scan(src interface{}) error { 125 a.ip = a.ip[:0] 126 switch x := src.(type) { 127 case uint32: 128 return a.fromUint32(x) 129 case uint64: 130 return a.fromUint32(uint32(x)) 131 case int64: 132 return a.fromUint32(uint32(x)) 133 default: 134 return errors.New("err: unsupported type") 135 } 136 } 137 138 func (a IPV4) Value() (driver.Value, error) { 139 return a.toUint32(), nil 140 }