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
 | 
			
		||||
func (s *DB) Not(query interface{}, args ...interface{}) *DB {
 | 
			
		||||
	tx := s.init()
 | 
			
		||||
	tx.Statement.AddConditions(Not(tx.Statement.BuildCondition(query, args...)))
 | 
			
		||||
	tx.Statement.AddConditions(Not([]ConditionInterface{tx.Statement.BuildCondition(query, args...)}))
 | 
			
		||||
	return tx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,4 +6,6 @@ type Dialect interface {
 | 
			
		||||
	Query(*DB) error
 | 
			
		||||
	Update(*DB) error
 | 
			
		||||
	Delete(*DB) error
 | 
			
		||||
 | 
			
		||||
	Quote(string) string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,63 +1,112 @@
 | 
			
		||||
package sqlbuilder
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"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)
 | 
			
		||||
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() {
 | 
			
		||||
		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)
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
		s := bytes.NewBufferString("")
 | 
			
		||||
		args := []interface{}{}
 | 
			
		||||
 | 
			
		||||
					if tableName != "" {
 | 
			
		||||
						break
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
		for i, c := range tx.Statement.Conditions {
 | 
			
		||||
			if i > 0 {
 | 
			
		||||
				s.WriteString(" AND ")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if tableName != "" {
 | 
			
		||||
			if model.DefaultTableNameHandler != nil {
 | 
			
		||||
				tableChan <- model.DefaultTableNameHandler(tx, tableName)
 | 
			
		||||
			} else {
 | 
			
		||||
				tableChan <- tableName
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			tx.AddError(ErrInvalidTable)
 | 
			
		||||
			args = append(args, buildCondition(tx, c, s)...)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	return tableChan
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type tabler interface {
 | 
			
		||||
	TableName() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type dbTabler interface {
 | 
			
		||||
	TableName(*gorm.DB) string
 | 
			
		||||
	return queryChan
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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"
 | 
			
		||||
 | 
			
		||||
	"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
 | 
			
		||||
@ -23,9 +24,9 @@ func (dialect Dialect) Quote(name string) string {
 | 
			
		||||
func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
 | 
			
		||||
	var (
 | 
			
		||||
		args            []interface{}
 | 
			
		||||
		assignmentsChan = destination.GetAssignments(tx)
 | 
			
		||||
		tableNameChan   = destination.GetTable(tx)
 | 
			
		||||
		primaryFields   []*destination.Field
 | 
			
		||||
		assignmentsChan = sqlbuilder.GetAssignmentFields(tx)
 | 
			
		||||
		tableNameChan   = sqlbuilder.GetTable(tx)
 | 
			
		||||
		primaryFields   []*model.Field
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	s := bytes.NewBufferString("INSERT INTO ")
 | 
			
		||||
@ -41,7 +42,7 @@ func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
 | 
			
		||||
		valueBuffer := bytes.NewBufferString("VALUES ")
 | 
			
		||||
 | 
			
		||||
		for idx, fields := range assignments {
 | 
			
		||||
			var primaryField *destination.Field
 | 
			
		||||
			var primaryField *model.Field
 | 
			
		||||
			if idx != 0 {
 | 
			
		||||
				valueBuffer.WriteString(",")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -105,8 +105,8 @@ func (stmt *Statement) AddConditions(conds ...ConditionInterface) {
 | 
			
		||||
 | 
			
		||||
// Raw raw sql
 | 
			
		||||
type Raw struct {
 | 
			
		||||
	Value string
 | 
			
		||||
	Args  []interface{} // TODO NamedArg
 | 
			
		||||
	SQL  string
 | 
			
		||||
	Args []interface{} // TODO NamedArg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Eq equal to
 | 
			
		||||
@ -153,7 +153,7 @@ type Lte struct {
 | 
			
		||||
type And []ConditionInterface
 | 
			
		||||
 | 
			
		||||
// Not TRUE if condition is false
 | 
			
		||||
type Not ConditionInterface
 | 
			
		||||
type Not []ConditionInterface
 | 
			
		||||
 | 
			
		||||
// Or TRUE if any of the conditions is TRUE
 | 
			
		||||
type Or []ConditionInterface
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user