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  }