Vapor GitHub

You're viewing documentation for an older version. View the latest version

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 Users 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")
}