
* Implement Generics API * Add more generics tests * Add more tests and Take method * use delayed‑ops pipeline for generics API * fix generics tests for mysql * Support SubQuery for Generics * Add clause.JoinTable helper method * Fix golangci-lint error * Complete the design and implementation of generic version Join * improve generics version Joins support * allow configuring select/omit columns for joins via subqueries * finish generic version Preload * handle error of generics Joins/Preload * fix tests * Add LimitPerRecord for generic version Preload * fix tests for mysql 5.7 * test for nested generic version Join/Preload * Add WithResult support for generics API * test reuse generics db conditions * fix data race * remove ExampleLRU test * Add default transaction timeout support * fix test
80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
package clause
|
|
|
|
import "gorm.io/gorm/utils"
|
|
|
|
type JoinType string
|
|
|
|
const (
|
|
CrossJoin JoinType = "CROSS"
|
|
InnerJoin JoinType = "INNER"
|
|
LeftJoin JoinType = "LEFT"
|
|
RightJoin JoinType = "RIGHT"
|
|
)
|
|
|
|
type JoinTarget struct {
|
|
Type JoinType
|
|
Association string
|
|
Subquery Expression
|
|
Table string
|
|
}
|
|
|
|
func Has(name string) JoinTarget {
|
|
return JoinTarget{Type: InnerJoin, Association: name}
|
|
}
|
|
|
|
func (jt JoinType) Association(name string) JoinTarget {
|
|
return JoinTarget{Type: jt, Association: name}
|
|
}
|
|
|
|
func (jt JoinType) AssociationFrom(name string, subquery Expression) JoinTarget {
|
|
return JoinTarget{Type: jt, Association: name, Subquery: subquery}
|
|
}
|
|
|
|
func (jt JoinTarget) As(name string) JoinTarget {
|
|
jt.Table = name
|
|
return jt
|
|
}
|
|
|
|
// Join clause for from
|
|
type Join struct {
|
|
Type JoinType
|
|
Table Table
|
|
ON Where
|
|
Using []string
|
|
Expression Expression
|
|
}
|
|
|
|
func JoinTable(names ...string) Table {
|
|
return Table{
|
|
Name: utils.JoinNestedRelationNames(names),
|
|
}
|
|
}
|
|
|
|
func (join Join) Build(builder Builder) {
|
|
if join.Expression != nil {
|
|
join.Expression.Build(builder)
|
|
} else {
|
|
if join.Type != "" {
|
|
builder.WriteString(string(join.Type))
|
|
builder.WriteByte(' ')
|
|
}
|
|
|
|
builder.WriteString("JOIN ")
|
|
builder.WriteQuoted(join.Table)
|
|
|
|
if len(join.ON.Exprs) > 0 {
|
|
builder.WriteString(" ON ")
|
|
join.ON.Build(builder)
|
|
} else if len(join.Using) > 0 {
|
|
builder.WriteString(" USING (")
|
|
for idx, c := range join.Using {
|
|
if idx > 0 {
|
|
builder.WriteByte(',')
|
|
}
|
|
builder.WriteQuoted(c)
|
|
}
|
|
builder.WriteByte(')')
|
|
}
|
|
}
|
|
}
|