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
|
// Group specify the group method on the find
|
||||||
func (s *DB) Group(column string) *DB {
|
func (s *DB) Group(column string) *DB {
|
||||||
tx := s.init()
|
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
|
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
|
package sqlbuilder
|
||||||
|
|
||||||
import (
|
import "bytes"
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
// Builder sql builder
|
||||||
)
|
type Builder struct {
|
||||||
|
SQL bytes.Buffer
|
||||||
func buildCondition(tx *gorm.DB, c gorm.ConditionInterface, s *bytes.Buffer) []interface{} {
|
Args []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
|
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ type Join struct {
|
|||||||
|
|
||||||
// GroupBy group by statement
|
// GroupBy group by statement
|
||||||
type GroupBy struct {
|
type GroupBy struct {
|
||||||
GroupByColumns []string
|
Columns []string
|
||||||
Having []ConditionInterface
|
Having []ConditionInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ func (stmt *Statement) Clone() *Statement {
|
|||||||
// BuildCondition build condition
|
// BuildCondition build condition
|
||||||
func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) ConditionInterface {
|
func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) ConditionInterface {
|
||||||
if sql, ok := query.(string); ok {
|
if sql, ok := query.(string); ok {
|
||||||
return Raw{Value: sql, Args: args}
|
return Raw{SQL: sql, Args: args}
|
||||||
}
|
}
|
||||||
|
|
||||||
andConds := And([]ConditionInterface{ConditionInterface(query)})
|
andConds := And([]ConditionInterface{ConditionInterface(query)})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user