-
Notifications
You must be signed in to change notification settings - Fork 3
/
parse.go
113 lines (91 loc) · 2.64 KB
/
parse.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
package qbcli
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"github.com/QuickBase/quickbase-cli/qbclient"
"github.com/cpliakas/cliutil"
)
var reSortBy, reGroupBy *regexp.Regexp
// ParseQuery parses queries. It also detcts and transforms simple queries into
// Quick Base query syntax.
func ParseQuery(q string) string {
// Returns as-is if using Quick Base query syntax.
if strings.HasPrefix(q, "{") || strings.HasPrefix(q, "(") {
return q
}
// Parse the key/value pairs.
m := cliutil.ParseKeyValue(q)
clauses := make([]string, len(m))
// Convert simple syntax into Quick Base query syntax.
i := 0
for k, v := range m {
if v == "" {
clauses[i] = fmt.Sprintf("{3.EX.%q}", k)
} else {
clauses[i] = fmt.Sprintf("{%q.EX.%q}", k, v)
}
i++
}
// Join all clauses by AND.
return strings.Join(clauses, " AND ")
}
// ParseSortBy parses the sortBy clause.
func ParseSortBy(s string) (sortBy []*qbclient.QueryRecordsInputSortBy, err error) {
clauses := strings.Split(s, ",")
sortBy = make([]*qbclient.QueryRecordsInputSortBy, len(clauses))
for i, clause := range clauses {
matches := reSortBy.FindAllStringSubmatch(clause, -1)
// Return an error if any clause cannot be parsed.
if len(matches) == 0 {
err = errors.New("sort by clause not valid")
return
}
// Convert the field ID to an integer. Panic on any errors, because the
// regex should only parse integers. Signifies logic error in app.
fid, err := strconv.Atoi(matches[0][1])
if err != nil {
panic(err)
}
// Default to ASC.
order := matches[0][2]
if order == "" {
order = qbclient.SortByASC
}
sortBy[i] = &qbclient.QueryRecordsInputSortBy{
FieldID: fid,
Order: order,
}
}
return
}
// ParseGroupBy parses the groupBy clause.
func ParseGroupBy(s string) (groupBy []*qbclient.QueryRecordsInputGroupBy, err error) {
clauses := strings.Split(s, ",")
groupBy = make([]*qbclient.QueryRecordsInputGroupBy, len(clauses))
for i, clause := range clauses {
matches := reGroupBy.FindAllStringSubmatch(clause, -1)
// Return an error if any clause cannot be parsed.
if len(matches) == 0 {
err = errors.New("group by clause not valid")
return
}
// Convert the field ID to an integer. Panic on any errors, because the
// regex should only parse integers. Signifies logic error in app.
fid, err := strconv.Atoi(matches[0][1])
if err != nil {
panic(err)
}
groupBy[i] = &qbclient.QueryRecordsInputGroupBy{
FieldID: fid,
Grouping: matches[0][2],
}
}
return
}
func init() {
reSortBy = regexp.MustCompile(`^\s*(\d+)(?:\s+(ASC|DESC)?\s*)?$`)
reGroupBy = regexp.MustCompile(`^\s*(\d+)(?:\s+([-A-Za-z0-9_]+)?\s*)?$`)
}