@@ -30,48 +30,17 @@ pub fn q(s: &str) -> Query {
30
30
}
31
31
32
32
impl Query {
33
- /// Form expected: `{search}*{filter}*`
34
- ///
35
- /// where `{filter}` is of the form `{field}{op}{value}`
36
- ///
37
- /// Multiple searches and/or filters should be `&`-delimited
38
- ///
39
- /// The `{search}` text will result in an OR clause of LIKE clauses
40
- /// for every [String] field in the associated Columns. Optional
41
- /// filters of the form `{field}{op}{value}` may further constrain
42
- /// the results. Each `{field}` name must correspond to one of the
43
- /// selected Columns.
44
- ///
45
- /// Fields corresponding to JSON objects in the database may use a
46
- /// ':' to delimit the column name and the object key,
47
- /// e.g. `purl:name=foo`
48
- ///
49
- /// Both `{search}` and `{value}` may contain `|`-delimited
50
- /// alternate values that will result in an OR clause. Any literal
51
- /// `|` or `&` within a search or value should be escaped with a
52
- /// backslash, e.g. `\|` or `\&`.
53
- ///
54
- /// `{op}` should be one of `=`, `!=`, `~`, `!~, `>=`, `>`, `<=`,
55
- /// or `<`.
56
- ///
33
+ /// Construct a Query from a properly-formatted string denoting
34
+ /// full text searches and/or filters
57
35
pub fn q ( s : & str ) -> Self {
58
36
Self {
59
37
q : s. into ( ) ,
60
38
sort : String :: default ( ) ,
61
39
}
62
40
}
63
41
64
- /// Form expected: `{sort}*`
65
- ///
66
- /// where `{sort}` is of the form `{field}[:order]` and the
67
- /// optional `order` should be one of `asc` or `desc`. If omitted,
68
- /// the order defaults to `asc`.
69
- ///
70
- /// Multiple sorts should be `,`-delimited
71
- ///
72
- /// Each `{field}` name must correspond to one of the selected
73
- /// Columns.
74
- ///
42
+ /// Sort the results of a Query per a comma-delimited string of
43
+ /// field names.
75
44
pub fn sort ( self , s : & str ) -> Self {
76
45
Self {
77
46
q : self . q ,
@@ -165,11 +134,76 @@ impl Query {
165
134
}
166
135
}
167
136
137
+ /// A Query is comprised of full text searches and/or filters with optional sorting rules.
138
+ ///
168
139
#[ derive( Clone , Default , Debug , Eq , PartialEq , Deserialize , Serialize , ToSchema , IntoParams ) ]
169
140
#[ serde( rename_all = "camelCase" ) ]
170
141
pub struct Query {
142
+ /// EBNF grammar for the _q_ parameter:
143
+ /// ```text
144
+ /// q = ( values | filter ) { '&' q }
145
+ /// values = value { '|', values }
146
+ /// filter = field, operator, values
147
+ /// operator = "=" | "!=" | "~" | "!~" | ">=" | ">" | "<=" | "<"
148
+ /// value = (* any text but escape special characters with '\' *)
149
+ /// field = (* must match an entity attribute name *)
150
+ /// ```
151
+ /// Any values in a _q_ will result in a case-insensitive "full
152
+ /// text search", effectively producing an OR clause of LIKE
153
+ /// clauses for every string-ish field in the resource being
154
+ /// queried.
155
+ ///
156
+ /// Examples:
157
+ /// - `foo` - any field containing 'foo'
158
+ /// - `foo|bar` - any field containing either 'foo' OR 'bar'
159
+ /// - `foo&bar` - some field contains 'foo' AND some field contains 'bar'
160
+ ///
161
+ /// A _filter_ can further constrain the results. The filter's
162
+ /// field name must correspond to one of the resource's
163
+ /// attributes. If it doesn't, an error will be returned
164
+ /// containing a list of the valid fields for that resource.
165
+ ///
166
+ /// The value 'null' is treated specially for [not]equal filters:
167
+ /// it returns resources on which the field isn't set. Use the
168
+ /// LIKE operator, `~`, to match a literal "null" string.
169
+ ///
170
+ /// Examples:
171
+ /// - `name=foo` - entity's _name_ matches 'foo' exactly
172
+ /// - `name~foo` - entity's _name_ contains 'foo', case-insensitive
173
+ /// - `name~foo|bar` - entity's _name_ contains either 'foo' OR 'bar', case-insensitive
174
+ /// - `name=null` - entity's _name_ isn't set
175
+ /// - `published>3 days ago` - date values can be "human time"
176
+ ///
177
+ /// Multiple full text searches and/or filters should be
178
+ /// '&'-delimited -- they are logically AND'd together.
179
+ ///
180
+ /// - `red hat|fedora&labels:type=cve|osv&published>last wednesday 17:00`
181
+ ///
182
+ /// Fields corresponding to JSON objects in the database may use a
183
+ /// ':' to delimit the column name and the object key,
184
+ /// e.g. `purl:qualifiers:type=pom`
185
+ ///
186
+ /// Any operator or special character, e.g. '|', '&', within a
187
+ /// value should be escaped by prefixing it with a backslash.
188
+ ///
171
189
#[ serde( default ) ]
172
190
pub q : String ,
191
+
192
+ /// EBNF grammar for the _sort_ parameter:
193
+ /// ```text
194
+ /// sort = field [ ':', order ] { ',' sort }
195
+ /// order = ( "asc" | "desc" )
196
+ /// field = (* must match the name of entity's attributes *)
197
+ /// ```
198
+ /// The optional _order_ should be one of "asc" or "desc". If
199
+ /// omitted, the order defaults to "asc".
200
+ ///
201
+ /// Each _field_ name must correspond to one of the columns of the
202
+ /// table holding the entities being queried. Those corresponding
203
+ /// to JSON objects in the database may use a ':' to delimit the
204
+ /// column name and the object key,
205
+ /// e.g. `purl:qualifiers:type:desc`
206
+ ///
173
207
#[ serde( default ) ]
174
208
pub sort : String ,
175
209
}
0 commit comments