mirror of
https://github.com/hanzoai/sqlbuilder.git
synced 2026-10-01 00:37:42 +00:00
333 lines
8.5 KiB
Go
333 lines
8.5 KiB
Go
// Copyright 2018 Huan Du. All rights reserved.
|
|
// Licensed under the MIT license that can be found in the LICENSE file.
|
|
|
|
package sqlbuilder
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/huandu/go-assert"
|
|
)
|
|
|
|
func ExampleWhereClause() {
|
|
// Build a SQL to select a user from database.
|
|
sb := Select("name", "level").From("users")
|
|
sb.Where(
|
|
sb.Equal("id", 1234),
|
|
)
|
|
sql, args := sb.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Query database with the sql and update this user's level...
|
|
|
|
ub := Update("users")
|
|
ub.Set(
|
|
ub.Add("level", 10),
|
|
)
|
|
|
|
// The WHERE clause of UPDATE should be the same as the WHERE clause of SELECT.
|
|
ub.WhereClause = sb.WhereClause
|
|
|
|
sql, args = ub.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Output:
|
|
// SELECT name, level FROM users WHERE id = ?
|
|
// [1234]
|
|
// UPDATE users SET level = level + ? WHERE id = ?
|
|
// [10 1234]
|
|
}
|
|
|
|
func ExampleWhereClause_sharedAmongBuilders() {
|
|
// A WhereClause can be shared among builders.
|
|
// However, as it's not thread-safe, don't use it in a concurrent environment.
|
|
sb1 := Select("level").From("users")
|
|
sb2 := Select("status").From("users")
|
|
|
|
// Share the same WhereClause between sb1 and sb2.
|
|
whereClause := NewWhereClause()
|
|
sb1.WhereClause = whereClause
|
|
sb2.WhereClause = whereClause
|
|
|
|
// The Where method in sb1 and sb2 will update the same WhereClause.
|
|
// When we call sb1.Where(), the WHERE clause in sb2 will also be updated.
|
|
sb1.Where(
|
|
sb1.Like("name", "Charmy%"),
|
|
)
|
|
|
|
// We can get a copy of the WhereClause.
|
|
// The copy is independent from the original.
|
|
sb3 := Select("name").From("users")
|
|
sb3.WhereClause = CopyWhereClause(whereClause)
|
|
|
|
// Adding more expressions to sb1 and sb2 will not affect sb3.
|
|
sb2.Where(
|
|
sb2.In("status", 1, 2, 3),
|
|
)
|
|
|
|
// Adding more expressions to sb3 will not affect sb1 and sb2.
|
|
sb3.Where(
|
|
sb3.GreaterEqualThan("level", 10),
|
|
)
|
|
|
|
sql1, args1 := sb1.Build()
|
|
sql2, args2 := sb2.Build()
|
|
sql3, args3 := sb3.Build()
|
|
|
|
fmt.Println(sql1)
|
|
fmt.Println(args1)
|
|
fmt.Println(sql2)
|
|
fmt.Println(args2)
|
|
fmt.Println(sql3)
|
|
fmt.Println(args3)
|
|
|
|
// Output:
|
|
// SELECT level FROM users WHERE name LIKE ? AND status IN (?, ?, ?)
|
|
// [Charmy% 1 2 3]
|
|
// SELECT status FROM users WHERE name LIKE ? AND status IN (?, ?, ?)
|
|
// [Charmy% 1 2 3]
|
|
// SELECT name FROM users WHERE name LIKE ? AND level >= ?
|
|
// [Charmy% 10]
|
|
}
|
|
|
|
func ExampleWhereClause_clearWhereClause() {
|
|
db := DeleteFrom("users")
|
|
db.Where(
|
|
db.GreaterThan("level", 10),
|
|
)
|
|
|
|
sql, args := db.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Clear WHERE clause.
|
|
db.WhereClause = nil
|
|
sql, args = db.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
db.Where(
|
|
db.Equal("id", 1234),
|
|
)
|
|
sql, args = db.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Output:
|
|
// DELETE FROM users WHERE level > ?
|
|
// [10]
|
|
// DELETE FROM users
|
|
// []
|
|
// DELETE FROM users WHERE id = ?
|
|
// [1234]
|
|
}
|
|
|
|
func ExampleWhereClause_AddWhereExpr() {
|
|
// WhereClause can be used as a standalone builder to build WHERE clause.
|
|
// It's recommended to use it with Cond.
|
|
whereClause := NewWhereClause()
|
|
cond := NewCond()
|
|
|
|
whereClause.AddWhereExpr(
|
|
cond.Args,
|
|
cond.In("name", "Charmy", "Huan"),
|
|
cond.LessEqualThan("level", 10),
|
|
)
|
|
|
|
// Set the flavor of the WhereClause to PostgreSQL.
|
|
whereClause.SetFlavor(PostgreSQL)
|
|
|
|
sql, args := whereClause.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Use this WhereClause in another builder.
|
|
sb := MySQL.NewSelectBuilder()
|
|
sb.Select("name", "level").From("users")
|
|
sb.WhereClause = whereClause
|
|
|
|
// The flavor of sb overrides the flavor of the WhereClause.
|
|
sql, args = sb.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Output:
|
|
// WHERE name IN ($1, $2) AND level <= $3
|
|
// [Charmy Huan 10]
|
|
// SELECT name, level FROM users WHERE name IN (?, ?) AND level <= ?
|
|
// [Charmy Huan 10]
|
|
}
|
|
|
|
func ExampleWhereClause_AddWhereClause() {
|
|
sb := Select("level").From("users")
|
|
sb.Where(
|
|
sb.Equal("id", 1234),
|
|
)
|
|
|
|
sql, args := sb.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
ub := Update("users")
|
|
ub.Set(
|
|
ub.Add("level", 10),
|
|
)
|
|
|
|
// Copy the WHERE clause of sb into ub and add more expressions.
|
|
ub.AddWhereClause(sb.WhereClause).Where(
|
|
ub.Equal("deleted", 0),
|
|
)
|
|
|
|
sql, args = ub.Build()
|
|
fmt.Println(sql)
|
|
fmt.Println(args)
|
|
|
|
// Output:
|
|
// SELECT level FROM users WHERE id = ?
|
|
// [1234]
|
|
// UPDATE users SET level = level + ? WHERE id = ? AND deleted = ?
|
|
// [10 1234 0]
|
|
}
|
|
|
|
func TestWhereClauseSharedInstances(t *testing.T) {
|
|
a := assert.New(t)
|
|
sb := Select("*").From("t")
|
|
ub := Update("t").Set("foo = 1")
|
|
db := DeleteFrom("t")
|
|
|
|
whereClause := NewWhereClause()
|
|
sb.WhereClause = whereClause
|
|
ub.WhereClause = whereClause
|
|
db.WhereClause = whereClause
|
|
sb.Where(sb.Equal("id", 123))
|
|
a.Equal(sb.String(), "SELECT * FROM t WHERE id = ?")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 WHERE id = ?")
|
|
a.Equal(db.String(), "DELETE FROM t WHERE id = ?")
|
|
|
|
// Add more WhereClause.
|
|
cond := NewCond()
|
|
moreWhereClause := NewWhereClause().AddWhereExpr(
|
|
cond.Args,
|
|
cond.GreaterEqualThan("credit", 100),
|
|
)
|
|
|
|
// The moreWhereClause is added to whereClause.
|
|
// All builders sharing the same WhereClause will have the same new cluase.
|
|
sb.AddWhereClause(moreWhereClause)
|
|
a.Equal(sb.String(), "SELECT * FROM t WHERE id = ? AND credit >= ?")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 WHERE id = ? AND credit >= ?")
|
|
a.Equal(db.String(), "DELETE FROM t WHERE id = ? AND credit >= ?")
|
|
|
|
// Copied WhereClause is independent from the original.
|
|
ub.WhereClause = CopyWhereClause(whereClause)
|
|
ub.Where(ub.GreaterEqualThan("level", 10))
|
|
db.Where(db.In("status", 1, 2))
|
|
a.Equal(sb.String(), "SELECT * FROM t WHERE id = ? AND credit >= ? AND status IN (?, ?)")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 WHERE id = ? AND credit >= ? AND level >= ?")
|
|
a.Equal(db.String(), "DELETE FROM t WHERE id = ? AND credit >= ? AND status IN (?, ?)")
|
|
|
|
// Clear the WhereClause and add new where clause and expressions.
|
|
db.WhereClause = nil
|
|
db.AddWhereClause(ub.WhereClause)
|
|
db.AddWhereExpr(db.Args, db.Equal("deleted", 0))
|
|
a.Equal(sb.String(), "SELECT * FROM t WHERE id = ? AND credit >= ? AND status IN (?, ?)")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 WHERE id = ? AND credit >= ? AND level >= ?")
|
|
a.Equal(db.String(), "DELETE FROM t WHERE id = ? AND credit >= ? AND level >= ? AND deleted = ?")
|
|
|
|
// Nested WhereClause.
|
|
ub.Where(ub.NotIn("id", sb))
|
|
sb.Where(sb.NotEqual("flag", "normal"))
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 WHERE id = ? AND credit >= ? AND level >= ? AND id NOT IN (SELECT * FROM t WHERE id = ? AND credit >= ? AND status IN (?, ?) AND flag <> ?)")
|
|
}
|
|
|
|
func TestEmptyWhereExpr(t *testing.T) {
|
|
a := assert.New(t)
|
|
var emptyExpr []string
|
|
sb := Select("*").From("t").Where(emptyExpr...)
|
|
ub := Update("t").Set("foo = 1").Where(emptyExpr...)
|
|
db := DeleteFrom("t").Where(emptyExpr...)
|
|
|
|
a.Equal(sb.String(), "SELECT * FROM t")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1")
|
|
a.Equal(db.String(), "DELETE FROM t")
|
|
}
|
|
|
|
func TestEmptyStringsWhere(t *testing.T) {
|
|
a := assert.New(t)
|
|
emptyExpr := []string{"", "", ""}
|
|
|
|
sb := Select("*").From("t").Where(emptyExpr...)
|
|
ub := Update("t").Set("foo = 1").Where(emptyExpr...)
|
|
db := DeleteFrom("t").Where(emptyExpr...)
|
|
|
|
a.Equal(sb.String(), "SELECT * FROM t")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1")
|
|
a.Equal(db.String(), "DELETE FROM t")
|
|
}
|
|
|
|
func TestEmptyAddWhereExpr(t *testing.T) {
|
|
a := assert.New(t)
|
|
var emptyExpr []string
|
|
sb := Select("*").From("t")
|
|
ub := Update("t").Set("foo = 1")
|
|
db := DeleteFrom("t")
|
|
|
|
cond := NewCond()
|
|
whereClause := NewWhereClause().AddWhereExpr(
|
|
cond.Args,
|
|
emptyExpr...,
|
|
)
|
|
|
|
sb.AddWhereClause(whereClause)
|
|
ub.AddWhereClause(whereClause)
|
|
db.AddWhereClause(whereClause)
|
|
|
|
a.Equal(sb.String(), "SELECT * FROM t ")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 ")
|
|
a.Equal(db.String(), "DELETE FROM t ")
|
|
}
|
|
|
|
func TestEmptyStringsWhereAddWhereExpr(t *testing.T) {
|
|
a := assert.New(t)
|
|
emptyExpr := []string{"", "", ""}
|
|
sb := Select("*").From("t")
|
|
ub := Update("t").Set("foo = 1")
|
|
db := DeleteFrom("t")
|
|
|
|
cond := NewCond()
|
|
whereClause := NewWhereClause().AddWhereExpr(
|
|
cond.Args,
|
|
emptyExpr...,
|
|
)
|
|
|
|
sb.AddWhereClause(whereClause)
|
|
ub.AddWhereClause(whereClause)
|
|
db.AddWhereClause(whereClause)
|
|
|
|
a.Equal(sb.String(), "SELECT * FROM t ")
|
|
a.Equal(ub.String(), "UPDATE t SET foo = 1 ")
|
|
a.Equal(db.String(), "DELETE FROM t ")
|
|
}
|
|
|
|
func TestWhereClauseGetFlavor(t *testing.T) {
|
|
a := assert.New(t)
|
|
wc := NewWhereClause()
|
|
wc.SetFlavor(PostgreSQL)
|
|
flavor := wc.Flavor()
|
|
a.Equal(PostgreSQL, flavor)
|
|
}
|
|
|
|
func TestWhereClauseCopyGetFlavor(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
wc := NewWhereClause()
|
|
wc.SetFlavor(PostgreSQL)
|
|
|
|
wcCopy := CopyWhereClause(wc)
|
|
flavor := wcCopy.Flavor()
|
|
a.Equal(PostgreSQL, flavor)
|
|
}
|