-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
search_parse.go
135 lines (116 loc) · 3.22 KB
/
search_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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package gofindit
import (
"encoding/json"
"errors"
"net/url"
"strconv"
"strings"
)
// Take full raw query string and parse it into a SearchQuery struct
// Field types are a flat structure of the field and type of field
func StringToSearchQuery(input string) (*SearchQuery, error) {
fields := make([]SearchQueryField, 0)
var limit, skip uint64
var sort string
// If the input doesnt have an = sign then we know its not a valid query
if !strings.Contains(input, "=") {
return nil, errors.New("invalid input format")
}
// Parse the input string as a URL-encoded string of parameters
params, err := url.ParseQuery(input)
if err != nil {
return nil, errors.New("invalid input format")
}
// Check if the "limit" parameter is present
if limitValues, ok := params["limit"]; ok {
if len(limitValues) > 0 {
limit, err = strconv.ParseUint(limitValues[0], 10, 64)
if err != nil {
return nil, errors.New("invalid value for limit parameter")
}
}
}
// Check if the "skip" parameter is present
if skipValues, ok := params["skip"]; ok {
if len(skipValues) > 0 {
skip, err = strconv.ParseUint(skipValues[0], 10, 64)
if err != nil {
return nil, errors.New("invalid value for skip parameter")
}
}
}
// Check if the "sort" parameter is present
if sortValues, ok := params["sort"]; ok {
if len(sortValues) > 0 {
sort = sortValues[0]
}
}
// Iterate over the map of parameters
for fieldName, values := range params {
if fieldName == "limit" || fieldName == "skip" || fieldName == "sort" {
// Skip special parameters
continue
}
if len(values) == 0 {
continue
}
searchType := ""
fieldValue := values[0] // Get the first value for the field
// Check if the field value has a type prefix (e.g. "match:", "partial:", "range:")
value := fieldValue
if strings.Contains(fieldValue, ":") {
parts := strings.Split(fieldValue, ":")
if len(parts) == 2 {
searchType = parts[0]
value = parts[1]
}
}
// Map the value to the appropriate type
valueAny, err := stringToAny(value)
if err != nil {
return nil, err
}
// If searchType is empty, check if the value is a slice
// If it is a slice, set the searchType to "range"
if searchType == "" {
if _, ok := valueAny.([]int); ok {
searchType = "range"
}
if _, ok := valueAny.([]float64); ok {
searchType = "range"
}
}
// Otherwise, set the searchType to "match"
if searchType == "" {
searchType = "match"
}
// Create the SearchQueryField struct with the parsed field type and value
searchQueryField := SearchQueryField{
Field: fieldName,
Type: searchType,
Value: valueAny,
}
// Append the SearchQueryField to the fields slice
fields = append(fields, searchQueryField)
}
// If fields is empty, set to nil
if len(fields) == 0 {
fields = nil
}
// Create the SearchQuery struct with the map of SearchQueryFields and special fields
searchQuery := &SearchQuery{
Limit: uint(limit),
Skip: uint(skip),
Sort: sort,
Fields: fields,
}
return searchQuery, nil
}
func JsontoSearchQueries(jsonBytes []byte) (*SearchQuery, error) {
var searchQuery SearchQuery
err := json.Unmarshal(jsonBytes, &searchQuery)
if err != nil {
return nil, err
}
return &searchQuery, nil
}