You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
3.5 KiB
178 lines
3.5 KiB
package db
|
|
|
|
import (
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
type Expr struct {
|
|
clauses []clause.Expression
|
|
}
|
|
|
|
func NewExpr() *Expr {
|
|
return &Expr{}
|
|
}
|
|
|
|
func (e *Expr) add(expr clause.Expression) *Expr {
|
|
e.clauses = append(e.clauses, expr)
|
|
return e
|
|
}
|
|
|
|
func (e *Expr) Eq(col string, val any) *Expr {
|
|
return e.add(clause.Eq{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Neq(col string, val any) *Expr {
|
|
return e.add(clause.Neq{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Lt(col string, val any) *Expr {
|
|
return e.add(clause.Lt{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Lte(col string, val any) *Expr {
|
|
return e.add(clause.Lte{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Gt(col string, val any) *Expr {
|
|
return e.add(clause.Gt{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Gte(col string, val any) *Expr {
|
|
return e.add(clause.Gte{Column: col, Value: val})
|
|
}
|
|
|
|
func (e *Expr) Between(col string, less, more any) *Expr {
|
|
return e.add(between{col, less, more})
|
|
}
|
|
|
|
func (e *Expr) NotBetween(col string, less, more any) *Expr {
|
|
return e.add(clause.Not(between{col, less, more}))
|
|
}
|
|
|
|
func (e *Expr) IsNull(col string) *Expr {
|
|
return e.add(null{col})
|
|
}
|
|
|
|
func (e *Expr) NotNull(col string) *Expr {
|
|
return e.add(clause.Not(null{col}))
|
|
}
|
|
|
|
func (e *Expr) Like(col, tpl string) *Expr {
|
|
return e.add(clause.Like{Column: col, Value: tpl})
|
|
}
|
|
|
|
func (e *Expr) NotLike(col, tpl string) *Expr {
|
|
return e.add(clause.Not(clause.Like{Column: col, Value: tpl}))
|
|
}
|
|
|
|
func (e *Expr) In(col string, values ...any) *Expr {
|
|
return e.add(clause.IN{Column: col, Values: values})
|
|
}
|
|
|
|
func (e *Expr) NotIn(col string, values ...any) *Expr {
|
|
return e.add(clause.Not(clause.IN{Column: col, Values: values}))
|
|
}
|
|
|
|
func (e *Expr) When(condition bool, then func(ex *Expr), elses ...func(ex *Expr)) *Expr {
|
|
if condition {
|
|
then(e)
|
|
} else {
|
|
for _, els := range elses {
|
|
els(e)
|
|
}
|
|
}
|
|
return e
|
|
}
|
|
|
|
func (e *Expr) Or(or func(ex *Expr)) *Expr {
|
|
other := &Expr{}
|
|
or(other)
|
|
if len(other.clauses) == 0 {
|
|
return e
|
|
}
|
|
if len(e.clauses) == 0 {
|
|
e.clauses = other.clauses[:]
|
|
return e
|
|
}
|
|
e.clauses = []clause.Expression{
|
|
clause.Or(
|
|
clause.And(e.clauses...),
|
|
clause.And(other.clauses...),
|
|
),
|
|
}
|
|
return e
|
|
}
|
|
|
|
func (e *Expr) And(and func(ex *Expr)) *Expr {
|
|
other := &Expr{}
|
|
and(other)
|
|
if len(other.clauses) == 0 {
|
|
return e
|
|
}
|
|
if len(e.clauses) == 0 {
|
|
e.clauses = other.clauses[:]
|
|
return e
|
|
}
|
|
e.clauses = []clause.Expression{
|
|
clause.And(
|
|
clause.And(e.clauses...),
|
|
clause.And(other.clauses...),
|
|
),
|
|
}
|
|
return e
|
|
}
|
|
|
|
func (e *Expr) Not(not func(ex *Expr)) *Expr {
|
|
other := &Expr{}
|
|
not(other)
|
|
if len(other.clauses) == 0 {
|
|
return e
|
|
}
|
|
return e.add(clause.Not(other.clauses...))
|
|
}
|
|
|
|
func (e *Expr) Scopes(tx *gorm.DB) *gorm.DB {
|
|
if e.clauses != nil {
|
|
for _, express := range e.clauses {
|
|
tx = tx.Where(express)
|
|
}
|
|
}
|
|
return tx
|
|
}
|
|
|
|
type null struct {
|
|
Column any
|
|
}
|
|
|
|
func (n null) Build(builder clause.Builder) {
|
|
builder.WriteQuoted(n.Column)
|
|
builder.WriteString(" IS NULL")
|
|
}
|
|
|
|
func (n null) NegationBuild(builder clause.Builder) {
|
|
builder.WriteQuoted(n.Column)
|
|
builder.WriteString(" IS NOT NULL")
|
|
}
|
|
|
|
type between struct {
|
|
Column any
|
|
Less any
|
|
More any
|
|
}
|
|
|
|
func (b between) Build(builder clause.Builder) {
|
|
b.build(builder, " BETWEEN ")
|
|
}
|
|
|
|
func (b between) NegationBuild(builder clause.Builder) {
|
|
b.build(builder, " NOT BETWEEN ")
|
|
}
|
|
|
|
func (b between) build(builder clause.Builder, op string) {
|
|
builder.WriteQuoted(b.Column)
|
|
builder.WriteString(op)
|
|
builder.AddVar(builder, b.Less)
|
|
builder.WriteString(" And ")
|
|
builder.AddVar(builder, b.More)
|
|
}
|
|
|