gorm/clause/with.go
2022-03-16 19:54:12 +08:00

89 lines
1.7 KiB
Go

package clause
import "strings"
// With Common Table Expressions
type With struct {
Recursive bool
Exprs []Expression
Expression Expression
}
// Name with clause name
func (with With) Name() string {
return "WITH"
}
// Build build with clause
func (with With) Build(builder Builder) {
if with.Expression != nil {
with.Expression.Build(builder)
return
}
if len(with.Exprs) == 0 {
return
}
if with.Recursive {
builder.WriteString("RECURSIVE ")
}
for idx, expr := range with.Exprs {
if idx != 0 {
builder.WriteByte(',')
}
expr.Build(builder)
}
}
// MergeClause merge with clauses
func (with With) MergeClause(clause *Clause) {
if w, ok := clause.Expression.(With); ok {
if !with.Recursive {
with.Recursive = w.Recursive
}
if w.Expression != nil {
with.Expression = w.Expression
with.Exprs = nil
} else if with.Expression == nil {
exprs := make([]Expression, len(w.Exprs)+len(with.Exprs))
copy(exprs, w.Exprs)
copy(exprs[len(w.Exprs):], with.Exprs)
with.Exprs = exprs
}
}
clause.Expression = with
}
// WithExpression with expression
type WithExpression struct {
Name string
Columns []string
Expr Expression
}
func (with WithExpression) Build(builder Builder) {
if with.Name == "" || with.Expr == nil {
return
}
builder.WriteQuoted(with.Name)
if len(with.Columns) > 0 {
builder.WriteByte(' ')
builder.WriteByte('(')
for idx, column := range with.Columns {
if idx != 0 {
builder.WriteByte(',')
}
column = strings.TrimSpace(column)
builder.WriteQuoted(column)
}
builder.WriteByte(')')
}
builder.WriteString(" AS ")
builder.WriteByte('(')
with.Expr.Build(builder)
builder.WriteByte(')')
}