diff --git a/core/builder.go b/core/builder.go index d2c6931..0220405 100644 --- a/core/builder.go +++ b/core/builder.go @@ -4,7 +4,11 @@ package core -import "github.com/issue9/errwrap" +import ( + "strings" + + "github.com/issue9/errwrap" +) // 作用于表名,列名等非关键字上的引号占位符。 // 在执行会自动替换成该数据库相应的符号。 @@ -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() diff --git a/sqlbuilder/where.go b/sqlbuilder/where.go index 37a826f..db04245 100644 --- a/sqlbuilder/where.go +++ b/sqlbuilder/where.go @@ -135,35 +135,35 @@ 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 } @@ -171,7 +171,7 @@ func (stmt *WhereStmt) AndBetween(col string, v1, v2 any) *WhereStmt { // 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 } @@ -179,7 +179,7 @@ func (stmt *WhereStmt) OrBetween(col string, v1, v2 any) *WhereStmt { // 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 } @@ -187,7 +187,7 @@ func (stmt *WhereStmt) AndNotBetween(col string, v1, v2 any) *WhereStmt { // 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 } @@ -195,7 +195,7 @@ func (stmt *WhereStmt) OrNotBetween(col string, v1, v2 any) *WhereStmt { // 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 } @@ -203,7 +203,7 @@ func (stmt *WhereStmt) AndLike(col string, content any) *WhereStmt { // 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 } @@ -211,7 +211,7 @@ func (stmt *WhereStmt) OrLike(col string, content any) *WhereStmt { // 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 } @@ -219,7 +219,7 @@ func (stmt *WhereStmt) AndNotLike(col string, content any) *WhereStmt { // 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 } @@ -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") diff --git a/sqlbuilder/where_test.go b/sqlbuilder/where_test.go index 64ff868..6c0dda0 100644 --- a/sqlbuilder/where_test.go +++ b/sqlbuilder/where_test.go @@ -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")