Build query SQL
This commit is contained in:
parent
0e25debf63
commit
eb43b539f9
@ -12,13 +12,13 @@ type ConditionInterface interface {
|
||||
}
|
||||
|
||||
// BuildConditions build conditions
|
||||
func BuildConditions(tx *gorm.DB) chan *Builder {
|
||||
func BuildConditions(tx *gorm.DB, conds []gorm.ConditionInterface) chan *Builder {
|
||||
queryChan := make(chan *Builder)
|
||||
|
||||
go func() {
|
||||
builder := &Builder{}
|
||||
|
||||
for i, c := range tx.Statement.Conditions {
|
||||
for i, c := range conds {
|
||||
if i > 0 {
|
||||
builder.SQL.WriteString(" AND ")
|
||||
}
|
||||
|
@ -50,13 +50,35 @@ func GetAssignmentFields(tx *gorm.DB) chan [][]*model.Field {
|
||||
return fieldChan
|
||||
}
|
||||
|
||||
func mapToFields(value map[string]interface{}, s *schema.Schema, assignableChecker func(*model.Field) bool) (fields []*model.Field) {
|
||||
// GetSelectableFields get selectable fields
|
||||
func GetSelectableFields(tx *gorm.DB) chan []string {
|
||||
fieldChan := make(chan []string)
|
||||
|
||||
go func() {
|
||||
assignableChecker := generateAssignableChecker(selectAttrs(tx.Statement), omitAttrs(tx.Statement))
|
||||
if s := schema.Parse(tx.Statement.Dest); s != nil {
|
||||
columns := []string{}
|
||||
for _, field := range s.Fields {
|
||||
if assignableChecker(field) {
|
||||
columns = append(columns, field.DBName)
|
||||
}
|
||||
}
|
||||
fieldChan <- columns
|
||||
return
|
||||
}
|
||||
fieldChan <- []string{"*"}
|
||||
}()
|
||||
|
||||
return fieldChan
|
||||
}
|
||||
|
||||
func mapToFields(value map[string]interface{}, s *schema.Schema, assignableChecker func(*schema.Field) bool) (fields []*model.Field) {
|
||||
// TODO assign those value to dest
|
||||
for k, v := range value {
|
||||
if s != nil {
|
||||
if f := s.FieldByName(k); f != nil {
|
||||
field := &model.Field{Field: f, Value: reflect.ValueOf(v)}
|
||||
if assignableChecker(field) {
|
||||
if assignableChecker(field.Field) {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
continue
|
||||
@ -64,7 +86,7 @@ func mapToFields(value map[string]interface{}, s *schema.Schema, assignableCheck
|
||||
}
|
||||
|
||||
field := &model.Field{Field: &schema.Field{DBName: k}, Value: reflect.ValueOf(v)}
|
||||
if assignableChecker(field) {
|
||||
if assignableChecker(field.Field) {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
}
|
||||
@ -75,7 +97,7 @@ func mapToFields(value map[string]interface{}, s *schema.Schema, assignableCheck
|
||||
return
|
||||
}
|
||||
|
||||
func structToField(value reflect.Value, s *schema.Schema, assignableChecker func(*model.Field) bool) (fields []*model.Field) {
|
||||
func structToField(value reflect.Value, s *schema.Schema, assignableChecker func(*schema.Field) bool) (fields []*model.Field) {
|
||||
// TODO use Offset to replace FieldByName?
|
||||
for _, sf := range s.Fields {
|
||||
obj := value
|
||||
@ -83,7 +105,7 @@ func structToField(value reflect.Value, s *schema.Schema, assignableChecker func
|
||||
obj = value.FieldByName(bn)
|
||||
}
|
||||
field := &model.Field{Field: sf, Value: obj, IsBlank: model.IsBlank(obj)}
|
||||
if assignableChecker(field) {
|
||||
if assignableChecker(field.Field) {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
}
|
||||
@ -91,8 +113,8 @@ func structToField(value reflect.Value, s *schema.Schema, assignableChecker func
|
||||
}
|
||||
|
||||
// generateAssignableChecker generate checker to check if field is assignable or not
|
||||
func generateAssignableChecker(selectAttrs []string, omitAttrs []string) func(*model.Field) bool {
|
||||
return func(field *model.Field) bool {
|
||||
func generateAssignableChecker(selectAttrs []string, omitAttrs []string) func(*schema.Field) bool {
|
||||
return func(field *schema.Field) bool {
|
||||
if len(selectAttrs) > 0 {
|
||||
for _, attr := range selectAttrs {
|
||||
if field.Name == attr || field.DBName == attr {
|
||||
|
@ -13,6 +13,7 @@ func BuildGroupCondition(tx *gorm.DB) chan *Builder {
|
||||
go func() {
|
||||
builder := &Builder{}
|
||||
if groupBy := tx.Statement.GroupBy; len(groupBy.Columns) > 0 {
|
||||
builder.SQL.WriteString(" GROUP BY ")
|
||||
builder.SQL.WriteString(strings.Join(tx.Statement.GroupBy.Columns, ", "))
|
||||
|
||||
if len(groupBy.Having) > 0 {
|
||||
|
@ -100,8 +100,68 @@ func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
|
||||
}
|
||||
|
||||
// Query query
|
||||
func (*Dialect) Query(tx *gorm.DB) error {
|
||||
return nil
|
||||
func (dialect *Dialect) Query(tx *gorm.DB) (err error) {
|
||||
var (
|
||||
args []interface{}
|
||||
tableNameChan = sqlbuilder.GetTable(tx)
|
||||
conditionsChan = sqlbuilder.BuildConditions(tx, tx.Statement.Conditions)
|
||||
groupChan = sqlbuilder.BuildGroupCondition(tx)
|
||||
orderChan = sqlbuilder.BuildOrderCondition(tx)
|
||||
limitChan = sqlbuilder.BuildLimitCondition(tx)
|
||||
)
|
||||
|
||||
s := bytes.NewBufferString("SELECT ")
|
||||
|
||||
// FIXME quote, add table
|
||||
columns := tx.Statement.Select.Columns
|
||||
if len(columns) > 0 {
|
||||
args = append(args, tx.Statement.Select.Args...)
|
||||
} else {
|
||||
columns = []string{"*"}
|
||||
}
|
||||
|
||||
for idx, column := range columns {
|
||||
if idx != 0 {
|
||||
s.WriteString(",")
|
||||
}
|
||||
s.WriteString(column)
|
||||
}
|
||||
|
||||
s.WriteString(" FROM ")
|
||||
s.WriteString(dialect.Quote(<-tableNameChan))
|
||||
|
||||
// Join SQL
|
||||
for _, join := range tx.Statement.Joins {
|
||||
if join.Table == "" {
|
||||
builder := <-sqlbuilder.BuildConditions(tx, join.Conditions)
|
||||
_, err = builder.SQL.WriteTo(s)
|
||||
args = append(args, builder.Args...)
|
||||
}
|
||||
// FIXME
|
||||
}
|
||||
|
||||
if len(tx.Statement.Conditions) > 0 {
|
||||
s.WriteString(" WHERE ")
|
||||
builder := <-conditionsChan
|
||||
_, err = builder.SQL.WriteTo(s)
|
||||
args = append(args, builder.Args...)
|
||||
}
|
||||
|
||||
if builder := <-groupChan; builder != nil {
|
||||
_, err = builder.SQL.WriteTo(s)
|
||||
args = append(args, builder.Args)
|
||||
}
|
||||
|
||||
if builder := <-orderChan; builder != nil {
|
||||
_, err = builder.SQL.WriteTo(s)
|
||||
args = append(args, builder.Args)
|
||||
}
|
||||
|
||||
if builder := <-limitChan; builder != nil {
|
||||
_, err = builder.SQL.WriteTo(s)
|
||||
args = append(args, builder.Args)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Update update
|
||||
|
Loading…
x
Reference in New Issue
Block a user