/
query2query.go
89 lines (84 loc) · 2.32 KB
/
query2query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package dalgo2datastore
import (
"cloud.google.com/go/datastore"
"fmt"
"github.com/dal-go/dalgo/dal"
)
func dalQuery2datastoreQuery(query dal.Query) (q *datastore.Query, err error) {
q = datastore.NewQuery(query.From().Name)
if limit := query.Limit(); limit > 0 {
q = q.Limit(limit)
}
if offset := query.Offset(); offset > 0 {
q.Offset(offset)
}
if where := query.Where(); where != nil {
if q, err = applyWhere(query.Where(), q); err != nil {
return q, err
}
}
if orderBy := query.OrderBy(); len(orderBy) > 0 {
if q, err = applyOrderBy(orderBy, q); err != nil {
return q, err
}
}
return q, nil
}
func applyOrderBy(orderBy []dal.OrderExpression, q *datastore.Query) (*datastore.Query, error) {
for _, o := range orderBy {
expression := o.Expression().String()
if o.Descending() {
expression = "-" + expression
}
q = q.Order(expression)
}
return q, nil
}
func applyWhere(where dal.Condition, q *datastore.Query) (*datastore.Query, error) {
if where == nil {
return q, nil
}
var applyComparison = func(comparison dal.Comparison) (*datastore.Query, error) {
switch left := comparison.Left.(type) {
case dal.FieldRef:
switch right := comparison.Right.(type) {
case dal.Constant:
var operator string
switch comparison.Operator {
case dal.Equal:
operator = "="
default:
operator = string(comparison.Operator)
}
q = q.FilterField(left.Name, operator, right.Value)
default:
return q, fmt.Errorf("only FieldRef are supported as left operand, got: %T", right)
}
default:
return q, fmt.Errorf("only FieldRef are supported as left operand, got: %T", left)
}
return q, nil
}
switch cond := where.(type) {
case dal.GroupCondition:
if cond.Operator() != dal.And {
return q, fmt.Errorf("only AND operator is supported in group condition, got: %v", cond.Operator())
}
for _, c := range cond.Conditions() {
switch c := c.(type) {
case dal.Comparison:
var err error
if q, err = applyComparison(c); err != nil {
return q, err
}
default:
return q, fmt.Errorf("only comparisons are supported in group condition, got: %T", c)
}
}
return q, nil
case dal.Comparison:
return applyComparison(cond)
default:
return q, fmt.Errorf("only comparison or group conditions are supported at root level of where clause, got: %T", cond)
}
}