Add group builder
This commit is contained in:
parent
23457d28ce
commit
1f501c36d7
2
api.go
2
api.go
@ -40,7 +40,7 @@ func (s *DB) Joins(query string, args ...interface{}) *DB {
|
||||
// Group specify the group method on the find
|
||||
func (s *DB) Group(column string) *DB {
|
||||
tx := s.init()
|
||||
tx.Statement.GroupBy.GroupByColumns = append(tx.Statement.GroupBy.GroupByColumns, column)
|
||||
tx.Statement.GroupBy.Columns = append(tx.Statement.GroupBy.Columns, column)
|
||||
return tx
|
||||
}
|
||||
|
||||
|
110
dialects/common/sqlbuilder/conditions.go
Normal file
110
dialects/common/sqlbuilder/conditions.go
Normal file
@ -0,0 +1,110 @@
|
||||
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) chan *Builder {
|
||||
queryChan := make(chan *Builder)
|
||||
|
||||
go func() {
|
||||
builder := &Builder{}
|
||||
|
||||
for i, c := range tx.Statement.Conditions {
|
||||
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
|
||||
}
|
32
dialects/common/sqlbuilder/group.go
Normal file
32
dialects/common/sqlbuilder/group.go
Normal file
@ -0,0 +1,32 @@
|
||||
package sqlbuilder
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// BuildGroupCondition build group condition
|
||||
func BuildGroupCondition(tx *gorm.DB) chan *Builder {
|
||||
groupChan := make(chan *Builder)
|
||||
|
||||
go func() {
|
||||
builder := &Builder{}
|
||||
if groupBy := tx.Statement.GroupBy; len(groupBy.Columns) > 0 {
|
||||
builder.SQL.WriteString(strings.Join(tx.Statement.GroupBy.Columns, ", "))
|
||||
|
||||
if len(groupBy.Having) > 0 {
|
||||
builder.SQL.WriteString(" HAVING ")
|
||||
for i, having := range groupBy.Having {
|
||||
if i > 0 {
|
||||
builder.SQL.WriteString(" AND ")
|
||||
}
|
||||
buildCondition(tx, having, builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
groupChan <- builder
|
||||
}()
|
||||
|
||||
return groupChan
|
||||
}
|
@ -1,112 +1,9 @@
|
||||
package sqlbuilder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
import "bytes"
|
||||
|
||||
"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
|
||||
// Builder sql builder
|
||||
type Builder struct {
|
||||
SQL bytes.Buffer
|
||||
Args []interface{}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ type Join struct {
|
||||
|
||||
// GroupBy group by statement
|
||||
type GroupBy struct {
|
||||
GroupByColumns []string
|
||||
Having []ConditionInterface
|
||||
Columns []string
|
||||
Having []ConditionInterface
|
||||
}
|
||||
|
||||
// OrderCondition order condition, could be string or sql expr
|
||||
@ -84,7 +84,7 @@ func (stmt *Statement) Clone() *Statement {
|
||||
// BuildCondition build condition
|
||||
func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) ConditionInterface {
|
||||
if sql, ok := query.(string); ok {
|
||||
return Raw{Value: sql, Args: args}
|
||||
return Raw{SQL: sql, Args: args}
|
||||
}
|
||||
|
||||
andConds := And([]ConditionInterface{ConditionInterface(query)})
|
||||
|
Loading…
x
Reference in New Issue
Block a user