Skip to content

Commit

Permalink
Refactor clause Writer
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhu committed Mar 9, 2020
1 parent 3aa1891 commit 504f427
Show file tree
Hide file tree
Showing 20 changed files with 117 additions and 108 deletions.
11 changes: 7 additions & 4 deletions clause/clause.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ type ClauseBuilder interface {
Build(Clause, Builder)
}

type Writer interface {
WriteByte(byte) error
WriteString(string) (int, error)
}

// Builder builder interface
type Builder interface {
WriteByte(byte) error
Write(sql ...string) error
Writer
WriteQuoted(field interface{}) error
AddVar(vars ...interface{}) string
Quote(field interface{}) string
AddVar(Writer, ...interface{})
}

// Clause
Expand Down
4 changes: 2 additions & 2 deletions clause/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ func (d Delete) Name() string {
}

func (d Delete) Build(builder Builder) {
builder.Write("DELETE")
builder.WriteString("DELETE")

if d.Modifier != "" {
builder.WriteByte(' ')
builder.Write(d.Modifier)
builder.WriteString(d.Modifier)
}
}

Expand Down
60 changes: 37 additions & 23 deletions clause/expression.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package clause

import (
"strings"
)

// Expression expression interface
type Expression interface {
Build(builder Builder)
Expand All @@ -22,11 +18,15 @@ type Expr struct {

// Build build raw expression
func (expr Expr) Build(builder Builder) {
sql := expr.SQL
for _, v := range expr.Vars {
sql = strings.Replace(sql, "?", builder.AddVar(v), 1)
var idx int
for _, v := range []byte(expr.SQL) {
if v == '?' {
builder.AddVar(builder, expr.Vars[idx])
idx++
} else {
builder.WriteByte(v)
}
}
builder.Write(sql)
}

// IN Whether a value is within a set of values
Expand All @@ -40,21 +40,27 @@ func (in IN) Build(builder Builder) {

switch len(in.Values) {
case 0:
builder.Write(" IN (NULL)")
builder.WriteString(" IN (NULL)")
case 1:
builder.Write(" = ", builder.AddVar(in.Values...))
builder.WriteString(" = ")
builder.AddVar(builder, in.Values...)
default:
builder.Write(" IN (", builder.AddVar(in.Values...), ")")
builder.WriteString(" IN (")
builder.AddVar(builder, in.Values...)
builder.WriteByte(')')
}
}

func (in IN) NegationBuild(builder Builder) {
switch len(in.Values) {
case 0:
case 1:
builder.Write(" <> ", builder.AddVar(in.Values...))
builder.WriteString(" <> ")
builder.AddVar(builder, in.Values...)
default:
builder.Write(" NOT IN (", builder.AddVar(in.Values...), ")")
builder.WriteString(" NOT IN (")
builder.AddVar(builder, in.Values...)
builder.WriteByte(')')
}
}

Expand All @@ -68,9 +74,10 @@ func (eq Eq) Build(builder Builder) {
builder.WriteQuoted(eq.Column)

if eq.Value == nil {
builder.Write(" IS NULL")
builder.WriteString(" IS NULL")
} else {
builder.Write(" = ", builder.AddVar(eq.Value))
builder.WriteString(" = ")
builder.AddVar(builder, eq.Value)
}
}

Expand All @@ -85,9 +92,10 @@ func (neq Neq) Build(builder Builder) {
builder.WriteQuoted(neq.Column)

if neq.Value == nil {
builder.Write(" IS NOT NULL")
builder.WriteString(" IS NOT NULL")
} else {
builder.Write(" <> ", builder.AddVar(neq.Value))
builder.WriteString(" <> ")
builder.AddVar(builder, neq.Value)
}
}

Expand All @@ -100,7 +108,8 @@ type Gt Eq

func (gt Gt) Build(builder Builder) {
builder.WriteQuoted(gt.Column)
builder.Write(" > ", builder.AddVar(gt.Value))
builder.WriteString(" > ")
builder.AddVar(builder, gt.Value)
}

func (gt Gt) NegationBuild(builder Builder) {
Expand All @@ -112,7 +121,8 @@ type Gte Eq

func (gte Gte) Build(builder Builder) {
builder.WriteQuoted(gte.Column)
builder.Write(" >= ", builder.AddVar(gte.Value))
builder.WriteString(" >= ")
builder.AddVar(builder, gte.Value)
}

func (gte Gte) NegationBuild(builder Builder) {
Expand All @@ -124,7 +134,8 @@ type Lt Eq

func (lt Lt) Build(builder Builder) {
builder.WriteQuoted(lt.Column)
builder.Write(" < ", builder.AddVar(lt.Value))
builder.WriteString(" < ")
builder.AddVar(builder, lt.Value)
}

func (lt Lt) NegationBuild(builder Builder) {
Expand All @@ -136,7 +147,8 @@ type Lte Eq

func (lte Lte) Build(builder Builder) {
builder.WriteQuoted(lte.Column)
builder.Write(" <= ", builder.AddVar(lte.Value))
builder.WriteString(" <= ")
builder.AddVar(builder, lte.Value)
}

func (lte Lte) NegationBuild(builder Builder) {
Expand All @@ -148,12 +160,14 @@ type Like Eq

func (like Like) Build(builder Builder) {
builder.WriteQuoted(like.Column)
builder.Write(" LIKE ", builder.AddVar(like.Value))
builder.WriteString(" LIKE ")
builder.AddVar(builder, like.Value)
}

func (like Like) NegationBuild(builder Builder) {
builder.WriteQuoted(like.Column)
builder.Write(" NOT LIKE ", builder.AddVar(like.Value))
builder.WriteString(" NOT LIKE ")
builder.AddVar(builder, like.Value)
}

// Map
Expand Down
8 changes: 4 additions & 4 deletions clause/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ func (from From) Build(builder Builder) {

func (join Join) Build(builder Builder) {
if join.Type != "" {
builder.Write(string(join.Type))
builder.WriteString(string(join.Type))
builder.WriteByte(' ')
}

builder.Write("JOIN ")
builder.WriteString("JOIN ")
builder.WriteQuoted(join.Table)

if len(join.ON.Exprs) > 0 {
builder.Write(" ON ")
builder.WriteString(" ON ")
join.ON.Build(builder)
} else if len(join.Using) > 0 {
builder.Write(" USING (")
builder.WriteString(" USING (")
for idx, c := range join.Using {
if idx > 0 {
builder.WriteByte(',')
Expand Down
2 changes: 1 addition & 1 deletion clause/group_by.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (groupBy GroupBy) Build(builder Builder) {
}

if len(groupBy.Having) > 0 {
builder.Write(" HAVING ")
builder.WriteString(" HAVING ")
Where{Exprs: groupBy.Having}.Build(builder)
}
}
Expand Down
4 changes: 2 additions & 2 deletions clause/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ func (insert Insert) Name() string {
// Build build insert clause
func (insert Insert) Build(builder Builder) {
if insert.Modifier != "" {
builder.Write(insert.Modifier)
builder.WriteString(insert.Modifier)
builder.WriteByte(' ')
}

builder.Write("INTO ")
builder.WriteString("INTO ")
if insert.Table.Name == "" {
builder.WriteQuoted(currentTable)
} else {
Expand Down
8 changes: 4 additions & 4 deletions clause/limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ func (limit Limit) Name() string {
// Build build where clause
func (limit Limit) Build(builder Builder) {
if limit.Limit > 0 {
builder.Write("LIMIT ")
builder.Write(strconv.Itoa(limit.Limit))
builder.WriteString("LIMIT ")
builder.WriteString(strconv.Itoa(limit.Limit))

if limit.Offset > 0 {
builder.Write(" OFFSET ")
builder.Write(strconv.Itoa(limit.Offset))
builder.WriteString(" OFFSET ")
builder.WriteString(strconv.Itoa(limit.Offset))
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions clause/locking.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ func (f For) Build(builder Builder) {
builder.WriteByte(' ')
}

builder.Write("FOR ")
builder.Write(locking.Strength)
builder.WriteString("FOR ")
builder.WriteString(locking.Strength)
if locking.Table.Name != "" {
builder.Write(" OF ")
builder.WriteString(" OF ")
builder.WriteQuoted(locking.Table)
}

if locking.Options != "" {
builder.WriteByte(' ')
builder.Write(locking.Options)
builder.WriteString(locking.Options)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion clause/order_by.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (orderBy OrderBy) Build(builder Builder) {

builder.WriteQuoted(column.Column)
if column.Desc {
builder.Write(" DESC")
builder.WriteString(" DESC")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion clause/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (set Set) Build(builder Builder) {
}
builder.WriteQuoted(assignment.Column)
builder.WriteByte('=')
builder.Write(builder.AddVar(assignment.Value))
builder.AddVar(builder, assignment.Value)
}
} else {
builder.WriteQuoted(PrimaryColumn)
Expand Down
2 changes: 1 addition & 1 deletion clause/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (update Update) Name() string {
// Build build update clause
func (update Update) Build(builder Builder) {
if update.Modifier != "" {
builder.Write(update.Modifier)
builder.WriteString(update.Modifier)
builder.WriteByte(' ')
}

Expand Down
6 changes: 3 additions & 3 deletions clause/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ func (values Values) Build(builder Builder) {
}
builder.WriteByte(')')

builder.Write(" VALUES ")
builder.WriteString(" VALUES ")

for idx, value := range values.Values {
if idx > 0 {
builder.WriteByte(',')
}

builder.WriteByte('(')
builder.Write(builder.AddVar(value...))
builder.AddVar(builder, value...)
builder.WriteByte(')')
}
} else {
builder.Write("DEFAULT VALUES")
builder.WriteString("DEFAULT VALUES")
}
}

Expand Down
12 changes: 6 additions & 6 deletions clause/where.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func (where Where) Build(builder Builder) {
if expr != nil {
if idx > 0 {
if v, ok := expr.(OrConditions); ok && len(v.Exprs) == 1 {
builder.Write(" OR ")
builder.WriteString(" OR ")
} else {
builder.Write(" AND ")
builder.WriteString(" AND ")
}
}

Expand Down Expand Up @@ -65,7 +65,7 @@ func (and AndConditions) Build(builder Builder) {
}
for idx, c := range and.Exprs {
if idx > 0 {
builder.Write(" AND ")
builder.WriteString(" AND ")
}
c.Build(builder)
}
Expand All @@ -91,7 +91,7 @@ func (or OrConditions) Build(builder Builder) {
}
for idx, c := range or.Exprs {
if idx > 0 {
builder.Write(" OR ")
builder.WriteString(" OR ")
}
c.Build(builder)
}
Expand All @@ -117,13 +117,13 @@ func (not NotConditions) Build(builder Builder) {
}
for idx, c := range not.Exprs {
if idx > 0 {
builder.Write(" AND ")
builder.WriteString(" AND ")
}

if negationBuilder, ok := c.(NegationExpressionBuilder); ok {
negationBuilder.NegationBuild(builder)
} else {
builder.Write(" NOT ")
builder.WriteString(" NOT ")
c.Build(builder)
}
}
Expand Down
10 changes: 5 additions & 5 deletions dialects/mssql/mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"fmt"
"regexp"
"strconv"
"strings"

_ "github.com/denisenkom/go-mssqldb"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/callbacks"
"github.com/jinzhu/gorm/clause"
"github.com/jinzhu/gorm/logger"
"github.com/jinzhu/gorm/migrator"
"github.com/jinzhu/gorm/schema"
Expand Down Expand Up @@ -42,10 +42,10 @@ func (dialector Dialector) BindVar(stmt *gorm.Statement, v interface{}) string {
return "@p" + strconv.Itoa(len(stmt.Vars))
}

func (dialector Dialector) QuoteTo(builder *strings.Builder, str string) {
builder.WriteByte('"')
builder.WriteString(str)
builder.WriteByte('"')
func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {
writer.WriteByte('"')
writer.WriteString(str)
writer.WriteByte('"')
}

var numericPlaceholder = regexp.MustCompile("@p(\\d+)")
Expand Down
Loading

0 comments on commit 504f427

Please sign in to comment.