forked from gocassa/gocassa
-
Notifications
You must be signed in to change notification settings - Fork 5
/
relation.go
140 lines (122 loc) · 2.37 KB
/
relation.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package gocassa
import (
"strings"
"time"
)
const (
equality = iota
in
greaterThan
greaterThanOrEquals
lesserThan
lesserThanOrEquals
)
type Relation struct {
op int
key string
terms []interface{}
}
func (r Relation) cql() (string, []interface{}) {
ret := ""
key := strings.ToLower(r.key)
switch r.op {
case equality:
ret = key + " = ?"
case in:
return key + " IN ?", r.terms
case greaterThan:
ret = key + " > ?"
case greaterThanOrEquals:
ret = key + " >= ?"
case lesserThan:
ret = key + " < ?"
case lesserThanOrEquals:
ret = key + " <= ?"
}
return ret, r.terms
}
func anyEquals(value interface{}, terms []interface{}) bool {
primVal := convertToPrimitive(value)
for _, term := range terms {
if primVal == convertToPrimitive(term) {
return true
}
}
return false
}
func convertToPrimitive(i interface{}) interface{} {
switch v := i.(type) {
case time.Time:
return v.UnixNano()
case time.Duration:
return v.Nanoseconds()
default:
return i
}
}
func (r Relation) accept(i interface{}) bool {
var result bool
var err error
if r.op == equality || r.op == in {
return anyEquals(i, r.terms)
}
a, b := convertToPrimitive(i), convertToPrimitive(r.terms[0])
switch r.op {
case greaterThan:
result, err = builtinGreaterThan(a, b)
case greaterThanOrEquals:
result, err = builtinGreaterThan(a, b)
result = result || a == b
case lesserThanOrEquals:
result, err = builtinLessThan(a, b)
result = result || a == b
case lesserThan:
result, err = builtinLessThan(a, b)
}
return err == nil && result
}
func toI(i interface{}) []interface{} {
return []interface{}{i}
}
func Eq(key string, term interface{}) Relation {
return Relation{
op: equality,
key: key,
terms: toI(term),
}
}
func In(key string, terms ...interface{}) Relation {
return Relation{
op: in,
key: key,
terms: terms,
}
}
func GT(key string, term interface{}) Relation {
return Relation{
op: greaterThan,
key: key,
terms: toI(term),
}
}
func GTE(key string, term interface{}) Relation {
return Relation{
op: greaterThanOrEquals,
key: key,
terms: toI(term),
}
}
func LT(key string, term interface{}) Relation {
return Relation{
op: lesserThan,
key: key,
terms: toI(term),
}
}
func LTE(key string, term interface{}) Relation {
return Relation{
op: lesserThanOrEquals,
key: key,
terms: toI(term),
}
}