mirror of
https://github.com/ent/ent.git
synced 2026-05-22 09:31:45 +03:00
225 lines
6.8 KiB
Cheetah
225 lines
6.8 KiB
Cheetah
{{ define "where" }}
|
|
|
|
{{ template "header" $.Package }}
|
|
|
|
{{ template "import" $ }}
|
|
|
|
// ID filters vertices based on their identifier.
|
|
func ID(id {{ $.ID.Type }}) ent.Predicate {
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
{{- if $.ID.IsString }}id, _ := strconv.Atoi(id){{- end }}
|
|
s.Where(sql.EQ(s.C({{ $.ID.Constant }}), id))
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
t.HasID(id)
|
|
},
|
|
}
|
|
}
|
|
|
|
{{ range $_, $op := ops $.ID }}
|
|
{{ $r := "id" }}{{ if $op.Variadic }}{{ $r = "ids" }}{{ end }}
|
|
{{ $func := printf "ID%s" $op.Name }}
|
|
// {{ $func }} applies the {{ $op.Name }} predicate on the ID field.
|
|
func {{ $func }}({{ $r }} {{ if $op.Variadic }}...{{ end }}{{ $.ID.Type }}) ent.Predicate {
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
{{- if $op.Variadic }}
|
|
// if not arguments were provided, append the FALSE constants,
|
|
// since we can't apply "IN ()". This will make this predicate falsy.
|
|
if len({{ $r }}) == 0 {
|
|
s.Where(sql.False())
|
|
return
|
|
}
|
|
v := make([]interface{}, len({{ $r }}))
|
|
for i := range v {
|
|
{{ if $.ID.IsString }}v[i], _ = strconv.Atoi({{ $r }}[i]){{ else }}v[i] = {{ $r }}[i]{{ end }}
|
|
}
|
|
{{- else if $.ID.IsString }}
|
|
v, _ := strconv.Atoi({{ $r }})
|
|
{{- end }}
|
|
s.Where(sql.{{ $op.Name }}(s.C({{ $.ID.Constant }}), v{{ if $op.Variadic }}...{{ end }}))
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
{{- if $op.Variadic }}
|
|
v := make([]interface{}, len({{ $r }}))
|
|
for i := range v {
|
|
v[i] = {{ $r }}[i]
|
|
}
|
|
{{- end }}
|
|
t.HasID(p.{{ $op.Gremlin }}({{ if $op.Variadic }}v...{{ else }}{{ $r }}{{ end }}))
|
|
},
|
|
}
|
|
}
|
|
{{ end }}
|
|
|
|
{{ range $_, $f := $.Fields }}
|
|
{{ $func := pascal $f.Name }}
|
|
// {{ $func }} applies equality check predicate on the {{ quote $f.Name }} field. It's identical to {{ $func }}EQ.
|
|
func {{ $func }}(v {{ $f.Type }}) ent.Predicate {
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
s.Where(sql.EQ(s.C({{ $f.Constant }}), v))
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
t.Has(Label, {{ $f.Constant }}, p.EQ(v))
|
|
},
|
|
}
|
|
}
|
|
{{ end }}
|
|
|
|
{{ range $_, $f := $.Fields }}
|
|
{{ range $_, $op := (ops $f) }}
|
|
{{ $r := "v" }}{{ if $op.Variadic }}{{ $r = "vs" }}{{ end }}
|
|
{{ $func := print (pascal $f.Name) ($op.Name) }}
|
|
// {{ $func }} applies the {{ $op.Name }} predicate on the {{ quote $f.Name }} field.
|
|
func {{ $func }}({{ $r }} {{ if $op.Variadic }}...{{ end }}{{ $f.Type }}) ent.Predicate {
|
|
{{- if $op.Variadic }}
|
|
v := make([]interface{}, len({{ $r }}))
|
|
for i := range v {
|
|
v[i] = {{ $r }}[i]
|
|
}
|
|
{{- end }}
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
{{- if $op.Variadic }}
|
|
// if not arguments were provided, append the FALSE constants,
|
|
// since we can't apply "IN ()". This will make this predicate falsy.
|
|
if len({{ $r }}) == 0 {
|
|
s.Where(sql.False())
|
|
return
|
|
}
|
|
{{- end }}
|
|
s.Where(sql.{{ $op.Name }}(s.C({{ $f.Constant }}), v{{ if $op.Variadic }}...{{ end }}))
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
t.Has(Label, {{ $f.Constant }}, p.{{ $op.Gremlin }}(v{{ if $op.Variadic }}...{{ end }}))
|
|
},
|
|
}
|
|
}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{ range $_, $e := $.Edges }}
|
|
{{ $func := pascal $e.Name | printf "Has%s" }}
|
|
{{ $label := $e.Constant }}
|
|
{{ $direction := "Out" }}
|
|
{{ $inverse_direction := "In" }}
|
|
{{ if $e.IsInverse }}
|
|
{{ $direction = "In" }}
|
|
{{ $inverse_direction = "Out" }}
|
|
{{/* avoid circular dependecies */}}
|
|
{{ $label = $e.InverseConstant }}
|
|
{{ end }}
|
|
// {{ $func }} applies the HasEdge predicate on the {{ quote $e.Name }} edge.
|
|
func {{ $func }}() ent.Predicate {
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
{{- if $e.M2M }}
|
|
t1 := s.Table()
|
|
s.Where(
|
|
sql.In(
|
|
t1.C({{ $.ID.Constant }}),
|
|
sql.Select({{ $e.PKConstant }}[{{ if $e.IsInverse }}1{{ else }}0{{ end }}]).From(sql.Table({{ $e.TableConstant }})),
|
|
),
|
|
)
|
|
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
|
t1 := s.Table()
|
|
s.Where(sql.NotNull(t1.C({{ $e.ColumnConstant }})))
|
|
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
|
t1 := s.Table()
|
|
s.Where(
|
|
sql.In(
|
|
t1.C({{ $.ID.Constant }}),
|
|
sql.Select({{ $e.ColumnConstant }}).
|
|
From(sql.Table({{ $e.TableConstant }})).
|
|
Where(sql.NotNull({{ $e.ColumnConstant }})),
|
|
),
|
|
)
|
|
{{- end }}
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
{{- /* if it's an edge with self-reference, take the two vertices */}}
|
|
{{- if $e.SelfRef }}
|
|
t.Both({{ $label }})
|
|
{{- else }}
|
|
t.{{ $direction }}E({{ $label }}).{{ $direction }}V()
|
|
{{- end }}
|
|
},
|
|
}
|
|
}
|
|
{{ $func = printf "%sWith" $func }}
|
|
// {{ $func }} applies the HasEdge predicate on the {{ quote $e.Name }} edge with a given conditions (other predicates).
|
|
func {{ $func }}(preds ...ent.Predicate) ent.Predicate {
|
|
return ent.Predicate{
|
|
SQL: func(s *sql.Selector) {
|
|
{{- if $e.M2M }}
|
|
{{ $i := 1 }}{{ $j := 0 }}{{- if $e.IsInverse }}{{ $i = 0 }}{{ $j = 1 }}{{ end -}}
|
|
t1 := s.Table()
|
|
t2 := sql.Table(
|
|
{{- if ne $.Table $e.Type.Table -}}
|
|
{{ $e.InverseTableConstant }}
|
|
{{- else -}}
|
|
Table
|
|
{{- end -}}
|
|
)
|
|
t3 := sql.Table({{ $e.TableConstant }})
|
|
t4 := sql.Select(t3.C({{ $e.PKConstant }}[{{ $j }}])).
|
|
From(t3).
|
|
Join(t2).
|
|
On(t3.C({{ $e.PKConstant }}[{{ $i }}]), t2.C({{ $e.Type.ID.Constant }}))
|
|
t5 := sql.Select().From(t2)
|
|
for _, p := range preds {
|
|
p.SQL(t5)
|
|
}
|
|
t4.FromSelect(t5)
|
|
s.Where(sql.In(t1.C({{ $.ID.Constant }}), t4))
|
|
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
|
t1 := s.Table()
|
|
t2 := sql.Select({{ $e.Type.ID.Constant }}).From(sql.Table(
|
|
{{- if ne $.Table $e.Type.Table -}}
|
|
{{ $e.InverseTableConstant }}
|
|
{{- else -}}
|
|
{{ $e.TableConstant }}
|
|
{{- end -}}
|
|
))
|
|
for _, p := range preds {
|
|
p.SQL(t2)
|
|
}
|
|
s.Where(sql.In(t1.C({{ $e.ColumnConstant }}), t2))
|
|
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
|
t1 := s.Table()
|
|
t2 := sql.Select({{ $e.ColumnConstant }}).From(sql.Table({{ $e.TableConstant }}))
|
|
for _, p := range preds {
|
|
p.SQL(t2)
|
|
}
|
|
s.Where(sql.In(t1.C({{ $.ID.Constant }}), t2))
|
|
{{- end }}
|
|
},
|
|
Gremlin: func(t *dsl.Traversal) {
|
|
{{- if $e.SelfRef }}{{/* selfref means it should be true in one of the directions */}}
|
|
in, out := __.InV(), __.OutV()
|
|
for _, p := range preds {
|
|
p.Gremlin(in)
|
|
p.Gremlin(out)
|
|
}
|
|
t.Where(
|
|
__.Or(
|
|
__.OutE({{ $label }}).Where(in),
|
|
__.InE({{ $label }}).Where(out),
|
|
),
|
|
)
|
|
{{- else }}
|
|
tr := __.{{ $inverse_direction }}V()
|
|
for _, p := range preds {
|
|
p.Gremlin(tr)
|
|
}
|
|
t.{{ $direction }}E({{ $label }}).Where(tr).{{ $direction }}V()
|
|
{{- end }}
|
|
},
|
|
}
|
|
}
|
|
{{ end }}
|
|
|
|
{{ end }}
|