Query
The Query
class is what powers every interaction with Fluent. Whether you're fetching a model with .find()
or saving to the database, there is a Query
involved somewhere.
Querying Models
Every type that conforms to Model gets a static .query()
method.
let query = try User.query()
This is how you can create a Query<User>
.
No Database
The .query()
method is marked with try
because it can throw an error if the Model has not had its static database property set.
User.database = drop.database
This property is set automatically when you pass the Model as a preparation.
Filter
The most common types of queries involve filtering data.
let smithsQuery = try User.query().filter("last_name", "Smith")
Here is the short hand for adding an equals
filter to the query. As you can see, queries can be chained together.
In additional to equals
, there are many other types of Filter.Comparison
.
let over21 = try User.query().filter("age", .greaterThanOrEquals, 21)
Scope
Filters can also be run on sets.
let coolPets = try Pet.query().filter("type", .in, ["Dog", "Ferret"])
Here only Pets of type Dog or Ferret are returned. The opposite works for notIn
.
Contains
Partially matching filters can also be applied.
let statesWithNew = try State.query().filter("name", contains: "New")
Retrieving
There are two methods for running a query.
All
All of the matching entities can be fetched. This returns an array of [Model]
, in this case users.
let usersOver21 = try User.query().filter("age", .greaterThanOrEquals, 21).all()
First
The first matching entity can be fetched. This returns an optional Model?
, in this case a user.
let firstSmith = try User.query().filter("last_name", "Smith").first()
Union
Other Models can be joined onto your query to assist in filtering. The results must still be either [Model]
or Model?
for whichever type created the query.
let usersWithCoolPets = try User.query()
.union(Pet.self)
.filter(Pet.self, "type", .in, ["Dog", "Ferret"])
Here the User
collection is unioned to the Pet
collection. Only User
s who have a dog or a ferret will be returned.
Keys
The union
method assumes that the querying table has a foreign key identifier to the joining table.
The above example with users and pets assumes the following schema.
users
- id
pets
- id
- user_id
Custom foreign keys can be provided through overloads to union
.
Raw Queries
Since Fluent is focused on interacting with models, each Query requires a model type. If you want to do raw database queries that aren't based on a model, you should use the underlying Fluent Driver to do so.
if let mysql = drop.database?.driver as? MySQLDriver {
let version = try mysql.raw("SELECT @@version")
}