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 }