github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/sqlx/builder/obj_column.go (about) 1 package builder 2 3 import ( 4 "container/list" 5 "fmt" 6 7 "github.com/sirupsen/logrus" 8 9 "github.com/johnnyeven/libtools/sqlx/data_type" 10 ) 11 12 func Col(table *Table, columnName string) *Column { 13 return &Column{ 14 Table: table, 15 Name: columnName, 16 } 17 } 18 19 func Cols(t *Table, columnNames ...string) (cols Columns) { 20 for _, columnName := range columnNames { 21 cols.Add(Col(t, columnName)) 22 } 23 return cols 24 } 25 26 type Columns struct { 27 columns map[string]*list.Element 28 fields map[string]*list.Element 29 l *list.List 30 autoIncrement *Column 31 } 32 33 func (cols *Columns) AutoIncrement() (col *Column) { 34 return cols.autoIncrement 35 } 36 37 func (cols *Columns) Clone() *Columns { 38 c := &Columns{} 39 cols.Range(func(col *Column, idx int) { 40 c.Add(col) 41 }) 42 return c 43 } 44 45 func (cols *Columns) Len() int { 46 if cols.l == nil { 47 return 0 48 } 49 return cols.l.Len() 50 } 51 52 func (cols *Columns) IsEmpty() bool { 53 return cols.l == nil || cols.l.Len() == 0 54 } 55 56 func (cols *Columns) Fields(fieldNames ...string) (columns *Columns) { 57 if len(fieldNames) == 0 { 58 return cols.Clone() 59 } 60 columns = &Columns{} 61 for _, fieldName := range fieldNames { 62 if col := cols.F(fieldName); col != nil { 63 columns.Add(col) 64 } 65 } 66 return 67 } 68 69 func (cols *Columns) FieldNames() []string { 70 fieldNames := make([]string, 0) 71 cols.Range(func(col *Column, idx int) { 72 fieldNames = append(fieldNames, col.FieldName) 73 }) 74 return fieldNames 75 } 76 77 func (cols *Columns) F(fileName string) (col *Column) { 78 if cols.fields != nil { 79 if c, ok := cols.fields[fileName]; ok { 80 return c.Value.(*Column) 81 } 82 } 83 return nil 84 } 85 86 func (cols *Columns) List() (l []*Column) { 87 if cols.columns != nil { 88 cols.Range(func(col *Column, idx int) { 89 l = append(l, col) 90 }) 91 } 92 return 93 } 94 95 func (cols *Columns) Cols(colNames ...string) (columns *Columns) { 96 if len(colNames) == 0 { 97 return cols.Clone() 98 } 99 columns = &Columns{} 100 for _, colName := range colNames { 101 if col := cols.Col(colName); col != nil { 102 columns.Add(col) 103 } 104 } 105 return 106 } 107 108 func (cols *Columns) Col(columnName string) (col *Column) { 109 if cols.columns != nil { 110 if c, ok := cols.columns[columnName]; ok { 111 return c.Value.(*Column) 112 } 113 } 114 return nil 115 } 116 117 func (cols *Columns) Add(columns ...*Column) { 118 if cols.columns == nil { 119 cols.columns = map[string]*list.Element{} 120 cols.fields = map[string]*list.Element{} 121 cols.l = list.New() 122 } 123 for _, col := range columns { 124 if col != nil { 125 if col.AutoIncrement { 126 if cols.autoIncrement != nil { 127 panic(fmt.Errorf("AutoIncrement field can only have one, now %s, but %s want to replace", cols.autoIncrement.Name, col.Name)) 128 } 129 cols.autoIncrement = col 130 } 131 e := cols.l.PushBack(col) 132 cols.columns[col.Name] = e 133 cols.fields[col.FieldName] = e 134 } 135 } 136 } 137 138 func (cols *Columns) Remove(name string) { 139 if cols.columns != nil { 140 if e, exists := cols.columns[name]; exists { 141 cols.l.Remove(e) 142 delete(cols.columns, name) 143 } 144 } 145 } 146 147 func (cols *Columns) Range(cb func(col *Column, idx int)) { 148 if cols.l != nil { 149 i := 0 150 for e := cols.l.Front(); e != nil; e = e.Next() { 151 cb(e.Value.(*Column), i) 152 i++ 153 } 154 } 155 } 156 157 func (cols Columns) Wrap() (e *Expression) { 158 e = cols.Expr() 159 if e.Query != "" { 160 e.Query = "(" + e.Query + ")" 161 } 162 return e 163 } 164 165 func (cols Columns) Expr() (e *Expression) { 166 query := "" 167 168 cols.Range(func(col *Column, idx int) { 169 if idx == 0 { 170 query = query + col.String() 171 } else { 172 query = query + "," + col.String() 173 } 174 }) 175 176 return Expr(query) 177 } 178 179 func (cols Columns) Diff(targetCols Columns) columnsDiffResult { 180 r := columnsDiffResult{} 181 182 cs := cols.Clone() 183 184 targetCols.Range(func(col *Column, idx int) { 185 if currentCol := cs.Col(col.Name); currentCol != nil { 186 sqlCurrent := currentCol.ColumnType.DeAlias().String() 187 sqlNext := col.ColumnType.DeAlias().String() 188 if sqlCurrent != sqlNext { 189 logrus.Warnf("data type of %s.%s current:`%s`, will be `%s`", col.Table.Name, col.Name, sqlCurrent, sqlNext) 190 r.colsForUpdate.Add(col) 191 } 192 } else { 193 r.colsForAdd.Add(col) 194 } 195 cs.Remove(col.Name) 196 }) 197 198 cs.Range(func(col *Column, idx int) { 199 r.colsForDelete.Add(col) 200 }) 201 202 return r 203 } 204 205 type columnsDiffResult struct { 206 colsForAdd Columns 207 colsForUpdate Columns 208 colsForDelete Columns 209 } 210 211 func (r columnsDiffResult) IsChanged() bool { 212 return !r.colsForAdd.IsEmpty() || !r.colsForUpdate.IsEmpty() || !r.colsForDelete.IsEmpty() 213 } 214 215 type Column struct { 216 Table *Table 217 Name string 218 FieldName string 219 data_type.ColumnType 220 } 221 222 func (c Column) Field(fieldName string) *Column { 223 c.FieldName = fieldName 224 return &c 225 } 226 227 func (c Column) Type(tpe string) *Column { 228 columnType, err := data_type.ParseColumnType(tpe) 229 if err != nil { 230 panic(fmt.Errorf("%s %s", c.Name, err)) 231 } 232 c.ColumnType = *columnType 233 return &c 234 } 235 236 func (c Column) Enum(enumType string, enums map[int][]string) *Column { 237 c.ColumnType.EnumType = enumType 238 c.ColumnType.Enums = enums 239 return &c 240 } 241 242 func (c *Column) IsValidDef() bool { 243 return c.ColumnType.DataType != "" 244 } 245 246 func (c Column) Def() *Expression { 247 return Expr(c.String() + " " + c.ColumnType.String()) 248 } 249 250 func (c *Column) Add() *Expression { 251 return Expr("ADD COLUMN").ConcatBy(" ", c.Def()) 252 } 253 254 func (c *Column) Modify() *Expression { 255 return Expr("MODIFY COLUMN").ConcatBy(" ", c.Def()) 256 } 257 258 func (c *Column) Drop() *Expression { 259 return Expr(fmt.Sprintf("DROP COLUMN %s", c.String())) 260 } 261 262 func (c *Column) String() string { 263 return quote(c.Name) 264 } 265 266 func (c *Column) Expr() *Expression { 267 return Expr(c.String()) 268 } 269 270 func (c *Column) Incr(d int) *Expression { 271 return Expr(fmt.Sprintf("%s + ?", c), d) 272 } 273 274 func (c *Column) Desc(d int) *Expression { 275 return Expr(fmt.Sprintf("%s - ?", c), d) 276 } 277 278 func (c *Column) By(v interface{}) *Assignment { 279 if e, ok := v.(*Expression); ok { 280 return (*Assignment)(Expr(fmt.Sprintf("%s = %s", c, e.Query), e.Args...)) 281 } 282 return (*Assignment)(Expr(fmt.Sprintf("%s = ?", c), v)) 283 } 284 285 func (c *Column) Like(v string) *Condition { 286 return (*Condition)(Expr(fmt.Sprintf("%s LIKE ?", c), "%"+v+"%")) 287 } 288 289 func (c *Column) LeftLike(v string) *Condition { 290 return (*Condition)(Expr(fmt.Sprintf("%s LIKE ?", c), "%"+v)) 291 } 292 293 func (c *Column) RightLike(v string) *Condition { 294 return (*Condition)(Expr(fmt.Sprintf("%s LIKE ?", c), v+"%")) 295 } 296 297 func (c *Column) NotLike(v string) *Condition { 298 return (*Condition)(Expr(fmt.Sprintf("%s NOT LIKE ?", c), "%"+v+"%")) 299 } 300 301 func (c *Column) IsNull() *Condition { 302 return (*Condition)(Expr(fmt.Sprintf("%s IS NULL", c))) 303 } 304 305 func (c *Column) IsNotNull() *Condition { 306 return (*Condition)(Expr(fmt.Sprintf("%s IS NOT NULL", c))) 307 } 308 309 func (c *Column) Between(leftValue interface{}, rightValue interface{}) *Condition { 310 return (*Condition)(Expr(fmt.Sprintf("%s BETWEEN ? AND ?", c), leftValue, rightValue)) 311 } 312 313 func (c *Column) NotBetween(leftValue interface{}, rightValue interface{}) *Condition { 314 return (*Condition)(Expr(fmt.Sprintf("%s NOT BETWEEN ? AND ?", c), leftValue, rightValue)) 315 } 316 317 func (c *Column) In(args ...interface{}) *Condition { 318 length := len(args) 319 if length == 0 { 320 return nil 321 } 322 if length == 1 { 323 expr := ExprFrom(args[0]) 324 if expr != nil { 325 return (*Condition)(Expr(fmt.Sprintf("%s IN (%s)", c, expr.Query), expr.Args...)) 326 } 327 } 328 return (*Condition)(Expr(fmt.Sprintf("%s IN (%s)", c, HolderRepeat(length)), args...)) 329 } 330 331 func (c *Column) NotIn(args ...interface{}) *Condition { 332 length := len(args) 333 if length == 0 { 334 return nil 335 } 336 if length == 1 { 337 expr := ExprFrom(args[0]) 338 if expr != nil { 339 return (*Condition)(Expr(fmt.Sprintf("%s NOT IN (%s)", c, expr.Query), expr.Args...)) 340 } 341 } 342 return (*Condition)(Expr(fmt.Sprintf("%s NOT IN (%s)", c, HolderRepeat(length)), args...)) 343 } 344 345 func (c *Column) Eq(value interface{}) *Condition { 346 return (*Condition)(Expr(fmt.Sprintf("%s = ?", c), value)) 347 } 348 349 func (c *Column) Neq(v interface{}) *Condition { 350 return (*Condition)(Expr(fmt.Sprintf("%s <> ?", c), v)) 351 } 352 353 func (c *Column) Gt(v interface{}) *Condition { 354 return (*Condition)(Expr(fmt.Sprintf("%s > ?", c), v)) 355 } 356 357 func (c *Column) Gte(v interface{}) *Condition { 358 return (*Condition)(Expr(fmt.Sprintf("%s >= ?", c), v)) 359 } 360 361 func (c *Column) Lt(v interface{}) *Condition { 362 return (*Condition)(Expr(fmt.Sprintf("%s < ?", c), v)) 363 } 364 365 func (c *Column) Lte(v interface{}) *Condition { 366 return (*Condition)(Expr(fmt.Sprintf("%s <= ?", c), v)) 367 }