Skip to content

Commit

Permalink
fix(sqlbuilder): 正确处理 where 语句中包含表名的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
caixw committed Aug 27, 2024
1 parent b31a909 commit 858081e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
16 changes: 15 additions & 1 deletion core/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

package core

import "github.com/issue9/errwrap"
import (
"strings"

"github.com/issue9/errwrap"
)

// 作用于表名,列名等非关键字上的引号占位符。
// 在执行会自动替换成该数据库相应的符号。
Expand Down Expand Up @@ -56,6 +60,16 @@ func (b *Builder) Quote(str string, l, r byte) *Builder { return b.WBytes(l).WSt
// QuoteKey 给 str 左右添加 [QuoteLeft] 和 [QuoteRight] 两个字符
func (b *Builder) QuoteKey(str string) *Builder { return b.Quote(str, QuoteLeft, QuoteRight) }

// QuoteColumn 为列名添加 [QuoteLeft] 和 [QuoteRight] 两个字符
//
// NOTE: 列名可能包含表名或是表名别名:table.col
func (b *Builder) QuoteColumn(col string) *Builder {
if index := strings.IndexByte(col, '.'); index > 0 {
return b.QuoteKey(col[:index]).WBytes('.').QuoteKey(col[index+1:])
}
return b.Quote(col, QuoteLeft, QuoteRight)
}

// Reset 重置内容,同时也会将 err 设置为 nil
func (b *Builder) Reset() *Builder {
b.buffer.Reset()
Expand Down
26 changes: 13 additions & 13 deletions sqlbuilder/where.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,91 +135,91 @@ func (stmt *WhereStmt) Or(cond string, args ...any) *WhereStmt {
// AndIsNull 指定 WHERE ... AND col IS NULL
func (stmt *WhereStmt) AndIsNull(col string) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" IS NULL ")
stmt.builder.QuoteColumn(col).WString(" IS NULL ")
return stmt
}

// OrIsNull 指定 WHERE ... OR col IS NULL
func (stmt *WhereStmt) OrIsNull(col string) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" IS NULL ")
stmt.builder.QuoteColumn(col).WString(" IS NULL ")
return stmt
}

// AndIsNotNull 指定 WHERE ... AND col IS NOT NULL
func (stmt *WhereStmt) AndIsNotNull(col string) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" IS NOT NULL ")
stmt.builder.QuoteColumn(col).WString(" IS NOT NULL ")
return stmt
}

// OrIsNotNull 指定 WHERE ... OR col IS NOT NULL
func (stmt *WhereStmt) OrIsNotNull(col string) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" IS NOT NULL ")
stmt.builder.QuoteColumn(col).WString(" IS NOT NULL ")
return stmt
}

// AndBetween 指定 WHERE ... AND col BETWEEN v1 AND v2
func (stmt *WhereStmt) AndBetween(col string, v1, v2 any) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" BETWEEN ? AND ? ")
stmt.builder.QuoteColumn(col).WString(" BETWEEN ? AND ? ")
stmt.args = append(stmt.args, v1, v2)
return stmt
}

// OrBetween 指定 WHERE ... OR col BETWEEN v1 AND v2
func (stmt *WhereStmt) OrBetween(col string, v1, v2 any) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" BETWEEN ? AND ? ")
stmt.builder.QuoteColumn(col).WString(" BETWEEN ? AND ? ")
stmt.args = append(stmt.args, v1, v2)
return stmt
}

// AndNotBetween 指定 WHERE ... AND col NOT BETWEEN v1 AND v2
func (stmt *WhereStmt) AndNotBetween(col string, v1, v2 any) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" NOT BETWEEN ? AND ? ")
stmt.builder.QuoteColumn(col).WString(" NOT BETWEEN ? AND ? ")
stmt.args = append(stmt.args, v1, v2)
return stmt
}

// OrNotBetween 指定 WHERE ... OR col BETWEEN v1 AND v2
func (stmt *WhereStmt) OrNotBetween(col string, v1, v2 any) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" NOT BETWEEN ? AND ? ")
stmt.builder.QuoteColumn(col).WString(" NOT BETWEEN ? AND ? ")
stmt.args = append(stmt.args, v1, v2)
return stmt
}

// AndLike 指定 WHERE ... AND col LIKE content
func (stmt *WhereStmt) AndLike(col string, content any) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" LIKE ?")
stmt.builder.QuoteColumn(col).WString(" LIKE ?")
stmt.args = append(stmt.args, content)
return stmt
}

// OrLike 指定 WHERE ... OR col LIKE content
func (stmt *WhereStmt) OrLike(col string, content any) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" LIKE ?")
stmt.builder.QuoteColumn(col).WString(" LIKE ?")
stmt.args = append(stmt.args, content)
return stmt
}

// AndNotLike 指定 WHERE ... AND col NOT LIKE content
func (stmt *WhereStmt) AndNotLike(col string, content any) *WhereStmt {
stmt.writeAnd(true)
stmt.builder.QuoteKey(col).WString(" NOT LIKE ?")
stmt.builder.QuoteColumn(col).WString(" NOT LIKE ?")
stmt.args = append(stmt.args, content)
return stmt
}

// OrNotLike 指定 WHERE ... OR col NOT LIKE content
func (stmt *WhereStmt) OrNotLike(col string, content any) *WhereStmt {
stmt.writeAnd(false)
stmt.builder.QuoteKey(col).WString(" NOT LIKE ?")
stmt.builder.QuoteColumn(col).WString(" NOT LIKE ?")
stmt.args = append(stmt.args, content)
return stmt
}
Expand Down Expand Up @@ -250,7 +250,7 @@ func (stmt *WhereStmt) in(and, not bool, col string, v ...any) *WhereStmt {
}

stmt.writeAnd(and)
stmt.builder.QuoteKey(col)
stmt.builder.QuoteColumn(col)

if not {
stmt.builder.WString(" NOT")
Expand Down
4 changes: 2 additions & 2 deletions sqlbuilder/where_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ func TestWhereStmt_IsNull(t *testing.T) {
a.NotError(err).Empty(args)
sqltest.Equal(a, query, "{col1} is null")

w.OrIsNull("col2")
w.OrIsNull("tbl.col2")
query, args, err = w.SQL()
a.NotError(err).Empty(args)
sqltest.Equal(a, query, "{col1} is null or {col2} is null")
sqltest.Equal(a, query, "{col1} is null or {tbl}.{col2} is null")

w.Reset()
w.AndIsNotNull("col1")
Expand Down

0 comments on commit 858081e

Please sign in to comment.