Update sqlbuilder
This commit is contained in:
parent
8b567b49d0
commit
23457d28ce
2
api.go
2
api.go
@ -10,7 +10,7 @@ func (s *DB) Where(query interface{}, args ...interface{}) *DB {
|
|||||||
// Not add NOT condition
|
// Not add NOT condition
|
||||||
func (s *DB) Not(query interface{}, args ...interface{}) *DB {
|
func (s *DB) Not(query interface{}, args ...interface{}) *DB {
|
||||||
tx := s.init()
|
tx := s.init()
|
||||||
tx.Statement.AddConditions(Not(tx.Statement.BuildCondition(query, args...)))
|
tx.Statement.AddConditions(Not([]ConditionInterface{tx.Statement.BuildCondition(query, args...)}))
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,4 +6,6 @@ type Dialect interface {
|
|||||||
Query(*DB) error
|
Query(*DB) error
|
||||||
Update(*DB) error
|
Update(*DB) error
|
||||||
Delete(*DB) error
|
Delete(*DB) error
|
||||||
|
|
||||||
|
Quote(string) string
|
||||||
}
|
}
|
||||||
|
@ -1,63 +1,112 @@
|
|||||||
package sqlbuilder
|
package sqlbuilder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/jinzhu/gorm/model"
|
|
||||||
"github.com/jinzhu/gorm/schema"
|
|
||||||
"github.com/jinzhu/inflection"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetTable get table name for current db operation
|
func buildCondition(tx *gorm.DB, c gorm.ConditionInterface, s *bytes.Buffer) []interface{} {
|
||||||
func GetTable(tx *gorm.DB) chan string {
|
args := []interface{}{}
|
||||||
tableChan := make(chan string)
|
|
||||||
|
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() {
|
go func() {
|
||||||
var tableName string
|
s := bytes.NewBufferString("")
|
||||||
if name, ok := tx.Statement.Table.(string); ok {
|
args := []interface{}{}
|
||||||
tableName = name
|
|
||||||
} else {
|
|
||||||
for _, v := range []interface{}{tx.Statement.Table, tx.Statement.Dest} {
|
|
||||||
if v != nil {
|
|
||||||
if t, ok := v.(tabler); ok {
|
|
||||||
tableName = t.TableName()
|
|
||||||
} else if t, ok := v.(dbTabler); ok {
|
|
||||||
tableName = t.TableName(tx)
|
|
||||||
} else if s := schema.Parse(v); s != nil {
|
|
||||||
if s.TableName != "" {
|
|
||||||
tableName = s.TableName
|
|
||||||
} else {
|
|
||||||
tableName = schema.ToDBName(s.ModelType.Name())
|
|
||||||
if !tx.Config.SingularTable {
|
|
||||||
tableName = inflection.Plural(tableName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tableName != "" {
|
for i, c := range tx.Statement.Conditions {
|
||||||
break
|
if i > 0 {
|
||||||
}
|
s.WriteString(" AND ")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
args = append(args, buildCondition(tx, c, s)...)
|
||||||
|
|
||||||
if tableName != "" {
|
|
||||||
if model.DefaultTableNameHandler != nil {
|
|
||||||
tableChan <- model.DefaultTableNameHandler(tx, tableName)
|
|
||||||
} else {
|
|
||||||
tableChan <- tableName
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tx.AddError(ErrInvalidTable)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
return queryChan
|
||||||
return tableChan
|
|
||||||
}
|
|
||||||
|
|
||||||
type tabler interface {
|
|
||||||
TableName() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type dbTabler interface {
|
|
||||||
TableName(*gorm.DB) string
|
|
||||||
}
|
}
|
||||||
|
63
dialects/common/sqlbuilder/table.go
Normal file
63
dialects/common/sqlbuilder/table.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package sqlbuilder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
"github.com/jinzhu/gorm/model"
|
||||||
|
"github.com/jinzhu/gorm/schema"
|
||||||
|
"github.com/jinzhu/inflection"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetTable get table name for current db operation
|
||||||
|
func GetTable(tx *gorm.DB) chan string {
|
||||||
|
tableChan := make(chan string)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
var tableName string
|
||||||
|
if name, ok := tx.Statement.Table.(string); ok {
|
||||||
|
tableName = name
|
||||||
|
} else {
|
||||||
|
for _, v := range []interface{}{tx.Statement.Table, tx.Statement.Dest} {
|
||||||
|
if v != nil {
|
||||||
|
if t, ok := v.(tabler); ok {
|
||||||
|
tableName = t.TableName()
|
||||||
|
} else if t, ok := v.(dbTabler); ok {
|
||||||
|
tableName = t.TableName(tx)
|
||||||
|
} else if s := schema.Parse(v); s != nil {
|
||||||
|
if s.TableName != "" {
|
||||||
|
tableName = s.TableName
|
||||||
|
} else {
|
||||||
|
tableName = schema.ToDBName(s.ModelType.Name())
|
||||||
|
if !tx.Config.SingularTable {
|
||||||
|
tableName = inflection.Plural(tableName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tableName != "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tableName != "" {
|
||||||
|
if model.DefaultTableNameHandler != nil {
|
||||||
|
tableChan <- model.DefaultTableNameHandler(tx, tableName)
|
||||||
|
} else {
|
||||||
|
tableChan <- tableName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tx.AddError(ErrInvalidTable)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return tableChan
|
||||||
|
}
|
||||||
|
|
||||||
|
type tabler interface {
|
||||||
|
TableName() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type dbTabler interface {
|
||||||
|
TableName(*gorm.DB) string
|
||||||
|
}
|
@ -6,7 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/jinzhu/gorm/dialects/common/destination"
|
"github.com/jinzhu/gorm/dialects/common/sqlbuilder"
|
||||||
|
"github.com/jinzhu/gorm/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dialect Sqlite3 Dialect for GORM
|
// Dialect Sqlite3 Dialect for GORM
|
||||||
@ -23,9 +24,9 @@ func (dialect Dialect) Quote(name string) string {
|
|||||||
func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
|
func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
|
||||||
var (
|
var (
|
||||||
args []interface{}
|
args []interface{}
|
||||||
assignmentsChan = destination.GetAssignments(tx)
|
assignmentsChan = sqlbuilder.GetAssignmentFields(tx)
|
||||||
tableNameChan = destination.GetTable(tx)
|
tableNameChan = sqlbuilder.GetTable(tx)
|
||||||
primaryFields []*destination.Field
|
primaryFields []*model.Field
|
||||||
)
|
)
|
||||||
|
|
||||||
s := bytes.NewBufferString("INSERT INTO ")
|
s := bytes.NewBufferString("INSERT INTO ")
|
||||||
@ -41,7 +42,7 @@ func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
|
|||||||
valueBuffer := bytes.NewBufferString("VALUES ")
|
valueBuffer := bytes.NewBufferString("VALUES ")
|
||||||
|
|
||||||
for idx, fields := range assignments {
|
for idx, fields := range assignments {
|
||||||
var primaryField *destination.Field
|
var primaryField *model.Field
|
||||||
if idx != 0 {
|
if idx != 0 {
|
||||||
valueBuffer.WriteString(",")
|
valueBuffer.WriteString(",")
|
||||||
}
|
}
|
||||||
|
@ -105,8 +105,8 @@ func (stmt *Statement) AddConditions(conds ...ConditionInterface) {
|
|||||||
|
|
||||||
// Raw raw sql
|
// Raw raw sql
|
||||||
type Raw struct {
|
type Raw struct {
|
||||||
Value string
|
SQL string
|
||||||
Args []interface{} // TODO NamedArg
|
Args []interface{} // TODO NamedArg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eq equal to
|
// Eq equal to
|
||||||
@ -153,7 +153,7 @@ type Lte struct {
|
|||||||
type And []ConditionInterface
|
type And []ConditionInterface
|
||||||
|
|
||||||
// Not TRUE if condition is false
|
// Not TRUE if condition is false
|
||||||
type Not ConditionInterface
|
type Not []ConditionInterface
|
||||||
|
|
||||||
// Or TRUE if any of the conditions is TRUE
|
// Or TRUE if any of the conditions is TRUE
|
||||||
type Or []ConditionInterface
|
type Or []ConditionInterface
|
||||||
|
Loading…
x
Reference in New Issue
Block a user