-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrange.go
117 lines (106 loc) · 2.46 KB
/
range.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
package qs
import (
"fmt"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/search/query"
"strconv"
"time"
)
// helper stuff for setting up range queries
// returns time, precision
// TODO: support other precisions? "YYYY-MM", "YYYY-MM-DDThh:mm:ss" etc?
func parseTime(in string, loc *time.Location) (time.Time, string) {
t, err := time.ParseInLocation("2006-01-02", in, loc)
if err != nil {
return time.Time{}, ""
}
return t, "day"
}
type rangeParams struct {
min, max *string
minInclusive, maxInclusive *bool
// need location for parsing times
loc *time.Location
}
func newRangeParams(minVal, maxVal string, minInc, maxInc bool, loc *time.Location) *rangeParams {
rp := &rangeParams{}
if minVal != "" {
rp.min = &minVal
rp.minInclusive = &minInc
}
if maxVal != "" {
rp.max = &maxVal
rp.maxInclusive = &maxInc
}
if loc == nil {
loc = time.UTC
}
rp.loc = loc
return rp
}
func (rp *rangeParams) numericArgs() (bool, *float64, *float64) {
var f1, f2 *float64
if rp.min != nil {
f, err := strconv.ParseFloat(*rp.min, 64)
if err != nil {
return false, nil, nil
}
f1 = &f
}
if rp.max != nil {
f, err := strconv.ParseFloat(*rp.max, 64)
if err != nil {
return false, nil, nil
}
f2 = &f
}
return true, f1, f2
}
func (rp *rangeParams) dateArgs() (bool, time.Time, time.Time) {
var truthy bool = true
var falsey bool = false
var t1, t2 time.Time
var prec string
if rp.min != nil {
t1, prec = parseTime(*rp.min, rp.loc)
switch prec {
case "day":
if !*rp.minInclusive {
// add 1 day and make inclusive
t1 = t1.AddDate(0, 0, 1)
rp.minInclusive = &truthy
}
default:
return false, t1, t2
}
}
if rp.max != nil {
t2, prec = parseTime(*rp.max, rp.loc)
switch prec {
case "day":
if *rp.maxInclusive {
// add 1 day and change to exclusive
t2 = t2.AddDate(0, 0, 1)
rp.maxInclusive = &falsey
}
default:
return false, t1, t2
}
}
return true, t1, t2
}
// try and build a query from the given params
func (rp *rangeParams) generate() (query.Query, error) {
if rp.min == nil && rp.max == nil {
return nil, fmt.Errorf("empty range")
}
isNumeric, f1, f2 := rp.numericArgs()
if isNumeric {
return bleve.NewNumericRangeInclusiveQuery(f1, f2, rp.minInclusive, rp.maxInclusive), nil
}
isDate, t1, t2 := rp.dateArgs()
if isDate {
return bleve.NewDateRangeInclusiveQuery(t1, t2, rp.minInclusive, rp.maxInclusive), nil
}
return nil, fmt.Errorf("not numeric")
}