Query is an adaptor of http query to expressions. Check adapters to convert it to sql or other expressions.
go get github.com/rakunlabs/queryParse url and extract query parameters with RAW, give to query.Parse to convert it to expression.
Use an adapter to convert it to sql or other expressions.
urlStr := "http://example.com?name=foo,bar|nick=bar&age[lt]=1&_sort=-age&_limit=10&_offset=5&_fields=id,name"
parsedURL, err := url.Parse(urlStr)
// ...
query, err := query.Parse(parsedURL.RawQuery)
// ...
sql, params, err := adaptergoqu.Select(query, goqu.From("test")).ToSQL()
// ...
// Output:
// SQL: SELECT "id", "name" FROM "test" WHERE ((("name" IN (?, ?)) OR ("nick" = ?)) AND ("age" < ?)) ORDER BY "age" DESC LIMIT ? OFFSET ?
// Params: [foo bar bar 1 10 5]If some value separated by , it will be converted to IN operator.
There are a list of [ ] operators that can be used in the query string:
eq, ne, gt, lt, gte, lte, like, ilike, nlike, nilike, in, nin, is, not, kv, jin, njin
| Operator | Description | Example | SQL |
|---|---|---|---|
eq |
Equal | name[eq]=foo or name=foo |
name = 'foo' |
ne |
Not equal | name[ne]=foo |
name != 'foo' |
gt |
Greater than | age[gt]=18 |
age > 18 |
lt |
Less than | age[lt]=18 |
age < 18 |
gte |
Greater than or equal | age[gte]=18 |
age >= 18 |
lte |
Less than or equal | age[lte]=18 |
age <= 18 |
like |
LIKE pattern | name[like]=%foo% |
name LIKE '%foo%' |
ilike |
Case-insensitive LIKE | name[ilike]=%foo% |
name ILIKE '%foo%' |
nlike |
NOT LIKE | name[nlike]=%foo% |
name NOT LIKE '%foo%' |
nilike |
Case-insensitive NOT LIKE | name[nilike]=%foo% |
name NOT ILIKE '%foo%' |
in |
IN list | name[in]=foo,bar or name=foo,bar |
name IN ('foo', 'bar') |
nin |
NOT IN list | name[nin]=foo,bar |
name NOT IN ('foo', 'bar') |
is |
IS NULL | name[is]= |
name IS NULL |
not |
IS NOT NULL | name[not]= |
name IS NOT NULL |
kv |
JSONB containment (@>) | meta[kv]=eyJhIjoxfQ |
meta @> '{"a":1}' |
jin |
JSONB array has any (?|) | tags[jin]=admin,editor |
tags ?| array['admin','editor'] |
njin |
JSONB array has none (NOT ?|) | tags[njin]=admin,editor |
NOT (tags ?| array['admin','editor']) |
_limit and _offset are used to limit the number of rows returned. 0 limit means no limit.
_fields is used to select the fields to be returned, comma separated.
_sort is used to sort the result set, can be prefixed with - to indicate descending order and comma separated to indicate multiple fields.
[] empty operator means in operator.
Paranteses () can be used to group expressions, | is used for OR operation and & is used for AND operation.
Options can be passed to query.Parse to customize parsing behavior:
Sets the default operator for a specific key when no bracket operator is specified. This allows you to write cleaner query strings without explicit [op] brackets.
// Without WithKeyOperator: name=foo → name[eq]=foo (default)
// With WithKeyOperator: name=foo → name[like]=foo
q, err := query.Parse("name=foo", query.WithKeyOperator("name", query.OperatorLike))
// Useful for JSONB array columns:
// tags=admin,editor → tags ?| array['admin','editor']
q, err := query.Parse("tags=admin,editor", query.WithKeyOperator("tags", query.OperatorJIn))Explicit bracket operators always take priority over WithKeyOperator. If the query contains name[eq]=foo, the eq operator is used regardless of the WithKeyOperator setting.
Sets a value transform function for a specific key. The function is applied to the raw value string before parsing, regardless of whether a bracket operator is present.
// Wrap value with % for LIKE queries
q, err := query.Parse("name=foo",
query.WithKeyOperator("name", query.OperatorLike),
query.WithKeyValueTransform("name", func(v string) string {
return "%" + v + "%"
}),
)
// Result: name[like]=%foo%
// SQL: name LIKE '%foo%'This also works with explicit bracket operators:
// name[ilike]=foo → name[ilike]=%foo%
q, err := query.Parse("name[ilike]=foo",
query.WithKeyValueTransform("name", func(v string) string {
return "%" + v + "%"
}),
)query.WithField is used to validate the field names.
WithNotInis used to validate the field names that are not allowed.WithInis used to validate the field names that are allowed.WithNotAllowedis used to validate the field names totally not allowed.
query.WithValues is used to validate the values of the fields.
WithNotInis used to validate the values that are not allowed.WithInis used to validate the values that are allowed.WithNotAllowedis used to validate the values totally not allowed.
query.WithValue is used to validate the values of the fields.
WithRequiredis used to validate the values that are required.WithNotEmptyis used to validate the values that are not empty.WithNotInis used to validate the values that are not allowed.WithInis used to validate the values that are allowed.WithNotAllowedis used to validate the value that are not allowed.WithOperatoris used to validate the operator that is allowed.WithNotOperatoris used to validate the operator that is not allowed.WithMaxis used to validate the maximum of value, value must be a number.WithMinis used to validate the minimum of value, value must be a number.
query.WithOffset is used to validate the offset value.
WithMaxis used to validate the maximum of offset, value must be a number.WithMinis used to validate the minimum of offset, value must be a number.WithNotAllowedis used to validate the offset value that are not allowed.
query.WithLimit is used to validate the limit value.
WithMaxis used to validate the maximum of limit, value must be a number.WithMinis used to validate the minimum of limit, value must be a number.WithNotAllowedis used to validate the limit value that are not allowed.
query.WithSort is used to validate the sort value.
WithNotInis used to validate the sort value that are not allowed.WithInis used to validate the sort value that are allowed.WithNotAllowedis used to validate the sort value that are not allowed.
Example of validation:
validator := query.NewValidator(
WithValue("member", query.WithRequired(), query.WithNotIn("O", "P", "S")),
WithValues(query.WithIn("age", "test", "member")),
WithValue("age", query.WithOperator(OperatorEq), query.WithNotOperator(OperatorIn)),
WithField(query.WithNotAllowed()),
)
// after that use it to validate
err := validator.Validate(query)
if err != nil {
// handle error
}
// or pass with when parsing
query, err := query.Parse(rawQuery, query.WithValidator(validator))
// ...