mirror of
https://github.com/hanzoai/sqlbuilder.git
synced 2026-10-01 00:37:42 +00:00
141 lines
3.4 KiB
Go
141 lines
3.4 KiB
Go
// Copyright 2018 Huan Du. All rights reserved.
|
|
// Licensed under the MIT license that can be found in the LICENSE file.
|
|
|
|
package sqlbuilder
|
|
|
|
// WhereClause is a Builder for WHERE clause.
|
|
// All builders which support `WHERE` clause have an anonymous `WhereClause` field,
|
|
// in which the conditions are stored.
|
|
//
|
|
// WhereClause can be shared among multiple builders.
|
|
// However, it is not thread-safe.
|
|
type WhereClause struct {
|
|
flavor Flavor
|
|
clauses []clause
|
|
}
|
|
|
|
var _ Builder = new(WhereClause)
|
|
|
|
// NewWhereClause creates a new WhereClause.
|
|
func NewWhereClause() *WhereClause {
|
|
return &WhereClause{}
|
|
}
|
|
|
|
// CopyWhereClause creates a copy of the whereClause.
|
|
func CopyWhereClause(whereClause *WhereClause) *WhereClause {
|
|
clauses := make([]clause, len(whereClause.clauses))
|
|
copy(clauses, whereClause.clauses)
|
|
|
|
return &WhereClause{
|
|
flavor: whereClause.flavor,
|
|
clauses: clauses,
|
|
}
|
|
}
|
|
|
|
type clause struct {
|
|
args *Args
|
|
andExprs []string
|
|
}
|
|
|
|
func (c *clause) Build(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
|
|
exprs := filterEmptyStrings(c.andExprs)
|
|
|
|
if len(exprs) == 0 {
|
|
return
|
|
}
|
|
|
|
buf := newStringBuilder()
|
|
buf.WriteStrings(exprs, " AND ")
|
|
sql, args = c.args.CompileWithFlavor(buf.String(), flavor, initialArg...)
|
|
return
|
|
}
|
|
|
|
// whereClauseProxy is a proxy for WhereClause.
|
|
// It's useful when the WhereClause in a build can be changed.
|
|
type whereClauseProxy struct {
|
|
*WhereClause
|
|
}
|
|
|
|
var _ Builder = new(whereClauseProxy)
|
|
|
|
// BuildWithFlavor builds a WHERE clause with the specified flavor and initial arguments.
|
|
func (wc *WhereClause) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
|
|
if wc == nil || len(wc.clauses) == 0 {
|
|
return "", nil
|
|
}
|
|
|
|
buf := newStringBuilder()
|
|
buf.WriteLeadingString("WHERE ")
|
|
|
|
sql, args = wc.clauses[0].Build(flavor, initialArg...)
|
|
buf.WriteString(sql)
|
|
|
|
for _, clause := range wc.clauses[1:] {
|
|
buf.WriteString(" AND ")
|
|
sql, args = clause.Build(flavor, args...)
|
|
buf.WriteString(sql)
|
|
}
|
|
|
|
return buf.String(), args
|
|
}
|
|
|
|
// Build returns compiled WHERE clause string and args.
|
|
func (wc *WhereClause) Build() (sql string, args []interface{}) {
|
|
return wc.BuildWithFlavor(wc.flavor)
|
|
}
|
|
|
|
// SetFlavor sets the flavor of compiled sql.
|
|
// When the WhereClause belongs to a builder, the flavor of the builder will be used when building SQL.
|
|
func (wc *WhereClause) SetFlavor(flavor Flavor) (old Flavor) {
|
|
old = wc.flavor
|
|
wc.flavor = flavor
|
|
return
|
|
}
|
|
|
|
// Flavor returns flavor of clause
|
|
func (wc *WhereClause) Flavor() Flavor {
|
|
return wc.flavor
|
|
}
|
|
|
|
// AddWhereExpr adds an AND expression to WHERE clause with the specified arguments.
|
|
func (wc *WhereClause) AddWhereExpr(args *Args, andExpr ...string) *WhereClause {
|
|
if len(andExpr) == 0 {
|
|
return wc
|
|
}
|
|
|
|
andExprsBytesLen := estimateStringsBytes(andExpr)
|
|
|
|
if andExprsBytesLen == 0 {
|
|
return wc
|
|
}
|
|
|
|
// Merge with last clause if possible.
|
|
if len(wc.clauses) > 0 {
|
|
lastClause := &wc.clauses[len(wc.clauses)-1]
|
|
|
|
if lastClause.args == args {
|
|
lastClause.andExprs = append(lastClause.andExprs, andExpr...)
|
|
return wc
|
|
}
|
|
}
|
|
|
|
wc.clauses = append(wc.clauses, clause{
|
|
args: args,
|
|
andExprs: andExpr,
|
|
})
|
|
return wc
|
|
}
|
|
|
|
// AddWhereClause adds all clauses in the whereClause to the wc.
|
|
func (wc *WhereClause) AddWhereClause(whereClause *WhereClause) *WhereClause {
|
|
if wc == nil {
|
|
return nil
|
|
}
|
|
if whereClause == nil {
|
|
return wc
|
|
}
|
|
|
|
wc.clauses = append(wc.clauses, whereClause.clauses...)
|
|
return wc
|
|
}
|