github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/field/expr.go (about)

     1  package field
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"gorm.io/gorm"
     9  	"gorm.io/gorm/clause"
    10  )
    11  
    12  var _ Expr = new(Field)
    13  
    14  // AssignExpr assign expression
    15  type AssignExpr interface {
    16  	Expr
    17  
    18  	AssignExpr() expression
    19  }
    20  
    21  // Expr a query expression about field
    22  type Expr interface {
    23  	// Clause Expression interface
    24  	Build(clause.Builder)
    25  
    26  	As(alias string) Expr
    27  	ColumnName() sql
    28  	BuildColumn(*gorm.Statement, ...BuildOpt) sql
    29  	BuildWithArgs(*gorm.Statement) (query sql, args []interface{})
    30  	RawExpr() expression
    31  
    32  	// col operate expression
    33  	AddCol(col Expr) Expr
    34  	SubCol(col Expr) Expr
    35  	MulCol(col Expr) Expr
    36  	DivCol(col Expr) Expr
    37  	ConcatCol(cols ...Expr) Expr
    38  
    39  	// implement Condition
    40  	BeCond() interface{}
    41  	CondError() error
    42  
    43  	expression() clause.Expression
    44  }
    45  
    46  // OrderExpr order expression
    47  // used in Order()
    48  type OrderExpr interface {
    49  	Expr
    50  	Desc() Expr
    51  }
    52  
    53  type expression interface{}
    54  
    55  type sql string
    56  
    57  func (e sql) String() string { return string(e) }
    58  
    59  type expr struct {
    60  	col clause.Column
    61  
    62  	e         clause.Expression
    63  	buildOpts []BuildOpt
    64  }
    65  
    66  func (e expr) BeCond() interface{} { return e.expression() }
    67  func (expr) CondError() error      { return nil }
    68  
    69  func (e expr) AssignExpr() expression {
    70  	return e.expression()
    71  }
    72  
    73  func (e expr) expression() clause.Expression {
    74  	if e.e == nil {
    75  		return clause.NamedExpr{SQL: "?", Vars: []interface{}{e.col}}
    76  	}
    77  	return e.e
    78  }
    79  
    80  func (e expr) ColumnName() sql { return sql(e.col.Name) }
    81  
    82  // BuildOpt build option
    83  type BuildOpt uint
    84  
    85  const (
    86  	// WithTable build column with table
    87  	WithTable BuildOpt = iota
    88  
    89  	// WithAll build column with table and alias
    90  	WithAll
    91  
    92  	// WithoutQuote build column without quote
    93  	WithoutQuote
    94  )
    95  
    96  func (e expr) BuildColumn(stmt *gorm.Statement, opts ...BuildOpt) sql {
    97  	col := clause.Column{Name: e.col.Name}
    98  	for _, opt := range append(e.buildOpts, opts...) {
    99  		switch opt {
   100  		case WithTable:
   101  			col.Table = e.col.Table
   102  		case WithAll:
   103  			col.Table = e.col.Table
   104  			col.Alias = e.col.Alias
   105  		case WithoutQuote:
   106  			col.Raw = true
   107  		}
   108  	}
   109  	if col.Name == "*" {
   110  		if col.Table != "" {
   111  			return sql(stmt.Quote(col.Table)) + ".*"
   112  		}
   113  		return "*"
   114  	}
   115  	return sql(stmt.Quote(col))
   116  }
   117  
   118  func (e expr) Build(builder clause.Builder) {
   119  	if e.e == nil {
   120  		if stmt, ok := builder.(*gorm.Statement); ok {
   121  			builder.WriteString(string(e.BuildColumn(stmt, WithAll)))
   122  			return
   123  		}
   124  	}
   125  
   126  	e.e.Build(builder)
   127  }
   128  
   129  func (e expr) BuildWithArgs(stmt *gorm.Statement) (sql, []interface{}) {
   130  	if e.e == nil {
   131  		return sql(e.BuildColumn(stmt, WithAll)), nil
   132  	}
   133  	newStmt := &gorm.Statement{DB: stmt.DB, Table: stmt.Table, Schema: stmt.Schema}
   134  	e.e.Build(newStmt)
   135  	return sql(newStmt.SQL.String()), newStmt.Vars
   136  }
   137  
   138  func (e expr) RawExpr() expression {
   139  	if e.e == nil {
   140  		return e.col
   141  	}
   142  	return e.e
   143  }
   144  
   145  func (e expr) setE(expression clause.Expression) expr {
   146  	e.e = expression
   147  	return e
   148  }
   149  
   150  func (e expr) appendBuildOpts(opts ...BuildOpt) expr {
   151  	e.buildOpts = append(e.buildOpts, opts...)
   152  	return e
   153  }
   154  
   155  // ======================== basic function ========================
   156  func (e expr) WithTable(table string) Expr {
   157  	e.col.Table = table
   158  	return e
   159  }
   160  
   161  func (e expr) IsNull() Expr {
   162  	return e.setE(clause.Expr{SQL: "? IS NULL", Vars: []interface{}{e.RawExpr()}})
   163  }
   164  
   165  func (e expr) IsNotNull() Expr {
   166  	return e.setE(clause.Expr{SQL: "? IS NOT NULL", Vars: []interface{}{e.RawExpr()}})
   167  }
   168  
   169  func (e expr) Count() Int {
   170  	return Int{e.setE(clause.Expr{SQL: "COUNT(?)", Vars: []interface{}{e.RawExpr()}})}
   171  }
   172  
   173  func (e expr) Distinct() Int {
   174  	return Int{e.setE(clause.Expr{SQL: "DISTINCT ?", Vars: []interface{}{e.RawExpr()}})}
   175  }
   176  
   177  func (e expr) Length() Int {
   178  	return Int{e.setE(clause.Expr{SQL: "LENGTH(?)", Vars: []interface{}{e.RawExpr()}})}
   179  }
   180  
   181  func (e expr) Max() Float64 {
   182  	return Float64{e.setE(clause.Expr{SQL: "MAX(?)", Vars: []interface{}{e.RawExpr()}})}
   183  }
   184  
   185  func (e expr) Min() Float64 {
   186  	return Float64{e.setE(clause.Expr{SQL: "MIN(?)", Vars: []interface{}{e.RawExpr()}})}
   187  }
   188  
   189  func (e expr) Avg() Float64 {
   190  	return Float64{e.setE(clause.Expr{SQL: "AVG(?)", Vars: []interface{}{e.RawExpr()}})}
   191  }
   192  
   193  func (e expr) Null() AssignExpr {
   194  	return e.setE(clause.Eq{Column: e.col.Name, Value: nil})
   195  }
   196  
   197  func (e expr) GroupConcat() Expr {
   198  	return e.setE(clause.Expr{SQL: "GROUP_CONCAT(?)", Vars: []interface{}{e.RawExpr()}})
   199  }
   200  
   201  // ======================== comparison between columns ========================
   202  func (e expr) EqCol(col Expr) Expr {
   203  	return e.setE(clause.Expr{SQL: "? = ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   204  }
   205  
   206  func (e expr) NeqCol(col Expr) Expr {
   207  	return e.setE(clause.Expr{SQL: "? <> ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   208  }
   209  
   210  func (e expr) GtCol(col Expr) Expr {
   211  	return e.setE(clause.Expr{SQL: "? > ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   212  }
   213  
   214  func (e expr) GteCol(col Expr) Expr {
   215  	return e.setE(clause.Expr{SQL: "? >= ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   216  }
   217  
   218  func (e expr) LtCol(col Expr) Expr {
   219  	return e.setE(clause.Expr{SQL: "? < ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   220  }
   221  
   222  func (e expr) LteCol(col Expr) Expr {
   223  	return e.setE(clause.Expr{SQL: "? <= ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})
   224  }
   225  
   226  func (e expr) SetCol(col Expr) AssignExpr {
   227  	return e.setE(clause.Eq{Column: e.col.Name, Value: col.RawExpr()})
   228  }
   229  
   230  // ======================== operate columns ========================
   231  func (e expr) AddCol(col Expr) Expr {
   232  	return Field{e.setE(clause.Expr{SQL: "? + ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})}
   233  }
   234  
   235  func (e expr) SubCol(col Expr) Expr {
   236  	return Field{e.setE(clause.Expr{SQL: "? - ?", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})}
   237  }
   238  
   239  func (e expr) MulCol(col Expr) Expr {
   240  	return Field{e.setE(clause.Expr{SQL: "(?) * (?)", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})}
   241  }
   242  
   243  func (e expr) DivCol(col Expr) Expr {
   244  	return Field{e.setE(clause.Expr{SQL: "(?) / (?)", Vars: []interface{}{e.RawExpr(), col.RawExpr()}})}
   245  }
   246  
   247  func (e expr) ConcatCol(cols ...Expr) Expr {
   248  	placeholders := []string{"?"}
   249  	vars := []interface{}{e.RawExpr()}
   250  	for _, col := range cols {
   251  		placeholders = append(placeholders, "?")
   252  		vars = append(vars, col.RawExpr())
   253  	}
   254  	return Field{e.setE(clause.Expr{
   255  		SQL:  fmt.Sprintf("Concat(%s)", strings.Join(placeholders, ",")),
   256  		Vars: vars,
   257  	})}
   258  }
   259  
   260  // ======================== keyword ========================
   261  func (e expr) As(alias string) Expr {
   262  	if e.e != nil {
   263  		return e.setE(clause.Expr{SQL: "? AS ?", Vars: []interface{}{e.e, clause.Column{Name: alias}}})
   264  	}
   265  	e.col.Alias = alias
   266  	return e
   267  }
   268  
   269  func (e expr) Desc() Expr {
   270  	return e.setE(clause.Expr{SQL: "? DESC", Vars: []interface{}{e.RawExpr()}})
   271  }
   272  
   273  // ======================== general experssion ========================
   274  func (e expr) value(value interface{}) AssignExpr {
   275  	return e.setE(clause.Eq{Column: e.col.Name, Value: value})
   276  }
   277  
   278  func (e expr) between(values []interface{}) expr {
   279  	return e.setE(clause.Expr{SQL: "? BETWEEN ? AND ?", Vars: append([]interface{}{e.RawExpr()}, values...)})
   280  }
   281  
   282  func (e expr) add(value interface{}) expr {
   283  	switch v := value.(type) {
   284  	case time.Duration:
   285  		return e.setE(clause.Expr{SQL: "DATE_ADD(?, INTERVAL ? MICROSECOND)", Vars: []interface{}{e.RawExpr(), v.Microseconds()}})
   286  	default:
   287  		return e.setE(clause.Expr{SQL: "?+?", Vars: []interface{}{e.RawExpr(), value}})
   288  	}
   289  }
   290  
   291  func (e expr) sub(value interface{}) expr {
   292  	switch v := value.(type) {
   293  	case time.Duration:
   294  		return e.setE(clause.Expr{SQL: "DATE_SUB(?, INTERVAL ? MICROSECOND)", Vars: []interface{}{e.RawExpr(), v.Microseconds()}})
   295  	default:
   296  		return e.setE(clause.Expr{SQL: "?-?", Vars: []interface{}{e.RawExpr(), value}})
   297  	}
   298  }
   299  
   300  func (e expr) mul(value interface{}) expr {
   301  	if e.isPure() {
   302  		return e.setE(clause.Expr{SQL: "?*?", Vars: []interface{}{e.col, value}})
   303  	}
   304  	return e.setE(clause.Expr{SQL: "(?)*?", Vars: []interface{}{e.e, value}})
   305  }
   306  
   307  func (e expr) div(value interface{}) expr {
   308  	if e.isPure() {
   309  		return e.setE(clause.Expr{SQL: "?/?", Vars: []interface{}{e.col, value}})
   310  	}
   311  	return e.setE(clause.Expr{SQL: "(?)/?", Vars: []interface{}{e.e, value}})
   312  }
   313  
   314  func (e expr) mod(value interface{}) expr {
   315  	if e.isPure() {
   316  		return e.setE(clause.Expr{SQL: "?%?", Vars: []interface{}{e.col, value}})
   317  	}
   318  	return e.setE(clause.Expr{SQL: "(?)%?", Vars: []interface{}{e.e, value}})
   319  }
   320  
   321  func (e expr) floorDiv(value interface{}) expr {
   322  	if e.isPure() {
   323  		return e.setE(clause.Expr{SQL: "? DIV ?", Vars: []interface{}{e.col, value}})
   324  	}
   325  	return e.setE(clause.Expr{SQL: "(?) DIV ?", Vars: []interface{}{e.e, value}})
   326  }
   327  
   328  func (e expr) floor() expr {
   329  	return e.setE(clause.Expr{SQL: "FLOOR(?)", Vars: []interface{}{e.RawExpr()}})
   330  }
   331  
   332  func (e expr) rightShift(value interface{}) expr {
   333  	if e.isPure() {
   334  		return e.setE(clause.Expr{SQL: "?>>?", Vars: []interface{}{e.col, value}})
   335  	}
   336  	return e.setE(clause.Expr{SQL: "(?)>>?", Vars: []interface{}{e.e, value}})
   337  }
   338  
   339  func (e expr) leftShift(value interface{}) expr {
   340  	if e.isPure() {
   341  		return e.setE(clause.Expr{SQL: "?<<?", Vars: []interface{}{e.col, value}})
   342  	}
   343  	return e.setE(clause.Expr{SQL: "(?)<<?", Vars: []interface{}{e.e, value}})
   344  }
   345  
   346  func (e expr) bitXor(value interface{}) expr {
   347  	if e.isPure() {
   348  		return e.setE(clause.Expr{SQL: "?^?", Vars: []interface{}{e.col, value}})
   349  	}
   350  	return e.setE(clause.Expr{SQL: "(?)^?", Vars: []interface{}{e.e, value}})
   351  }
   352  
   353  func (e expr) bitAnd(value interface{}) expr {
   354  	if e.isPure() {
   355  		return e.setE(clause.Expr{SQL: "?&?", Vars: []interface{}{e.col, value}})
   356  	}
   357  	return e.setE(clause.Expr{SQL: "(?)&?", Vars: []interface{}{e.e, value}})
   358  }
   359  
   360  func (e expr) bitOr(value interface{}) expr {
   361  	if e.isPure() {
   362  		return e.setE(clause.Expr{SQL: "?|?", Vars: []interface{}{e.col, value}})
   363  	}
   364  	return e.setE(clause.Expr{SQL: "(?)|?", Vars: []interface{}{e.e, value}})
   365  }
   366  
   367  func (e expr) bitFlip() expr {
   368  	if e.isPure() {
   369  		return e.setE(clause.Expr{SQL: "~?", Vars: []interface{}{e.col}})
   370  	}
   371  	return e.setE(clause.Expr{SQL: "~(?)", Vars: []interface{}{e.RawExpr()}})
   372  }
   373  
   374  func (e expr) regexp(value interface{}) expr {
   375  	return e.setE(clause.Expr{SQL: "? REGEXP ?", Vars: []interface{}{e.RawExpr(), value}})
   376  }
   377  
   378  func (e expr) not() expr {
   379  	return e.setE(clause.Expr{SQL: "NOT ?", Vars: []interface{}{e.RawExpr()}})
   380  }
   381  
   382  func (e expr) is(value interface{}) expr {
   383  	return e.setE(clause.Eq{Column: e.RawExpr(), Value: value})
   384  }
   385  
   386  func (e expr) and(value interface{}) expr {
   387  	return e.setE(clause.Expr{SQL: "? AND ?", Vars: []interface{}{e.RawExpr(), value}})
   388  }
   389  
   390  func (e expr) or(value interface{}) expr {
   391  	return e.setE(clause.Expr{SQL: "? OR ?", Vars: []interface{}{e.RawExpr(), value}})
   392  }
   393  
   394  func (e expr) xor(value interface{}) expr {
   395  	return e.setE(clause.Expr{SQL: "? XOR ?", Vars: []interface{}{e.RawExpr(), value}})
   396  }
   397  
   398  func (e expr) isPure() bool {
   399  	return e.e == nil
   400  }
   401  
   402  func (e expr) ifNull(value interface{}) expr {
   403  	return e.setE(clause.Expr{SQL: "IFNULL(?,?)", Vars: []interface{}{e.RawExpr(), value}})
   404  }
   405  
   406  func (e expr) sum() expr {
   407  	return e.setE(clause.Expr{SQL: "SUM(?)", Vars: []interface{}{e.RawExpr()}})
   408  }