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  }