111 lines
2.8 KiB
Go
111 lines
2.8 KiB
Go
package sqlbuilder
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/jinzhu/gorm"
|
|
)
|
|
|
|
// ConditionInterface condition interface
|
|
type ConditionInterface interface {
|
|
ToSQL(*gorm.DB) (string, []interface{})
|
|
}
|
|
|
|
// BuildConditions build conditions
|
|
func BuildConditions(tx *gorm.DB, conds []gorm.ConditionInterface) chan *Builder {
|
|
queryChan := make(chan *Builder)
|
|
|
|
go func() {
|
|
builder := &Builder{}
|
|
|
|
for i, c := range conds {
|
|
if i > 0 {
|
|
builder.SQL.WriteString(" AND ")
|
|
}
|
|
buildCondition(tx, c, builder)
|
|
}
|
|
|
|
queryChan <- builder
|
|
}()
|
|
return queryChan
|
|
}
|
|
|
|
func buildCondition(tx *gorm.DB, c gorm.ConditionInterface, builder *Builder) {
|
|
switch cond := c.(type) {
|
|
case gorm.And:
|
|
builder.SQL.WriteString("(")
|
|
for i, v := range cond {
|
|
if i > 0 {
|
|
builder.SQL.WriteString(" AND ")
|
|
}
|
|
buildCondition(tx, v, builder)
|
|
}
|
|
builder.SQL.WriteString(")")
|
|
case gorm.Or:
|
|
builder.SQL.WriteString("(")
|
|
for i, v := range cond {
|
|
if i > 0 {
|
|
builder.SQL.WriteString(" OR ")
|
|
}
|
|
buildCondition(tx, v, builder)
|
|
}
|
|
builder.SQL.WriteString(")")
|
|
case gorm.Not:
|
|
builder.SQL.WriteString("NOT (")
|
|
for i, v := range cond {
|
|
if i > 0 {
|
|
builder.SQL.WriteString(" AND ")
|
|
}
|
|
buildCondition(tx, v, builder)
|
|
}
|
|
builder.SQL.WriteString(")")
|
|
case gorm.Raw:
|
|
builder.SQL.WriteString(cond.SQL)
|
|
builder.Args = append(builder.Args, cond.Args...)
|
|
case gorm.Eq:
|
|
if cond.Value == nil {
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" IS NULL")
|
|
} else {
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" = ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
}
|
|
case gorm.Neq:
|
|
if cond.Value == nil {
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" IS NOT NULL")
|
|
} else {
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" <> ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
}
|
|
case gorm.Gt:
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" > ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
case gorm.Gte:
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" >= ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
case gorm.Lt:
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" < ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
case gorm.Lte:
|
|
builder.SQL.WriteString(tx.Dialect().Quote(cond.Column))
|
|
builder.SQL.WriteString(" <= ?")
|
|
builder.Args = append(builder.Args, cond.Value)
|
|
default:
|
|
if sqlCond, ok := cond.(ConditionInterface); ok {
|
|
sql, as := sqlCond.ToSQL(tx)
|
|
builder.SQL.WriteString(sql)
|
|
builder.Args = append(builder.Args, as...)
|
|
} else {
|
|
tx.AddError(fmt.Errorf("unsupported condition: %#v", cond))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|