gorm/dialects/common/sqlbuilder/sqlbuilder.go
2018-03-01 01:12:29 +08:00

113 lines
2.5 KiB
Go

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