Build query SQL
This commit is contained in:
parent
0e25debf63
commit
eb43b539f9
@ -12,13 +12,13 @@ type ConditionInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildConditions build conditions
|
// BuildConditions build conditions
|
||||||
func BuildConditions(tx *gorm.DB) chan *Builder {
|
func BuildConditions(tx *gorm.DB, conds []gorm.ConditionInterface) chan *Builder {
|
||||||
queryChan := make(chan *Builder)
|
queryChan := make(chan *Builder)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
builder := &Builder{}
|
builder := &Builder{}
|
||||||
|
|
||||||
for i, c := range tx.Statement.Conditions {
|
for i, c := range conds {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
builder.SQL.WriteString(" AND ")
|
builder.SQL.WriteString(" AND ")
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,35 @@ func GetAssignmentFields(tx *gorm.DB) chan [][]*model.Field {
|
|||||||
return fieldChan
|
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
|
// TODO assign those value to dest
|
||||||
for k, v := range value {
|
for k, v := range value {
|
||||||
if s != nil {
|
if s != nil {
|
||||||
if f := s.FieldByName(k); f != nil {
|
if f := s.FieldByName(k); f != nil {
|
||||||
field := &model.Field{Field: f, Value: reflect.ValueOf(v)}
|
field := &model.Field{Field: f, Value: reflect.ValueOf(v)}
|
||||||
if assignableChecker(field) {
|
if assignableChecker(field.Field) {
|
||||||
fields = append(fields, field)
|
fields = append(fields, field)
|
||||||
}
|
}
|
||||||
continue
|
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)}
|
field := &model.Field{Field: &schema.Field{DBName: k}, Value: reflect.ValueOf(v)}
|
||||||
if assignableChecker(field) {
|
if assignableChecker(field.Field) {
|
||||||
fields = append(fields, field)
|
fields = append(fields, field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +97,7 @@ func mapToFields(value map[string]interface{}, s *schema.Schema, assignableCheck
|
|||||||
return
|
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?
|
// TODO use Offset to replace FieldByName?
|
||||||
for _, sf := range s.Fields {
|
for _, sf := range s.Fields {
|
||||||
obj := value
|
obj := value
|
||||||
@ -83,7 +105,7 @@ func structToField(value reflect.Value, s *schema.Schema, assignableChecker func
|
|||||||
obj = value.FieldByName(bn)
|
obj = value.FieldByName(bn)
|
||||||
}
|
}
|
||||||
field := &model.Field{Field: sf, Value: obj, IsBlank: model.IsBlank(obj)}
|
field := &model.Field{Field: sf, Value: obj, IsBlank: model.IsBlank(obj)}
|
||||||
if assignableChecker(field) {
|
if assignableChecker(field.Field) {
|
||||||
fields = append(fields, 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
|
// generateAssignableChecker generate checker to check if field is assignable or not
|
||||||
func generateAssignableChecker(selectAttrs []string, omitAttrs []string) func(*model.Field) bool {
|
func generateAssignableChecker(selectAttrs []string, omitAttrs []string) func(*schema.Field) bool {
|
||||||
return func(field *model.Field) bool {
|
return func(field *schema.Field) bool {
|
||||||
if len(selectAttrs) > 0 {
|
if len(selectAttrs) > 0 {
|
||||||
for _, attr := range selectAttrs {
|
for _, attr := range selectAttrs {
|
||||||
if field.Name == attr || field.DBName == attr {
|
if field.Name == attr || field.DBName == attr {
|
||||||
|
@ -13,6 +13,7 @@ func BuildGroupCondition(tx *gorm.DB) chan *Builder {
|
|||||||
go func() {
|
go func() {
|
||||||
builder := &Builder{}
|
builder := &Builder{}
|
||||||
if groupBy := tx.Statement.GroupBy; len(groupBy.Columns) > 0 {
|
if groupBy := tx.Statement.GroupBy; len(groupBy.Columns) > 0 {
|
||||||
|
builder.SQL.WriteString(" GROUP BY ")
|
||||||
builder.SQL.WriteString(strings.Join(tx.Statement.GroupBy.Columns, ", "))
|
builder.SQL.WriteString(strings.Join(tx.Statement.GroupBy.Columns, ", "))
|
||||||
|
|
||||||
if len(groupBy.Having) > 0 {
|
if len(groupBy.Having) > 0 {
|
||||||
|
@ -100,8 +100,68 @@ func (dialect *Dialect) Insert(tx *gorm.DB) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query query
|
// Query query
|
||||||
func (*Dialect) Query(tx *gorm.DB) error {
|
func (dialect *Dialect) Query(tx *gorm.DB) (err error) {
|
||||||
return nil
|
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
|
// Update update
|
||||||
|
Loading…
x
Reference in New Issue
Block a user