2020-01-29 14:22:44 +03:00
|
|
|
package clause
|
|
|
|
|
2020-01-30 10:14:48 +03:00
|
|
|
// Clause
|
|
|
|
type Clause struct {
|
|
|
|
Name string // WHERE
|
|
|
|
Priority float64
|
|
|
|
BeforeExpressions []Expression
|
|
|
|
AfterNameExpressions []Expression
|
|
|
|
AfterExpressions []Expression
|
|
|
|
Expression Expression
|
|
|
|
Builder ClauseBuilder
|
|
|
|
}
|
|
|
|
|
|
|
|
// ClauseBuilder clause builder, allows to custmize how to build clause
|
|
|
|
type ClauseBuilder interface {
|
|
|
|
Build(Clause, Builder)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build build clause
|
|
|
|
func (c Clause) Build(builder Builder) {
|
|
|
|
if c.Builder != nil {
|
|
|
|
c.Builder.Build(c, builder)
|
|
|
|
} else {
|
|
|
|
builders := c.BeforeExpressions
|
|
|
|
if c.Name != "" {
|
|
|
|
builders = append(builders, Expr{c.Name})
|
|
|
|
}
|
|
|
|
|
|
|
|
builders = append(builders, c.AfterNameExpressions...)
|
|
|
|
if c.Expression != nil {
|
|
|
|
builders = append(builders, c.Expression)
|
|
|
|
}
|
|
|
|
|
|
|
|
for idx, expr := range append(builders, c.AfterExpressions...) {
|
|
|
|
if idx != 0 {
|
|
|
|
builder.WriteByte(' ')
|
|
|
|
}
|
|
|
|
expr.Build(builder)
|
|
|
|
}
|
|
|
|
}
|
2020-01-29 14:22:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Interface clause interface
|
|
|
|
type Interface interface {
|
|
|
|
Name() string
|
2020-01-30 10:14:48 +03:00
|
|
|
Build(Builder)
|
|
|
|
MergeExpression(Expression)
|
2020-01-29 22:03:06 +03:00
|
|
|
}
|
|
|
|
|
2020-01-30 10:14:48 +03:00
|
|
|
type OverrideNameInterface interface {
|
|
|
|
OverrideName() string
|
2020-01-29 14:22:44 +03:00
|
|
|
}
|
|
|
|
|
2020-01-30 10:14:48 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Predefined Clauses
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2020-01-29 14:22:44 +03:00
|
|
|
|
|
|
|
// Where where clause
|
|
|
|
type Where struct {
|
2020-01-30 10:14:48 +03:00
|
|
|
AndConditions AddConditions
|
|
|
|
ORConditions []ORConditions
|
2020-02-01 07:46:52 +03:00
|
|
|
builders []Expression
|
2020-01-30 10:14:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (where Where) Name() string {
|
|
|
|
return "WHERE"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (where Where) Build(builder Builder) {
|
|
|
|
var withConditions bool
|
|
|
|
|
|
|
|
if len(where.AndConditions) > 0 {
|
|
|
|
withConditions = true
|
|
|
|
where.AndConditions.Build(builder)
|
|
|
|
}
|
|
|
|
|
2020-02-01 07:46:52 +03:00
|
|
|
if len(where.builders) > 0 {
|
|
|
|
for _, b := range where.builders {
|
2020-01-30 10:14:48 +03:00
|
|
|
if withConditions {
|
|
|
|
builder.Write(" AND ")
|
|
|
|
}
|
|
|
|
withConditions = true
|
|
|
|
b.Build(builder)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var singleOrConditions []ORConditions
|
|
|
|
for _, or := range where.ORConditions {
|
|
|
|
if len(or) == 1 {
|
|
|
|
if withConditions {
|
|
|
|
builder.Write(" OR ")
|
|
|
|
or.Build(builder)
|
|
|
|
} else {
|
|
|
|
singleOrConditions = append(singleOrConditions, or)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
withConditions = true
|
|
|
|
builder.Write(" AND (")
|
|
|
|
or.Build(builder)
|
|
|
|
builder.WriteByte(')')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, or := range singleOrConditions {
|
|
|
|
if withConditions {
|
|
|
|
builder.Write(" AND ")
|
|
|
|
or.Build(builder)
|
|
|
|
} else {
|
|
|
|
withConditions = true
|
|
|
|
or.Build(builder)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !withConditions {
|
|
|
|
builder.Write(" FALSE")
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (where Where) MergeExpression(expr Expression) {
|
|
|
|
if w, ok := expr.(Where); ok {
|
|
|
|
where.AndConditions = append(where.AndConditions, w.AndConditions...)
|
|
|
|
where.ORConditions = append(where.ORConditions, w.ORConditions...)
|
2020-02-01 07:46:52 +03:00
|
|
|
where.builders = append(where.builders, w.builders...)
|
2020-01-30 10:14:48 +03:00
|
|
|
} else {
|
2020-02-01 07:46:52 +03:00
|
|
|
where.builders = append(where.builders, expr)
|
2020-01-30 10:14:48 +03:00
|
|
|
}
|
2020-01-29 14:22:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Select select attrs when querying, updating, creating
|
|
|
|
type Select struct {
|
|
|
|
Omit bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// Join join clause
|
|
|
|
type Join struct {
|
2020-02-01 07:46:52 +03:00
|
|
|
Table string
|
|
|
|
Type string // left join books on
|
|
|
|
ON []Expression
|
|
|
|
builders []Expression
|
|
|
|
}
|
|
|
|
|
|
|
|
func (join Join) Build(builder Builder) {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
func (join Join) MergeExpression(expr Expression) {
|
|
|
|
if j, ok := expr.(Join); ok {
|
|
|
|
join.builders = append(join.builders, j.builders...)
|
|
|
|
} else {
|
|
|
|
join.builders = append(join.builders, expr)
|
|
|
|
}
|
2020-01-29 14:22:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// GroupBy group by clause
|
|
|
|
type GroupBy struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Having having clause
|
|
|
|
type Having struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Order order clause
|
|
|
|
type Order struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit limit clause
|
|
|
|
type Limit struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Offset offset clause
|
|
|
|
type Offset struct {
|
|
|
|
}
|