github.com/eden-framework/sqlx@v0.0.2/builder/def_column.go (about) 1 package builder 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "strconv" 8 "strings" 9 10 "github.com/eden-framework/reflectx" 11 ) 12 13 func Col(name string) *Column { 14 return &Column{ 15 Name: strings.ToLower(name), 16 ColumnType: &ColumnType{}, 17 } 18 } 19 20 var _ TableDefinition = (*Column)(nil) 21 22 type Column struct { 23 Name string 24 FieldName string 25 Table *Table 26 exactly bool 27 28 Description []string 29 Relation []string 30 31 *ColumnType 32 } 33 34 func (c Column) Full() *Column { 35 c.exactly = true 36 return &c 37 } 38 39 func (c *Column) Of(table *Table) *Column { 40 col := &Column{ 41 Name: c.Name, 42 FieldName: c.FieldName, 43 Table: table, 44 exactly: true, 45 ColumnType: c.ColumnType, 46 } 47 return col 48 } 49 50 func (c *Column) IsNil() bool { 51 return c == nil 52 } 53 54 func (c *Column) Ex(ctx context.Context) *Ex { 55 toggles := TogglesFromContext(ctx) 56 57 if c.Table != nil && (c.exactly || toggles.Is(ToggleMultiTable)) { 58 if toggles.Is(ToggleNeedAutoAlias) { 59 return Expr("(?.?) AS ?", c.Table, Expr(c.Name), Expr(c.Name)).Ex(ctx) 60 } 61 return Expr("?.?", c.Table, Expr(c.Name)).Ex(ctx) 62 } 63 return Expr(c.Name).Ex(ctx) 64 } 65 66 func (c *Column) Expr(query string, args ...interface{}) *Ex { 67 e := Expr("") 68 69 qc := 0 70 n := len(args) 71 72 for _, key := range []byte(query) { 73 switch key { 74 case '#': 75 e.WriteExpr(c) 76 case '?': 77 e.WriteByte(key) 78 if n > qc { 79 e.AppendArgs(args[qc]) 80 qc++ 81 } 82 default: 83 e.WriteByte(key) 84 } 85 } 86 87 return e 88 } 89 90 func (c Column) Field(fieldName string) *Column { 91 c.FieldName = fieldName 92 return &c 93 } 94 95 func (c Column) Type(v interface{}, tagValue string) *Column { 96 c.ColumnType = ColumnTypeFromTypeAndTag(reflect.TypeOf(v), tagValue) 97 return &c 98 } 99 100 func (c Column) On(table *Table) *Column { 101 c.Table = table 102 return &c 103 } 104 105 func (c *Column) T() *Table { 106 return c.Table 107 } 108 109 func (c *Column) ValueBy(v interface{}) *Assignment { 110 return ColumnsAndValues(c, v) 111 } 112 113 func (c *Column) Incr(d int) SqlExpr { 114 return c.Expr("# + ?", d) 115 } 116 117 func (c *Column) Desc(d int) SqlExpr { 118 return c.Expr("# - ?", d) 119 } 120 121 func (c *Column) Like(v string) SqlCondition { 122 return AsCond(c.Expr("# LIKE ?", "%"+v+"%")) 123 } 124 125 func (c *Column) LeftLike(v string) SqlCondition { 126 return AsCond(c.Expr("# LIKE ?", "%"+v)) 127 } 128 129 func (c *Column) RightLike(v string) SqlCondition { 130 return AsCond(c.Expr("# LIKE ?", v+"%")) 131 } 132 133 func (c *Column) NotLike(v string) SqlCondition { 134 return AsCond(c.Expr("# NOT LIKE ?", "%"+v+"%")) 135 } 136 137 func (c *Column) IsNull() SqlCondition { 138 return AsCond(c.Expr("# IS NULL")) 139 } 140 141 func (c *Column) IsNotNull() SqlCondition { 142 return AsCond(c.Expr("# IS NOT NULL")) 143 } 144 145 func (c *Column) Between(leftValue interface{}, rightValue interface{}) SqlCondition { 146 return AsCond(c.Expr("# BETWEEN ? AND ?", leftValue, rightValue)) 147 } 148 149 func (c *Column) NotBetween(leftValue interface{}, rightValue interface{}) SqlCondition { 150 return AsCond(c.Expr("# NOT BETWEEN ? AND ?", leftValue, rightValue)) 151 } 152 153 func (c *Column) In(args ...interface{}) SqlCondition { 154 length := len(args) 155 if length == 0 { 156 return nil 157 } 158 159 e := Expr("# IN ") 160 e.WriteGroup(func(e *Ex) { 161 for i := 0; i < length; i++ { 162 e.WriteHolder(i) 163 } 164 }) 165 166 return AsCond(c.Expr(e.String(), args...)) 167 } 168 169 func (c *Column) NotIn(args ...interface{}) SqlCondition { 170 length := len(args) 171 if length == 0 { 172 return nil 173 } 174 175 e := Expr("# NOT IN ") 176 e.WriteGroup(func(e *Ex) { 177 for i := 0; i < length; i++ { 178 e.WriteHolder(i) 179 } 180 }) 181 182 return AsCond(c.Expr(e.String(), args...)) 183 } 184 185 func (c *Column) Eq(v interface{}) SqlCondition { 186 return AsCond(c.Expr("# = ?", v)) 187 } 188 189 func (c *Column) Neq(v interface{}) SqlCondition { 190 return AsCond(c.Expr("# <> ?", v)) 191 } 192 193 func (c *Column) Gt(v interface{}) SqlCondition { 194 return AsCond(c.Expr("# > ?", v)) 195 } 196 197 func (c *Column) Gte(v interface{}) SqlCondition { 198 return AsCond(c.Expr("# >= ?", v)) 199 } 200 201 func (c *Column) Lt(v interface{}) SqlCondition { 202 return AsCond(c.Expr("# < ?", v)) 203 } 204 205 func (c *Column) Lte(v interface{}) SqlCondition { 206 return AsCond(c.Expr("# <= ?", v)) 207 } 208 209 func ColumnTypeFromTypeAndTag(typ reflect.Type, nameAndFlags string) *ColumnType { 210 ct := &ColumnType{} 211 ct.Type = reflectx.DerefRT(typ) 212 213 v := reflect.New(ct.Type).Interface() 214 215 if dataTypeDescriber, ok := v.(DataTypeDescriber); ok { 216 ct.GetDataType = dataTypeDescriber.DataType 217 } 218 219 if strings.Index(nameAndFlags, ",") > -1 { 220 for _, flag := range strings.Split(nameAndFlags, ",")[1:] { 221 nameAndValue := strings.Split(flag, "=") 222 switch strings.ToLower(nameAndValue[0]) { 223 case "null": 224 ct.Null = true 225 case "autoincrement": 226 ct.AutoIncrement = true 227 case "deprecated": 228 rename := "" 229 if len(nameAndValue) > 1 { 230 rename = nameAndValue[1] 231 } 232 ct.DeprecatedActions = &DeprecatedActions{RenameTo: rename} 233 case "size": 234 if len(nameAndValue) == 1 { 235 panic(fmt.Errorf("missing size value")) 236 } 237 length, err := strconv.ParseUint(nameAndValue[1], 10, 64) 238 if err != nil { 239 panic(fmt.Errorf("invalid size value: %s", err)) 240 } 241 ct.Length = length 242 case "decimal": 243 if len(nameAndValue) == 1 { 244 panic(fmt.Errorf("missing size value")) 245 } 246 decimal, err := strconv.ParseUint(nameAndValue[1], 10, 64) 247 if err != nil { 248 panic(fmt.Errorf("invalid decimal value: %s", err)) 249 } 250 ct.Decimal = decimal 251 case "default": 252 if len(nameAndValue) == 1 { 253 panic(fmt.Errorf("missing default value")) 254 } 255 ct.Default = &nameAndValue[1] 256 } 257 } 258 } 259 260 return ct 261 } 262 263 type ColumnType struct { 264 Type reflect.Type 265 GetDataType func(engine string) string 266 267 Length uint64 268 Decimal uint64 269 270 Default *string 271 272 Null bool 273 AutoIncrement bool 274 275 Comment string 276 277 DeprecatedActions *DeprecatedActions 278 } 279 280 type DeprecatedActions struct { 281 RenameTo string `name:"rename"` 282 }