From d7ac078e4c0e1c31340b8149a09782d492d519a9 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Fri, 16 Mar 2018 18:29:11 +0800 Subject: [PATCH] Update sqlbuilder for sqlite --- dialects/common/sqlbuilder/conditions.go | 14 ++-- dialects/common/sqlbuilder/join.go | 25 +++++++ dialects/sqlite/sqlite.go | 86 ++++++++++++++++++++---- 3 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 dialects/common/sqlbuilder/join.go diff --git a/dialects/common/sqlbuilder/conditions.go b/dialects/common/sqlbuilder/conditions.go index 34b908e7..6cac5c36 100644 --- a/dialects/common/sqlbuilder/conditions.go +++ b/dialects/common/sqlbuilder/conditions.go @@ -12,17 +12,19 @@ type ConditionInterface interface { } // BuildConditions build conditions -func BuildConditions(tx *gorm.DB, conds []gorm.ConditionInterface) chan *Builder { +func BuildConditions(tx *gorm.DB) chan *Builder { queryChan := make(chan *Builder) go func() { builder := &Builder{} - - for i, c := range conds { - if i > 0 { - builder.SQL.WriteString(" AND ") + if len(tx.Statement.Conditions) > 0 { + builder.SQL.WriteString(" WHERE ") + for i, c := range tx.Statement.Conditions { + if i > 0 { + builder.SQL.WriteString(" AND ") + } + buildCondition(tx, c, builder) } - buildCondition(tx, c, builder) } queryChan <- builder diff --git a/dialects/common/sqlbuilder/join.go b/dialects/common/sqlbuilder/join.go new file mode 100644 index 00000000..0ec3ea15 --- /dev/null +++ b/dialects/common/sqlbuilder/join.go @@ -0,0 +1,25 @@ +package sqlbuilder + +import ( + "github.com/jinzhu/gorm" +) + +// BuildJoinCondition build join condition +func BuildJoinCondition(tx *gorm.DB) chan *Builder { + joinChan := make(chan *Builder) + + go func() { + builder := &Builder{} + for _, join := range tx.Statement.Joins { + if join.Table == "" { + for _, cond := range join.Conditions { + buildCondition(tx, cond, builder) + } + } + // FIXME fix join builder + } + joinChan <- builder + }() + + return joinChan +} diff --git a/dialects/sqlite/sqlite.go b/dialects/sqlite/sqlite.go index fc6c0763..ecc12fe7 100644 --- a/dialects/sqlite/sqlite.go +++ b/dialects/sqlite/sqlite.go @@ -104,7 +104,8 @@ func (dialect *Dialect) Query(tx *gorm.DB) (err error) { var ( args []interface{} tableNameChan = sqlbuilder.GetTable(tx) - conditionsChan = sqlbuilder.BuildConditions(tx, tx.Statement.Conditions) + joinChan = sqlbuilder.BuildJoinCondition(tx) + conditionsChan = sqlbuilder.BuildConditions(tx) groupChan = sqlbuilder.BuildGroupCondition(tx) orderChan = sqlbuilder.BuildOrderCondition(tx) limitChan = sqlbuilder.BuildLimitCondition(tx) @@ -131,17 +132,12 @@ func (dialect *Dialect) Query(tx *gorm.DB) (err error) { 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 builder := <-joinChan; builder != nil { + _, err = builder.SQL.WriteTo(s) + args = append(args, builder.Args) } if len(tx.Statement.Conditions) > 0 { - s.WriteString(" WHERE ") builder := <-conditionsChan _, err = builder.SQL.WriteTo(s) args = append(args, builder.Args...) @@ -165,11 +161,75 @@ func (dialect *Dialect) Query(tx *gorm.DB) (err error) { } // Update update -func (*Dialect) Update(tx *gorm.DB) error { - return nil +func (dialect *Dialect) Update(tx *gorm.DB) (err error) { + var ( + args []interface{} + tableNameChan = sqlbuilder.GetTable(tx) + conditionsChan = sqlbuilder.BuildConditions(tx) + assignmentsChan = sqlbuilder.GetAssignmentFields(tx) + orderChan = sqlbuilder.BuildOrderCondition(tx) + limitChan = sqlbuilder.BuildLimitCondition(tx) + ) + + s := bytes.NewBufferString("UPDATE ") + s.WriteString(dialect.Quote(<-tableNameChan)) + s.WriteString(" SET ") + if assignments := <-assignmentsChan; len(assignments) > 0 { + for _, fields := range assignments { + for _, field := range fields { + s.WriteString(dialect.Quote(field.Field.DBName)) + s.WriteString(" = ?") + args = append(args, field.Value.Interface()) + } + // TODO update with multiple records + } + } + + if len(tx.Statement.Conditions) > 0 { + builder := <-conditionsChan + _, 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 err } // Delete delete -func (*Dialect) Delete(tx *gorm.DB) error { - return nil +func (dialect *Dialect) Delete(tx *gorm.DB) (err error) { + var ( + args []interface{} + tableNameChan = sqlbuilder.GetTable(tx) + conditionsChan = sqlbuilder.BuildConditions(tx) + orderChan = sqlbuilder.BuildOrderCondition(tx) + limitChan = sqlbuilder.BuildLimitCondition(tx) + ) + s := bytes.NewBufferString("DELETE FROM ") + s.WriteString(dialect.Quote(<-tableNameChan)) + + if len(tx.Statement.Conditions) > 0 { + builder := <-conditionsChan + _, 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 }