Filtering and Sorting
MangoSQL Filters
All the Queries have one thing in common: MangoSQL Filters.
MangoSQL statically compiles queries ahead of time, so the shape and typing of the queries are immutable. But for convenience, some clause like WHERE, LIMIT, OFFSET can be dynamically modified at runtime.
Filters provide a Typed and Safe way to modify these clauses and we use Squirrel under the hood.
// All the Select Queries accepts 0..n filters
db.User.Count(filters...)
db.User.FindMany(filters...)
db.User.FindUnique(filters...)Sorting
This is also managed though MangoSQL filters
// generate `ORDER BY id ASC, name DESC`
users, err := db.User.FindMany(
db.User.Query.Id.OrderAsc(),
db.User.Query.Name.OrderDesc(),
)Pagination
This is also managed though MangoSQL filters
// generate `OFFSET 10 LIMIT 25`
users, err := db.User.FindMany(
db.User.Query.Limit(25),
db.User.Query.Offset(10),
)Auto-Generated Filters
For each field of your table, a set of filters will be automatically generated based on the Type. This covers the most common operations.
db.{Table}.Query.{Field}.Equal(input)
db.{Table}.Query.{Field}.NotEqual(input)
db.{Table}.Query.{Field}.In(input)
db.{Table}.Query.{Field}.NotIn(input)
db.{Table}.Query.{Field}.Like(input)
db.{Table}.Query.{Field}.MoreThan(input)
db.{Table}.Query.{Field}.LessThan(input)
db.{Table}.Query.{Field}.Between(low, high)
db.{Table}.Query.{Field}.OrderAsc()
db.{Table}.Query.{Field}.OrderDesc()
db.{Table}.Query.Offset(offset)
db.{Table}.Query.Limit(limit)Example
users, err := db.User.FindMany(
db.User.Query.Name.In("user1", "user2"),
db.User.Query.Id.LesserThan(10),
db.User.Query.Id.OrderAsc(),
db.User.Query.Offset(25),
db.User.Query.Limit(10),
)SELECT id, name, created_at, deleted_at
FROM users
WHERE users.name = ANY($1) AND users.id < $2
ORDER BY users.id ASC
LIMIT 10 OFFSET 25User Filters
You can also write your own filters, a filter is just a function which takes and returns a QueryBuilder. This gives way more freedom for advanced field manipulations, specific database syntax or extensions, ...
// This is a valid mango filter
func(cond SelectBuilder) SelectBuilder {
return cond.Where("name = ? OR id = ?", "user1", 2)
}// find all users which match this filter
users, err := db.User.FindMany(func(cond SelectBuilder) SelectBuilder {
return cond.Where("name = ? OR id = ?", "user1", 2)
})// create a new function to generate these where conditions
func MyFilter(name string, id int) WhereCondition {
return func(cond SelectBuilder) SelectBuilder {
return cond.Where("name = ? OR id = ?", name, id)
}
}
// can use the filter in any User related query
users, err := db.User.FindMany(
MyFilter("user1", 2),
)INFO
Even if this looks dynamic, each request will automatically turn into a prepared statement and arguments passed separately.
DANGER
Be careful to use ? to prepare parameters and not concatenate them into the query directly, you could have SQL Injection.