2020-02-02 09:40:44 +03:00
|
|
|
package clause
|
|
|
|
|
|
|
|
// From from clause
|
|
|
|
type From struct {
|
|
|
|
Tables []Table
|
2020-02-07 18:45:35 +03:00
|
|
|
Joins []Join
|
|
|
|
}
|
|
|
|
|
|
|
|
type JoinType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
CrossJoin JoinType = "CROSS"
|
|
|
|
InnerJoin = "INNER"
|
|
|
|
LeftJoin = "LEFT"
|
|
|
|
RightJoin = "RIGHT"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Join join clause for from
|
|
|
|
type Join struct {
|
|
|
|
Type JoinType
|
|
|
|
Table Table
|
|
|
|
ON Where
|
|
|
|
Using []string
|
2020-02-02 09:40:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Name from clause name
|
2020-02-07 18:45:35 +03:00
|
|
|
func (from From) Name() string {
|
2020-02-02 09:40:44 +03:00
|
|
|
return "FROM"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build build from clause
|
|
|
|
func (from From) Build(builder Builder) {
|
2020-02-04 04:51:19 +03:00
|
|
|
if len(from.Tables) > 0 {
|
|
|
|
for idx, table := range from.Tables {
|
|
|
|
if idx > 0 {
|
|
|
|
builder.WriteByte(',')
|
|
|
|
}
|
2020-02-02 09:40:44 +03:00
|
|
|
|
2020-02-04 04:51:19 +03:00
|
|
|
builder.WriteQuoted(table)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
builder.WriteQuoted(currentTable)
|
2020-02-02 09:40:44 +03:00
|
|
|
}
|
2020-02-07 18:45:35 +03:00
|
|
|
|
|
|
|
for _, join := range from.Joins {
|
|
|
|
builder.WriteByte(' ')
|
|
|
|
join.Build(builder)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (join Join) Build(builder Builder) {
|
|
|
|
if join.Type != "" {
|
2020-03-09 12:07:00 +03:00
|
|
|
builder.WriteString(string(join.Type))
|
2020-02-07 18:45:35 +03:00
|
|
|
builder.WriteByte(' ')
|
|
|
|
}
|
|
|
|
|
2020-03-09 12:07:00 +03:00
|
|
|
builder.WriteString("JOIN ")
|
2020-02-07 18:45:35 +03:00
|
|
|
builder.WriteQuoted(join.Table)
|
|
|
|
|
|
|
|
if len(join.ON.Exprs) > 0 {
|
2020-03-09 12:07:00 +03:00
|
|
|
builder.WriteString(" ON ")
|
2020-02-07 18:45:35 +03:00
|
|
|
join.ON.Build(builder)
|
|
|
|
} else if len(join.Using) > 0 {
|
2020-03-09 12:07:00 +03:00
|
|
|
builder.WriteString(" USING (")
|
2020-02-07 18:45:35 +03:00
|
|
|
for idx, c := range join.Using {
|
|
|
|
if idx > 0 {
|
|
|
|
builder.WriteByte(',')
|
|
|
|
}
|
|
|
|
builder.WriteQuoted(c)
|
|
|
|
}
|
|
|
|
builder.WriteByte(')')
|
|
|
|
}
|
2020-02-02 09:40:44 +03:00
|
|
|
}
|
2020-02-04 03:56:15 +03:00
|
|
|
|
2020-02-07 18:45:35 +03:00
|
|
|
// MergeClause merge from clause
|
|
|
|
func (from From) MergeClause(clause *Clause) {
|
|
|
|
if v, ok := clause.Expression.(From); ok {
|
2020-02-04 03:56:15 +03:00
|
|
|
from.Tables = append(v.Tables, from.Tables...)
|
2020-02-07 18:45:35 +03:00
|
|
|
from.Joins = append(v.Joins, from.Joins...)
|
2020-02-04 03:56:15 +03:00
|
|
|
}
|
2020-02-07 18:45:35 +03:00
|
|
|
clause.Expression = from
|
2020-02-04 03:56:15 +03:00
|
|
|
}
|