You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
3.3 KiB
182 lines
3.3 KiB
package exql
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
type innerJoinT struct {
|
|
Type string
|
|
Table string
|
|
On string
|
|
Using string
|
|
}
|
|
|
|
// Joins represents the union of different join conditions.
|
|
type Joins struct {
|
|
Conditions []Fragment
|
|
hash hash
|
|
}
|
|
|
|
var _ = Fragment(&Joins{})
|
|
|
|
// Hash returns a unique identifier for the struct.
|
|
func (j *Joins) Hash() string {
|
|
return j.hash.Hash(j)
|
|
}
|
|
|
|
// Compile transforms the Where into an equivalent SQL representation.
|
|
func (j *Joins) Compile(layout *Template) (compiled string, err error) {
|
|
if c, ok := layout.Read(j); ok {
|
|
return c, nil
|
|
}
|
|
|
|
l := len(j.Conditions)
|
|
|
|
chunks := make([]string, 0, l)
|
|
|
|
if l > 0 {
|
|
for i := 0; i < l; i++ {
|
|
chunk, err := j.Conditions[i].Compile(layout)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
chunks = append(chunks, chunk)
|
|
}
|
|
}
|
|
|
|
compiled = strings.Join(chunks, " ")
|
|
|
|
layout.Write(j, compiled)
|
|
|
|
return
|
|
}
|
|
|
|
// JoinConditions creates a Joins object.
|
|
func JoinConditions(joins ...*Join) *Joins {
|
|
fragments := make([]Fragment, len(joins))
|
|
for i := range fragments {
|
|
fragments[i] = joins[i]
|
|
}
|
|
return &Joins{Conditions: fragments}
|
|
}
|
|
|
|
// Join represents a generic JOIN statement.
|
|
type Join struct {
|
|
Type string
|
|
Table Fragment
|
|
On Fragment
|
|
Using Fragment
|
|
hash hash
|
|
}
|
|
|
|
var _ = Fragment(&Join{})
|
|
|
|
// Hash returns a unique identifier for the struct.
|
|
func (j *Join) Hash() string {
|
|
return j.hash.Hash(j)
|
|
}
|
|
|
|
// Compile transforms the Join into its equivalent SQL representation.
|
|
func (j *Join) Compile(layout *Template) (compiled string, err error) {
|
|
if c, ok := layout.Read(j); ok {
|
|
return c, nil
|
|
}
|
|
|
|
if j.Table == nil {
|
|
return "", nil
|
|
}
|
|
|
|
table, err := j.Table.Compile(layout)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
on, err := layout.doCompile(j.On)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
using, err := layout.doCompile(j.Using)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
data := innerJoinT{
|
|
Type: j.Type,
|
|
Table: table,
|
|
On: on,
|
|
Using: using,
|
|
}
|
|
|
|
compiled = layout.MustCompile(layout.JoinLayout, data)
|
|
layout.Write(j, compiled)
|
|
return
|
|
}
|
|
|
|
// On represents JOIN conditions.
|
|
type On Where
|
|
|
|
var _ = Fragment(&On{})
|
|
|
|
// Hash returns a unique identifier.
|
|
func (o *On) Hash() string {
|
|
return o.hash.Hash(o)
|
|
}
|
|
|
|
// Compile transforms the On into an equivalent SQL representation.
|
|
func (o *On) Compile(layout *Template) (compiled string, err error) {
|
|
if c, ok := layout.Read(o); ok {
|
|
return c, nil
|
|
}
|
|
|
|
grouped, err := groupCondition(layout, o.Conditions, layout.MustCompile(layout.ClauseOperator, layout.AndKeyword))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if grouped != "" {
|
|
compiled = layout.MustCompile(layout.OnLayout, conds{grouped})
|
|
}
|
|
|
|
layout.Write(o, compiled)
|
|
return
|
|
}
|
|
|
|
// Using represents a USING function.
|
|
type Using Columns
|
|
|
|
var _ = Fragment(&Using{})
|
|
|
|
type usingT struct {
|
|
Columns string
|
|
}
|
|
|
|
// Hash returns a unique identifier.
|
|
func (u *Using) Hash() string {
|
|
return u.hash.Hash(u)
|
|
}
|
|
|
|
// Compile transforms the Using into an equivalent SQL representation.
|
|
func (u *Using) Compile(layout *Template) (compiled string, err error) {
|
|
if u == nil {
|
|
return "", nil
|
|
}
|
|
|
|
if c, ok := layout.Read(u); ok {
|
|
return c, nil
|
|
}
|
|
|
|
if len(u.Columns) > 0 {
|
|
c := Columns(*u)
|
|
columns, err := c.Compile(layout)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
data := usingT{Columns: columns}
|
|
compiled = layout.MustCompile(layout.UsingLayout, data)
|
|
}
|
|
|
|
layout.Write(u, compiled)
|
|
return
|
|
}
|