From c0d6ef75681c50c63db59babbc13cb95091d34a2 Mon Sep 17 00:00:00 2001 From: tanner0101 Date: Mon, 16 Jul 2018 22:20:25 -0400 Subject: [PATCH] deploy --- build/3.0/fluent/getting-started/index.html | 40 +++++++++++++---- build/3.0/fluent/migrations/index.html | 50 +++++++++++++++------ build/3.0/fluent/querying/index.html | 36 +++++++-------- build/3.0/fluent/relations/index.html | 10 ++--- build/3.0/fluent/transaction/index.html | 2 +- build/3.0/search/search_index.json | 23 ++++++---- build/3.0/sql/overview/index.html | 4 +- build/3.0/version/upgrading/index.html | 40 +++++++++++++++++ 8 files changed, 147 insertions(+), 58 deletions(-) diff --git a/build/3.0/fluent/getting-started/index.html b/build/3.0/fluent/getting-started/index.html index 9bcdf735..f5601c83 100644 --- a/build/3.0/fluent/getting-started/index.html +++ b/build/3.0/fluent/getting-started/index.html @@ -2165,7 +2165,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio

Creating a Model

Now let's create your first model. Models represent tables in your database and they are the primary method of interacting with your data.

-

Each driver provides convenience model protocols (PostgreSQLModel, SQLiteModel, etc) that extend Fluent's base Model protocol. These convenience types make declaring models more concise by using standard values for ID key and type.

+

Each driver provides convenience model protocols (PostgreSQLModel, SQLiteModel, etc) that extend Fluent's base Model protocol. These convenience types make declaring models more concise by using standard values for ID key and type.

Fill in the Xcode placeholders below with the name of your chosen database, i.e., PostgreSQL.

import Fluent<#Database#>
 import Vapor
@@ -2211,12 +2211,34 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
 

Custom Credentials

If you are using default configuration for your database (such as default credentials or other config) then this may be the only setup you need to perform.

See the documentation for your specific database type for more information about custom configuration.

-
-

Danger

-

fixme: Add links to config structs.

-
+ + + + + + + + + + + + + + + + + + + + + + + + + +
databasedocsapi docs
PostgreSQLPostgreSQL → Getting StartedComing soon
MySQLMySQL → Getting StartedComing soon
SQLiteSQLite → Getting StartedSQLiteDatabase

Creating a Migration

-

If your database driver uses schemas (is a SQL database), you will need to create a Migration for your new model. Migrations allow Fluent to create a table for your model in a reliable, testable way. You can later create additional migrations to update or delete the model's table or even manipulate data in the table.

+

If your database driver uses schemas (is a SQL database), you will need to create a Migration for your new model. Migrations allow Fluent to create a table for your model in a reliable, testable way. You can later create additional migrations to update or delete the model's table or even manipulate data in the table.

To create a migration, you will normally first create a new struct or class to hold the migration. However, models can take advantage of a convenient shortcut. When you create a migration from an existing model type, Fluent can infer an appropriate schema from the model's codable properties.

You can add the migration conformance to a model as an extension or on the base type declaration.

import Fluent<#Database#>
@@ -2228,7 +2250,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
 
 

Take a look at Fluent → Migration if you are interested in learning more about custom migrations.

Configuring Migrations

-

Once you have created a migration, you must register it to Fluent using MigrationConfig. This is done in configure.swift.

+

Once you have created a migration, you must register it to Fluent using MigrationConfig. This is done in configure.swift.

Fill in the database ID (dbid) from the table above, i.e., psql.

import Fluent<#Database#>
 import Vapor
@@ -2244,7 +2266,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
 
 

Tip

-

If the migration you are adding is also a model, you can use the add(model:on:) convenience to automatically set the model's defaultDatabase property. Otherwise, use the add(migration:on) method.

+

If the migration you are adding is also a model, you can use the add(model:on:) convenience to automatically set the model's defaultDatabase property. Otherwise, use the add(migration:on) method.

Once you have the MigrationConfig added, you should be able to run your application and see the following:

Migrating <#dbid#> DB
@@ -2264,7 +2286,7 @@ Server starting on http://localhost:8080
 

If you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent model working.

Raw Queries

With Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a "raw query".

-

To perform raw queries, you need access to a database connection. Vapor's Request type has a number of conveniences for creating new database connections. The recommended method is withPooledConnection(to:). Learn about other methods in DatabaseKit → Overview → Connections.

+

To perform raw queries, you need access to a database connection. Vapor's Request type has a number of conveniences for creating new database connections. The recommended method is withPooledConnection(to:). Learn about other methods in DatabaseKit → Overview → Connections.

router.get("raw") { req -> Future<String> in
     return req.withPooledConnection(to: .<#dbid#>) { conn in
         // perform raw query using conn
diff --git a/build/3.0/fluent/migrations/index.html b/build/3.0/fluent/migrations/index.html
index 98dbfde5..ad33bedb 100644
--- a/build/3.0/fluent/migrations/index.html
+++ b/build/3.0/fluent/migrations/index.html
@@ -2051,7 +2051,7 @@ make normal queries to your database.

Automatic Model Migrations

-

Models provide a shortcut for declaring database migrations. If you conform a type that conforms to Model to Migration, Fluent can infer the model's properties and automatically implement the prepare(...) and revert(...) methods.

+

Models provide a shortcut for declaring database migrations. If you conform a type that conforms to Model to Migration, Fluent can infer the model's properties and automatically implement the prepare(...) and revert(...) methods.

import Fluent<#Database#>
 
 extension Galaxy: <#Database#>Migration { }
@@ -2059,16 +2059,16 @@ make normal queries to your database.

This method is especially useful for quick prototyping and simple setups. For most other situations you should consider creating a normal, custom migration.

-

Add this automatic migration to your MigrationConfig using the add(model:database:) method. This is done in configure.swift.

+

Add this automatic migration to your MigrationConfig using the add(model:database:) method. This is done in configure.swift.

var migrations = MigrationConfig()
 migrations.add(model: Galaxy.self, database: .<#dbid#>)
 services.register(migrations)
 
-

The add(model:database:) method will automatically set the model's defaultDatabase property.

+

The add(model:database:) method will automatically set the model's defaultDatabase property.

Custom Migrations

-

We can customize the table created for our model by creating a migration and using the static create and delete methods on Database.

+

We can customize the table created for our model by creating a migration and using the static create and delete methods on Database.

import Fluent<#Database#>
 
 struct CreateGalaxy: <#Database#>Migration {
@@ -2094,7 +2094,7 @@ make normal queries to your database.

-

To create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the SchemaBuilder. This builder has convenience methods for declaring fields in the schema.

+

To create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the SchemaBuilder. This builder has convenience methods for declaring fields in the schema.

You can use the field(for: <#KeyPath#>) method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by \.), Fluent can see what type those properties are. For most common types (String, Int, Double, etc) Fluent will automatically be able to determine the best database field type to use.

You can also choose to manually select which database field type to use for a given field.

try builder.field(for: \.name, type: <#DataType#>)
@@ -2102,10 +2102,32 @@ make normal queries to your database.

Each database has it's own unique data types, so refer to your database's documentation for more information.

-
-

Danger

-

fixme: links to db's data types

-
+ + + + + + + + + + + + + + + + + + + + + + + + + +
databasedocsapi docs
PostgreSQLPostgreSQL → Getting StartedComing soon
MySQLMySQL → Getting StartedComing soon
SQLiteSQLite → Getting StartedSQLiteDataType

Deleting a Schema

Each migration should also include a method for reverting the changes it makes. It is used when you boot your app with the --revert option.

@@ -2124,7 +2146,7 @@ app with the --revert option.

To delete a schema, you pass a model type and connection as the two required parameters. That's it.

You can always choose to skip a reversion by simplying returning conn.future(()). But note that they are especially useful when testing and debugging your migrations.

-

Add this custom migration to your MigrationConfig using the add(migration:database:) method. This is done in your configure.swift file.

+

Add this custom migration to your MigrationConfig using the add(migration:database:) method. This is done in your configure.swift file.

var migrations = MigrationConfig()
 migrations.add(migration: CreateGalaxy.self, database: .<#dbid#>)
 services.register(migrations)
@@ -2149,7 +2171,7 @@ app with the --revert option. 

-

Since our previous migration created a table with fields for both id and name, we need to update that table and add a field for mass. We can do this by using the static update method on Database.

+

Since our previous migration created a table with fields for both id and name, we need to update that table and add a field for mass. We can do this by using the static update method on Database.

import Fluent<#Database#>
 
 struct AddGalaxyMass: <#Database#>Migration {
@@ -2171,7 +2193,7 @@ app with the --revert option. 

-

All methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See SchemaUpdater for a list of all available methods.

+

All methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See SchemaUpdater for a list of all available methods.

To revert this change, we must delete the mass field from the table.

struct AddGalaxyMass: <#Database#>Migration {
     // ... 
@@ -2184,7 +2206,7 @@ app with the --revert option. 

-

Add this migration to your MigrationConfig using the add(migration:database:) method. This is done in your configure.swift file.

+

Add this migration to your MigrationConfig using the add(migration:database:) method. This is done in your configure.swift file.

var migrations = MigrationConfig()
 // ...
 migrations.add(migration: AddGalaxyMass.self, database: .<#dbid#>)
@@ -2224,7 +2246,7 @@ app with the --revert option. 

-

Add this migration to your MigrationConfig using the add(migration:database:) method. This is done in configure.swift.

+

Add this migration to your MigrationConfig using the add(migration:database:) method. This is done in configure.swift.

var migrations = MigrationConfig()
 // ...
 migrations.add(migration: GalaxyMassCleanup.self, database: .<#dbid#>)
diff --git a/build/3.0/fluent/querying/index.html b/build/3.0/fluent/querying/index.html
index 5a32bbf9..289f6ec5 100644
--- a/build/3.0/fluent/querying/index.html
+++ b/build/3.0/fluent/querying/index.html
@@ -93,7 +93,7 @@
     
     
     
-      
+      
         Skip to content
       
     
@@ -2170,12 +2170,12 @@
                   
                 
                 
-                

Querying Models

+

Fluent Queries

Once you have a model you can start querying your database to create, read, update, and delete data.

Connection

The first thing you need to query your database, is a connection to it. Luckily, they are easy to get.

Request

-

The easiest way to connect to your database is simply using the incoming Request. This will use the model's defaultDatabase property to automatically fetch a pooled connection to the database.

+

The easiest way to connect to your database is simply using the incoming Request. This will use the model's defaultDatabase property to automatically fetch a pooled connection to the database.

router.get("galaxies") { req in
     return Galaxy.query(on: req).all()
 }
@@ -2184,7 +2184,7 @@
 
 

You can use convenience methods on a Container to create connections manually. Learn more about that in DatabaseKit → Overview → Connections.

Create

-

One of the first things you will need to do is save some data to your database. You do this by initializing an instance of your model then calling create(on:).

+

One of the first things you will need to do is save some data to your database. You do this by initializing an instance of your model then calling create(on:).

router.post("galaxies") { req in
     let galaxy: Galaxy = ... 
     return galaxy.create(on: req)
@@ -2193,28 +2193,28 @@
 
 
 

The create method will return the saved model. The returned model will include any generated fields such as the ID or fields with default values.

-

If your model also conforms to Content you can return the result of the Fluent query directly.

+

If your model also conforms to Content you can return the result of the Fluent query directly.

Read

-

To read models from the database, you can use query(on:) or find(_:on:).

+

To read models from the database, you can use query(on:) or find(_:on:).

Find

-

The easiest way to find a single model is by passing its ID to find(_:on:).

+

The easiest way to find a single model is by passing its ID to find(_:on:).

Galaxy.find(42, on: conn)
 
-

The result will be a future containing an optional value. You can use unwrap(or:) to unwrap the future value or throw an error.

+

The result will be a future containing an optional value. You can use unwrap(or:) to unwrap the future value or throw an error.

Galaxy.find(42, on: conn).unwrap(or: Abort(...))
 

Query

-

You can use the query(on:) method to build database queries with filters, joins, sorts, and more.

+

You can use the query(on:) method to build database queries with filters, joins, sorts, and more.

Galaxy.query(on: conn).filter(\.name == "Milky Way")
 

Filter

-

The filter(_:) method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.

+

The filter(_:) method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.

Calls to filter can be chained and even grouped.

Galaxy.query(on: conn).filter(\.mass >= 500).filter(\.type == .spiral)
 
@@ -2285,9 +2285,9 @@
-

Once a table has been joined using join(_:to:), you can use fully-qualified key paths to filter results based on data in the joined table.

+

Once a table has been joined using join(_:to:), you can use fully-qualified key paths to filter results based on data in the joined table.

The above query fetches all galaxies that have a planet named Earth.

-

You can even decode the joined models using alsoDecode(...).

+

You can even decode the joined models using alsoDecode(...).

Galaxy.query(on: conn)
     // join Planet and filter
     .alsoDecode(Planet.self).all()
@@ -2296,20 +2296,20 @@
 
 

The above query will decode an array of (Galaxy, Planet) tuples.

Fetch

-

To fetch the results of a query, use all(), chunk(max:), first() or an aggregate method.

+

To fetch the results of a query, use all(), chunk(max:closure:), first() or an aggregate method.

All

The most common method for fetching results is with all(). This will return all matching results according to any fliters applied.

Galaxy.query(on: conn).all()
 
-

When combined with range(_:), you can efficiently limit how many results are returned by the database.

+

When combined with range(_:), you can efficiently limit how many results are returned by the database.

Galaxy.query(on: conn).range(..<50).all()
 

Chunk

-

For situations where memory conservation is important, use chunk(...). This method returns the result set in multiple calls of a maximum chunk size.

+

For situations where memory conservation is important, use chunk(...). This method returns the result set in multiple calls of a maximum chunk size.

Galaxy.query(on: conn).chunk(max: 32) { galaxies in
     print(galaxies) // Array of 32 or less galaxies
 }
@@ -2317,14 +2317,14 @@
 
 
 

First

-

The first() method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.

+

The first() method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.

Galaxy.query(on: conn).filter(\.name == "Milky Way").first()
 

This method is more efficient than calling all and getting the first item in the array.

Update

-

After a model has been fetched from the database and mutated, you can use update(on:) to save the changes.

+

After a model has been fetched from the database and mutated, you can use update(on:) to save the changes.

var planet: Planet ... // fetched from database
 planet.name = "Earth"
 planet.update(on: conn)
@@ -2332,7 +2332,7 @@
 
 
 

Delete

-

After a model has been fetched from the database, you can use delete(on:) to delete it.

+

After a model has been fetched from the database, you can use delete(on:) to delete it.

var planet: Planet ... // fetched from database
 planet.delete(on: conn)
 
diff --git a/build/3.0/fluent/relations/index.html b/build/3.0/fluent/relations/index.html index c62c79c5..e2b31b2b 100644 --- a/build/3.0/fluent/relations/index.html +++ b/build/3.0/fluent/relations/index.html @@ -1994,7 +1994,7 @@

For more information on defining models see Fluent → Models.

-

Fluent provides two helpers for working with parent-child relations: Parent and Children. These helpers can be created using extensions on the related models for convenient access.

+

Fluent provides two helpers for working with parent-child relations: Parent and Children. These helpers can be created using extensions on the related models for convenient access.

extension Galaxy {
     // this galaxy's related planets
     var planets: Children<Galaxy, Planet> { 
@@ -2004,7 +2004,7 @@
 
-

Here the children(_:) method is used on Galaxy to create the relation. The resulting type has two generic arguments in the signature that can be thought of as <From, To>. Since this relation goes from galaxy to planet, they are ordered as such in the generic arguments.

+

Here the children(_:) method is used on Galaxy to create the relation. The resulting type has two generic arguments in the signature that can be thought of as <From, To>. Since this relation goes from galaxy to planet, they are ordered as such in the generic arguments.

Note that this method is not static. That is because it must access the galaxy's identifier to perform the relation lookup.

extension Planet {
     // this planet's related galaxy
@@ -2015,7 +2015,7 @@
 
-

Here the parent(_:) method is used on Planet to create the inverse relation. The resulting type also has two generic arguments. In this case, they are reversed since this relation now goes from planet to galaxy.

+

Here the parent(_:) method is used on Planet to create the inverse relation. The resulting type also has two generic arguments. In this case, they are reversed since this relation now goes from planet to galaxy.

Note that this method is also not static. That is because it must access the referenced identifier to perform the relation lookup.

Now that the models and relation properties are created, they can be used to create, read, update, and delete related data.

let galaxy: Galaxy = ...
@@ -2023,7 +2023,7 @@
 
-

The query(on:) method on a relation creates an instance of QueryBuilder filtered to the related models. See Fluent → Querying for more information on working with the query builder.

+

The query(on:) method on a relation creates an instance of QueryBuilder filtered to the related models. See Fluent → Querying for more information on working with the query builder.

let planet: Planet = ...
 let galaxy = planet.galaxy.get(on: ...)
 
@@ -2107,7 +2107,7 @@

Modifiable Pivot

-

If the pivot conforms to ModifiablePivot, then Fluent can help to create and delete pivots (called attaching and detaching).

+

If the pivot conforms to ModifiablePivot, then Fluent can help to create and delete pivots (called attaching and detaching).

Conforming a pivot is fairly simple. Fluent just needs to be able to initialize the pivot from two related models.

extension PlanetTag: ModifiablePivot {
     init(_ planet: Planet, _ tag: Tag) throws {
diff --git a/build/3.0/fluent/transaction/index.html b/build/3.0/fluent/transaction/index.html
index b893fa15..47eff6bf 100644
--- a/build/3.0/fluent/transaction/index.html
+++ b/build/3.0/fluent/transaction/index.html
@@ -1881,7 +1881,7 @@
                 
                 

Fluent Transactions

Transactions allow you to ensure multiple operations complete succesfully before saving data to your database. Once a transaction is started, you may run Fluent queries normally. However, no data will be saved to the database until the transaction completes. If an error is thrown at any point during the transaction (by you or the database), none of the changes will take effect.

-

To perform a transaction, you need access to something that can connect to the database. This is usually an incoming HTTP request. Use the transaction(on:_:) method.

+

To perform a transaction, you need access to something that can connect to the database. This is usually an incoming HTTP request. Use the transaction(on:_:) method.

Fill in the Xcode placeholders below with your database's name from Getting Started → Choosing a Driver.

req.transaction(on: .<#dbid#>) { conn in
     // use conn as your connection
diff --git a/build/3.0/search/search_index.json b/build/3.0/search/search_index.json
index 956bf711..a5c43782 100644
--- a/build/3.0/search/search_index.json
+++ b/build/3.0/search/search_index.json
@@ -987,7 +987,7 @@
         }, 
         {
             "location": "/fluent/getting-started/", 
-            "text": "Getting Started with Fluent\n\n\nFluent (\nvapor/fluent\n) is a type-safe, fast, and easy-to-use ORM framework built for Swift.\nIt takes advantage of Swift's strong type system to provide an elegant foundation for building database integrations.\n\n\nChoosing a Driver\n\n\nFluent is a framework for building ORMs, not an ORM itself. To use Fluent, you will first need to choose a database driver to use. Fluent can support multiple databases and database drivers per application.\n\n\nBelow is a list of officially supported database drivers for Fluent. \n\n\n\n\n\n\n\n\ndatabase\n\n\nrepo\n\n\nversion\n\n\ndbid\n\n\nnotes\n\n\n\n\n\n\n\n\n\n\nPostgreSQL\n\n\nfluent-postgresql\n\n\n1.0.0\n\n\npsql\n\n\nRecommended\n. Open source, standards compliant SQL database. Available on most cloud hosting providers.\n\n\n\n\n\n\nMySQL\n\n\nfluent-mysql\n\n\n3.0.0\n\n\nmysql\n\n\nPopular open source SQL database. Available on most cloud hosting providers. This driver also supports MariaDB.\n\n\n\n\n\n\nSQLite\n\n\nfluent-sqlite\n\n\n3.0.0\n\n\nsqlite\n\n\nOpen source, embedded SQL database. Its simplistic nature makes it a great candiate for prototyping and testing.\n\n\n\n\n\n\nMongoDB\n\n\nfluent-mongo\n\n\nn/a\n\n\nmongo\n\n\nComing soon. Popular NoSQL database.\n\n\n\n\n\n\n\n\n\n\nNote\n\n\nReplace any Xcode placholders (\n#...#\n) in the code snippets below with information from the above table.\n\n\n\n\nYou can search GitHub for the tag \nfluent-database\n for a full list of official and third-party Fluent database drivers.\n\n\nPackage\n\n\nOnce you have decided which driver you want, the next step is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/\n#repo#\n.git\n,\n \nfrom\n:\n \n#version#\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nFluent\n#Database#\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nCreating a Model\n\n\nNow let's create your first model. Models represent tables in your database and they are the primary method of interacting with your data. \n\n\nEach driver provides convenience model protocols (\nPostgreSQLModel\n, \nSQLiteModel\n, etc) that extend Fluent's base \nModel\n protocol. These convenience types make declaring models more concise by using standard values for ID key and type.\n\n\nFill in the Xcode placeholders below with the name of your chosen database, i.e., \nPostgreSQL\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nID\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nID\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe example above shows a simple model representing a user. You can make both structs and classes a model. You can even conform types that come from external modules. The only requirement is that these types conform to \nCodable\n, which must be declared on the base type for synthesized (automatic) conformance.\n\n\nTake a look at \nFluent \n Model\n for more information on creating models with custom ID types and keys.\n\n\nConfiguring the Database\n\n\nNow that you have a model, you can configure your database. This is done in \nconfigure.swift\n.\n\n\nRegister Provider\n\n\nThe first step is to register your database driver's provider.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nFluent\n#\nDatabase\n#\nProvider\n())\n\n\n\n// Other services....\n\n\n\n\n\n\nRegistering the provider will add all of the services required for your Fluent database to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nCustom Credentials\n\n\nIf you are using default configuration for your database (such as default credentials or other config) then this may be the only setup you need to perform. \n\n\nSee the documentation for your specific database type for more information about custom configuration.\n\n\n\n\nDanger\n\n\nfixme: Add links to config structs.\n\n\n\n\nCreating a Migration\n\n\nIf your database driver uses schemas (is a SQL database), you will need to create a \nMigration\n for your new model. Migrations allow Fluent to create a table for your model in a reliable, testable way. You can later create additional migrations to update or delete the model's table or even manipulate data in the table.\n\n\nTo create a migration, you will normally first create a new struct or class to hold the migration. However, models can take advantage of a convenient shortcut. When you create a migration from an existing model type, Fluent can infer an appropriate schema from the model's codable properties.\n\n\nYou can add the migration conformance to a model as an extension or on the base type declaration.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\nextension\n \nUser\n:\n \n#\nDatabase\n#\nMigration\n \n{\n \n}\n\n\n\n\n\n\nTake a look at \nFluent \n Migration\n if you are interested in learning more about custom migrations.\n\n\nConfiguring Migrations\n\n\nOnce you have created a migration, you must register it to Fluent using \nMigrationConfig\n. This is done in \nconfigure.swift\n.\n\n\nFill in the database ID  (\ndbid\n) from the table above, i.e., \npsql\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n// Configure migrations\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nUser\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n// Other services....\n\n\n\n\n\n\n\n\nTip\n\n\nIf the migration you are adding is also a model, you can use the \nadd(model:on:)\n convenience to automatically set the model's \ndefaultDatabase\n property. Otherwise, use the \nadd(migration:on)\n method.\n\n\n\n\nOnce you have the \nMigrationConfig\n added, you should be able to run your application and see the following:\n\n\nMigrating \n#dbid#\n DB\n\nMigrations \ncomplete\n\nServer starting on http://localhost:8080\n\n\n\n\n\nPerforming a Query\n\n\nNow that you have created a model and a corresponding schema in your database, let's make your first query.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nIf you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent model working.\n\n\nRaw Queries\n\n\nWith Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\". \n\n\nTo perform raw queries, you need access to a database connection. Vapor's \nRequest\n type has a number of conveniences for creating new database connections. The recommended method is \nwithPooledConnection(to:)\n.  Learn about other methods in \nDatabaseKit \n Overview \n Connections\n.\n\n\nrouter\n.\nget\n(\nraw\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\n#\ndbid\n#\n)\n \n{\n \nconn\n \nin\n\n        \n// perform raw query using conn\n\n    \n}\n\n\n}\n\n\n\n\n\n\nOnce you have the database connection, you can perform a query on it. You can learn more about the methods available in the database's documentation.", 
+            "text": "Getting Started with Fluent\n\n\nFluent (\nvapor/fluent\n) is a type-safe, fast, and easy-to-use ORM framework built for Swift.\nIt takes advantage of Swift's strong type system to provide an elegant foundation for building database integrations.\n\n\nChoosing a Driver\n\n\nFluent is a framework for building ORMs, not an ORM itself. To use Fluent, you will first need to choose a database driver to use. Fluent can support multiple databases and database drivers per application.\n\n\nBelow is a list of officially supported database drivers for Fluent. \n\n\n\n\n\n\n\n\ndatabase\n\n\nrepo\n\n\nversion\n\n\ndbid\n\n\nnotes\n\n\n\n\n\n\n\n\n\n\nPostgreSQL\n\n\nfluent-postgresql\n\n\n1.0.0\n\n\npsql\n\n\nRecommended\n. Open source, standards compliant SQL database. Available on most cloud hosting providers.\n\n\n\n\n\n\nMySQL\n\n\nfluent-mysql\n\n\n3.0.0\n\n\nmysql\n\n\nPopular open source SQL database. Available on most cloud hosting providers. This driver also supports MariaDB.\n\n\n\n\n\n\nSQLite\n\n\nfluent-sqlite\n\n\n3.0.0\n\n\nsqlite\n\n\nOpen source, embedded SQL database. Its simplistic nature makes it a great candiate for prototyping and testing.\n\n\n\n\n\n\nMongoDB\n\n\nfluent-mongo\n\n\nn/a\n\n\nmongo\n\n\nComing soon. Popular NoSQL database.\n\n\n\n\n\n\n\n\n\n\nNote\n\n\nReplace any Xcode placholders (\n#...#\n) in the code snippets below with information from the above table.\n\n\n\n\nYou can search GitHub for the tag \nfluent-database\n for a full list of official and third-party Fluent database drivers.\n\n\nPackage\n\n\nOnce you have decided which driver you want, the next step is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/\n#repo#\n.git\n,\n \nfrom\n:\n \n#version#\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nFluent\n#Database#\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nCreating a Model\n\n\nNow let's create your first model. Models represent tables in your database and they are the primary method of interacting with your data. \n\n\nEach driver provides convenience model protocols (\nPostgreSQLModel\n, \nSQLiteModel\n, etc) that extend Fluent's base \nModel\n protocol. These convenience types make declaring models more concise by using standard values for ID key and type.\n\n\nFill in the Xcode placeholders below with the name of your chosen database, i.e., \nPostgreSQL\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nID\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nID\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe example above shows a simple model representing a user. You can make both structs and classes a model. You can even conform types that come from external modules. The only requirement is that these types conform to \nCodable\n, which must be declared on the base type for synthesized (automatic) conformance.\n\n\nTake a look at \nFluent \n Model\n for more information on creating models with custom ID types and keys.\n\n\nConfiguring the Database\n\n\nNow that you have a model, you can configure your database. This is done in \nconfigure.swift\n.\n\n\nRegister Provider\n\n\nThe first step is to register your database driver's provider.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nFluent\n#\nDatabase\n#\nProvider\n())\n\n\n\n// Other services....\n\n\n\n\n\n\nRegistering the provider will add all of the services required for your Fluent database to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nCustom Credentials\n\n\nIf you are using default configuration for your database (such as default credentials or other config) then this may be the only setup you need to perform. \n\n\nSee the documentation for your specific database type for more information about custom configuration.\n\n\n\n\n\n\n\n\ndatabase\n\n\ndocs\n\n\napi docs\n\n\n\n\n\n\n\n\n\n\nPostgreSQL\n\n\nPostgreSQL \n Getting Started\n\n\nComing soon\n\n\n\n\n\n\nMySQL\n\n\nMySQL \n Getting Started\n\n\nComing soon\n\n\n\n\n\n\nSQLite\n\n\nSQLite \n Getting Started\n\n\nSQLiteDatabase\n\n\n\n\n\n\n\n\nCreating a Migration\n\n\nIf your database driver uses schemas (is a SQL database), you will need to create a \nMigration\n for your new model. Migrations allow Fluent to create a table for your model in a reliable, testable way. You can later create additional migrations to update or delete the model's table or even manipulate data in the table.\n\n\nTo create a migration, you will normally first create a new struct or class to hold the migration. However, models can take advantage of a convenient shortcut. When you create a migration from an existing model type, Fluent can infer an appropriate schema from the model's codable properties.\n\n\nYou can add the migration conformance to a model as an extension or on the base type declaration.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\nextension\n \nUser\n:\n \n#\nDatabase\n#\nMigration\n \n{\n \n}\n\n\n\n\n\n\nTake a look at \nFluent \n Migration\n if you are interested in learning more about custom migrations.\n\n\nConfiguring Migrations\n\n\nOnce you have created a migration, you must register it to Fluent using \nMigrationConfig\n. This is done in \nconfigure.swift\n.\n\n\nFill in the database ID  (\ndbid\n) from the table above, i.e., \npsql\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\nimport\n \nVapor\n\n\n\n// Configure migrations\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nUser\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n// Other services....\n\n\n\n\n\n\n\n\nTip\n\n\nIf the migration you are adding is also a model, you can use the \nadd(model:on:)\n convenience to automatically set the model's \ndefaultDatabase\n property. Otherwise, use the \nadd(migration:on)\n method.\n\n\n\n\nOnce you have the \nMigrationConfig\n added, you should be able to run your application and see the following:\n\n\nMigrating \n#dbid#\n DB\n\nMigrations \ncomplete\n\nServer starting on http://localhost:8080\n\n\n\n\n\nPerforming a Query\n\n\nNow that you have created a model and a corresponding schema in your database, let's make your first query.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nIf you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent model working.\n\n\nRaw Queries\n\n\nWith Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\". \n\n\nTo perform raw queries, you need access to a database connection. Vapor's \nRequest\n type has a number of conveniences for creating new database connections. The recommended method is \nwithPooledConnection(to:)\n.  Learn about other methods in \nDatabaseKit \n Overview \n Connections\n.\n\n\nrouter\n.\nget\n(\nraw\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\n#\ndbid\n#\n)\n \n{\n \nconn\n \nin\n\n        \n// perform raw query using conn\n\n    \n}\n\n\n}\n\n\n\n\n\n\nOnce you have the database connection, you can perform a query on it. You can learn more about the methods available in the database's documentation.", 
             "title": "Getting Started"
         }, 
         {
@@ -1022,7 +1022,7 @@
         }, 
         {
             "location": "/fluent/getting-started/#custom-credentials", 
-            "text": "If you are using default configuration for your database (such as default credentials or other config) then this may be the only setup you need to perform.   See the documentation for your specific database type for more information about custom configuration.   Danger  fixme: Add links to config structs.", 
+            "text": "If you are using default configuration for your database (such as default credentials or other config) then this may be the only setup you need to perform.   See the documentation for your specific database type for more information about custom configuration.     database  docs  api docs      PostgreSQL  PostgreSQL   Getting Started  Coming soon    MySQL  MySQL   Getting Started  Coming soon    SQLite  SQLite   Getting Started  SQLiteDatabase", 
             "title": "Custom Credentials"
         }, 
         {
@@ -1137,13 +1137,13 @@
         }, 
         {
             "location": "/fluent/querying/", 
-            "text": "Querying Models\n\n\nOnce you have a \nmodel\n you can start querying your database to create, read, update, and delete data.\n\n\nConnection\n\n\nThe first thing you need to query your database, is a connection to it. Luckily, they are easy to get.\n\n\nRequest\n\n\nThe easiest way to connect to your database is simply using the incoming \nRequest\n. This will use the model's \ndefaultDatabase\n property to automatically fetch a pooled connection to the database. \n\n\nrouter\n.\nget\n(\ngalaxies\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nGalaxy\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nYou can use convenience methods on a \nContainer\n to create connections manually. Learn more about that in \nDatabaseKit \n Overview \n Connections\n.\n\n\nCreate\n\n\nOne of the first things you will need to do is save some data to your database. You do this by initializing an instance of your model then calling \ncreate(on:)\n.\n\n\nrouter\n.\npost\n(\ngalaxies\n)\n \n{\n \nreq\n \nin\n\n    \nlet\n \ngalaxy\n:\n \nGalaxy\n \n=\n \n...\n \n    \nreturn\n \ngalaxy\n.\ncreate\n(\non\n:\n \nreq\n)\n\n\n}\n\n\n\n\n\n\nThe create method will return the saved model. The returned model will include any generated fields such as the ID or fields with default values.\n\n\nIf your model also conforms to \nContent\n you can return the result of the Fluent query directly.\n\n\nRead\n\n\nTo read models from the database, you can use \nquery(on:)\n or \nfind(_:on:)\n.\n\n\nFind\n\n\nThe easiest way to find a single model is by passing its ID to \nfind(_:on:)\n.\n\n\nGalaxy\n.\nfind\n(\n42\n,\n \non\n:\n \nconn\n)\n\n\n\n\n\n\nThe result will be a future containing an optional value. You can use \nunwrap(or:)\n to unwrap the future value or throw an error.\n\n\nGalaxy\n.\nfind\n(\n42\n,\n \non\n:\n \nconn\n).\nunwrap\n(\nor\n:\n \nAbort\n(...))\n\n\n\n\n\n\nQuery\n\n\nYou can use the \nquery(on:)\n method to build database queries with filters, joins, sorts, and more. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nname\n \n==\n \nMilky Way\n)\n\n\n\n\n\n\nFilter\n\n\nThe \nfilter(_:)\n method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.\n\n\nCalls to filter can be chained and even grouped.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nmass\n \n=\n \n500\n).\nfilter\n(\n\\\n.\ntype\n \n==\n \n.\nspiral\n)\n\n\n\n\n\n\nBelow is a list of all supported operators.\n\n\n\n\n\n\n\n\noperator\n\n\ntype\n\n\n\n\n\n\n\n\n\n\n==\n\n\nEqual\n\n\n\n\n\n\n!=\n\n\nNot equal\n\n\n\n\n\n\n\n\nGreater than\n\n\n\n\n\n\n\n\nLess than\n\n\n\n\n\n\n=\n\n\nGreater than or equal\n\n\n\n\n\n\n=\n\n\nLess than or equal\n\n\n\n\n\n\n\n\nBy default, all chained filters will be used to limit the result set. You can use filter groups to change this behavior.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\ngroup\n(.\nor\n)\n \n{\n\n    \n$0\n.\nfilter\n(\n\\\n.\nmass\n \n=\n \n250\n).\nfilter\n(\n\\\n.\nmass\n \n=\n \n500\n)\n\n\n}.\nfilter\n(\n\\\n.\ntype\n \n==\n \n.\nspiral\n)\n\n\n\n\n\n\nThe above query will include results where the galaxy's mass is below 250 \nor\n above 500 \nand\n the type is spiral.\n\n\nRange\n\n\nYou can apply Swift ranges to a query builder to limit the result set.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nrange\n(..\n50\n)\n\n\n\n\n\n\nThe above query will include only the first 50 results.\n\n\nFor more information on ranges, see docs for Swift's \nRange\n type.\n\n\nSort\n\n\nQuery results can be sorted by a given field. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nsort\n(\n\\\n.\nname\n,\n \n.\ndescending\n)\n\n\n\n\n\n\nYou can sort by multiple fields to perform tie breaking behavior where there is duplicate information in the one of the sorted fields.\n\n\nJoin\n\n\nOther models can be joined to an existing query in order to further filter the results. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\njoin\n(\n\\\nPlanet\n.\ngalaxyID\n,\n \nto\n:\n \n\\\nGalaxy\n.\nid\n)\n\n    \n.\nfilter\n(\n\\\nPlanet\n.\nname\n \n==\n \nEarth\n)\n\n\n\n\n\n\nOnce a table has been joined using \njoin(_:to:)\n, you can use fully-qualified key paths to filter results based on data in the joined table.\n\n\nThe above query fetches all galaxies that have a planet named Earth.\n\n\nYou can even decode the joined models using \nalsoDecode(...)\n.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n)\n\n    \n// join Planet and filter\n\n    \n.\nalsoDecode\n(\nPlanet\n.\nself\n).\nall\n()\n\n\n\n\n\n\nThe above query will decode an array of \n(Galaxy, Planet)\n tuples.\n\n\nFetch\n\n\nTo fetch the results of a query, use \nall()\n, \nchunk(max:)\n,  \nfirst()\n or an aggregate method.\n\n\nAll\n\n\nThe most common method for fetching results is with \nall()\n. This will return all matching results according to any fliters applied. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nall\n()\n\n\n\n\n\n\nWhen combined with \nrange(_:)\n, you can efficiently limit how many results are returned by the database.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nrange\n(..\n50\n).\nall\n()\n\n\n\n\n\n\nChunk\n\n\nFor situations where memory conservation is important, use \nchunk(...)\n. This method returns the result set in multiple calls of a maximum chunk size.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nchunk\n(\nmax\n:\n \n32\n)\n \n{\n \ngalaxies\n \nin\n\n    \nprint\n(\ngalaxies\n)\n \n// Array of 32 or less galaxies\n\n\n}\n\n\n\n\n\n\nFirst\n\n\nThe \nfirst()\n method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nname\n \n==\n \nMilky Way\n).\nfirst\n()\n\n\n\n\n\n\nThis method is more efficient than calling \nall\n and getting the first item in the array.\n\n\nUpdate\n\n\nAfter a model has been fetched from the database and mutated, you can use \nupdate(on:)\n to save the changes.\n\n\nvar\n \nplanet\n:\n \nPlanet\n \n...\n \n// fetched from database\n\n\nplanet\n.\nname\n \n=\n \nEarth\n\n\nplanet\n.\nupdate\n(\non\n:\n \nconn\n)\n\n\n\n\n\n\nDelete\n\n\nAfter a model has been fetched from the database, you can use \ndelete(on:)\n to delete it.\n\n\nvar\n \nplanet\n:\n \nPlanet\n \n...\n \n// fetched from database\n\n\nplanet\n.\ndelete\n(\non\n:\n \nconn\n)", 
+            "text": "Fluent Queries\n\n\nOnce you have a \nmodel\n you can start querying your database to create, read, update, and delete data.\n\n\nConnection\n\n\nThe first thing you need to query your database, is a connection to it. Luckily, they are easy to get.\n\n\nRequest\n\n\nThe easiest way to connect to your database is simply using the incoming \nRequest\n. This will use the model's \ndefaultDatabase\n property to automatically fetch a pooled connection to the database. \n\n\nrouter\n.\nget\n(\ngalaxies\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nGalaxy\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nYou can use convenience methods on a \nContainer\n to create connections manually. Learn more about that in \nDatabaseKit \n Overview \n Connections\n.\n\n\nCreate\n\n\nOne of the first things you will need to do is save some data to your database. You do this by initializing an instance of your model then calling \ncreate(on:)\n.\n\n\nrouter\n.\npost\n(\ngalaxies\n)\n \n{\n \nreq\n \nin\n\n    \nlet\n \ngalaxy\n:\n \nGalaxy\n \n=\n \n...\n \n    \nreturn\n \ngalaxy\n.\ncreate\n(\non\n:\n \nreq\n)\n\n\n}\n\n\n\n\n\n\nThe create method will return the saved model. The returned model will include any generated fields such as the ID or fields with default values.\n\n\nIf your model also conforms to \nContent\n you can return the result of the Fluent query directly.\n\n\nRead\n\n\nTo read models from the database, you can use \nquery(on:)\n or \nfind(_:on:)\n.\n\n\nFind\n\n\nThe easiest way to find a single model is by passing its ID to \nfind(_:on:)\n.\n\n\nGalaxy\n.\nfind\n(\n42\n,\n \non\n:\n \nconn\n)\n\n\n\n\n\n\nThe result will be a future containing an optional value. You can use \nunwrap(or:)\n to unwrap the future value or throw an error.\n\n\nGalaxy\n.\nfind\n(\n42\n,\n \non\n:\n \nconn\n).\nunwrap\n(\nor\n:\n \nAbort\n(...))\n\n\n\n\n\n\nQuery\n\n\nYou can use the \nquery(on:)\n method to build database queries with filters, joins, sorts, and more. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nname\n \n==\n \nMilky Way\n)\n\n\n\n\n\n\nFilter\n\n\nThe \nfilter(_:)\n method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.\n\n\nCalls to filter can be chained and even grouped.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nmass\n \n=\n \n500\n).\nfilter\n(\n\\\n.\ntype\n \n==\n \n.\nspiral\n)\n\n\n\n\n\n\nBelow is a list of all supported operators.\n\n\n\n\n\n\n\n\noperator\n\n\ntype\n\n\n\n\n\n\n\n\n\n\n==\n\n\nEqual\n\n\n\n\n\n\n!=\n\n\nNot equal\n\n\n\n\n\n\n\n\nGreater than\n\n\n\n\n\n\n\n\nLess than\n\n\n\n\n\n\n=\n\n\nGreater than or equal\n\n\n\n\n\n\n=\n\n\nLess than or equal\n\n\n\n\n\n\n\n\nBy default, all chained filters will be used to limit the result set. You can use filter groups to change this behavior.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\ngroup\n(.\nor\n)\n \n{\n\n    \n$0\n.\nfilter\n(\n\\\n.\nmass\n \n=\n \n250\n).\nfilter\n(\n\\\n.\nmass\n \n=\n \n500\n)\n\n\n}.\nfilter\n(\n\\\n.\ntype\n \n==\n \n.\nspiral\n)\n\n\n\n\n\n\nThe above query will include results where the galaxy's mass is below 250 \nor\n above 500 \nand\n the type is spiral.\n\n\nRange\n\n\nYou can apply Swift ranges to a query builder to limit the result set.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nrange\n(..\n50\n)\n\n\n\n\n\n\nThe above query will include only the first 50 results.\n\n\nFor more information on ranges, see docs for Swift's \nRange\n type.\n\n\nSort\n\n\nQuery results can be sorted by a given field. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nsort\n(\n\\\n.\nname\n,\n \n.\ndescending\n)\n\n\n\n\n\n\nYou can sort by multiple fields to perform tie breaking behavior where there is duplicate information in the one of the sorted fields.\n\n\nJoin\n\n\nOther models can be joined to an existing query in order to further filter the results. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\njoin\n(\n\\\nPlanet\n.\ngalaxyID\n,\n \nto\n:\n \n\\\nGalaxy\n.\nid\n)\n\n    \n.\nfilter\n(\n\\\nPlanet\n.\nname\n \n==\n \nEarth\n)\n\n\n\n\n\n\nOnce a table has been joined using \njoin(_:to:)\n, you can use fully-qualified key paths to filter results based on data in the joined table.\n\n\nThe above query fetches all galaxies that have a planet named Earth.\n\n\nYou can even decode the joined models using \nalsoDecode(...)\n.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n)\n\n    \n// join Planet and filter\n\n    \n.\nalsoDecode\n(\nPlanet\n.\nself\n).\nall\n()\n\n\n\n\n\n\nThe above query will decode an array of \n(Galaxy, Planet)\n tuples.\n\n\nFetch\n\n\nTo fetch the results of a query, use \nall()\n, \nchunk(max:closure:)\n,  \nfirst()\n or an aggregate method.\n\n\nAll\n\n\nThe most common method for fetching results is with \nall()\n. This will return all matching results according to any fliters applied. \n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nall\n()\n\n\n\n\n\n\nWhen combined with \nrange(_:)\n, you can efficiently limit how many results are returned by the database.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nrange\n(..\n50\n).\nall\n()\n\n\n\n\n\n\nChunk\n\n\nFor situations where memory conservation is important, use \nchunk(...)\n. This method returns the result set in multiple calls of a maximum chunk size.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nchunk\n(\nmax\n:\n \n32\n)\n \n{\n \ngalaxies\n \nin\n\n    \nprint\n(\ngalaxies\n)\n \n// Array of 32 or less galaxies\n\n\n}\n\n\n\n\n\n\nFirst\n\n\nThe \nfirst()\n method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.\n\n\nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nname\n \n==\n \nMilky Way\n).\nfirst\n()\n\n\n\n\n\n\nThis method is more efficient than calling \nall\n and getting the first item in the array.\n\n\nUpdate\n\n\nAfter a model has been fetched from the database and mutated, you can use \nupdate(on:)\n to save the changes.\n\n\nvar\n \nplanet\n:\n \nPlanet\n \n...\n \n// fetched from database\n\n\nplanet\n.\nname\n \n=\n \nEarth\n\n\nplanet\n.\nupdate\n(\non\n:\n \nconn\n)\n\n\n\n\n\n\nDelete\n\n\nAfter a model has been fetched from the database, you can use \ndelete(on:)\n to delete it.\n\n\nvar\n \nplanet\n:\n \nPlanet\n \n...\n \n// fetched from database\n\n\nplanet\n.\ndelete\n(\non\n:\n \nconn\n)", 
             "title": "Querying"
         }, 
         {
-            "location": "/fluent/querying/#querying-models", 
+            "location": "/fluent/querying/#fluent-queries", 
             "text": "Once you have a  model  you can start querying your database to create, read, update, and delete data.", 
-            "title": "Querying Models"
+            "title": "Fluent Queries"
         }, 
         {
             "location": "/fluent/querying/#connection", 
@@ -1197,7 +1197,7 @@
         }, 
         {
             "location": "/fluent/querying/#fetch", 
-            "text": "To fetch the results of a query, use  all() ,  chunk(max:) ,   first()  or an aggregate method.", 
+            "text": "To fetch the results of a query, use  all() ,  chunk(max:closure:) ,   first()  or an aggregate method.", 
             "title": "Fetch"
         }, 
         {
@@ -1227,7 +1227,7 @@
         }, 
         {
             "location": "/fluent/migrations/", 
-            "text": "Fluent Migrations\n\n\nMigrations allow you to make organized, testable, and reliable changes to your database's structure--\neven while it's in production.\n\n\nMigrations are often used for preparing a database schema for your models. However, they can also be used to \nmake normal queries to your database.\n\n\nIn this guide we will cover creating both types of migrations.\n\n\nCreating and Deleting Schemas\n\n\nLet's take a look at how we can use migrations to prepare a schema supporting database to store a theoretical \nGalaxy\n model.\n\n\nFill in the Xcode placeholders below with your database's name from \nGetting Started \n Choosing a Driver\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nGalaxy\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \nvar\n \nid\n:\n \nID\n?\n\n    \nvar\n \nname\n:\n \nString\n\n\n}\n\n\n\n\n\n\nAutomatic Model Migrations\n\n\nModels provide a shortcut for declaring database migrations. If you conform a type that conforms to \nModel\n to \nMigration\n, Fluent can infer the model's properties and automatically implement the \nprepare(...)\n and \nrevert(...)\n methods.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nextension\n \nGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n \n}\n\n\n\n\n\n\nThis method is especially useful for quick prototyping and simple setups. For most other situations you should consider creating a normal, custom migration. \n\n\nAdd this automatic migration to your \nMigrationConfig\n using the \nadd(model:database:)\n method. This is done in \nconfigure.swift\n.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nGalaxy\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nThe \nadd(model:database:)\n method will automatically set the model's \ndefaultDatabase\n property. \n\n\nCustom Migrations\n\n\nWe can customize the table created for our model by creating a migration and using the static \ncreate\n and \ndelete\n methods on \nDatabase\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nCreating a Schema\n\n\nThe most important method in a migration is \nprepare(...)\n. This is responsible for effecting the migration's changes. For our \nCreateGalaxy\n migration, we will use our database's static \ncreate\n method to create a schema.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\ncreate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nid\n,\n \nisIdentifier\n:\n \ntrue\n)\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nTo create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the \nSchemaBuilder\n. This builder has convenience methods for declaring fields in the schema.\n\n\nYou can use the \nfield(for: \n#KeyPath#\n)\n method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by \n\\.\n), Fluent can see what type those properties are. For most common types (\nString\n, \nInt\n, \nDouble\n, etc) Fluent will automatically be able to determine the best database field type to use.\n\n\nYou can also choose to manually select which database field type to use for a given field.\n\n\ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n,\n \ntype\n:\n \n#\nDataType\n#\n)\n\n\n\n\n\n\nEach database has it's own unique data types, so refer to your database's documentation for more information.\n\n\n\n\nDanger\n\n\nfixme: links to db's data types\n\n\n\n\nDeleting a Schema\n\n\nEach migration should also include a method for \nreverting\n the changes it makes. It is used when you boot your \napp with the \n--revert\n option. \n\n\nFor a migration that creates a table in the database, the reversion is quite simple: delete the table.\n\n\nTo implement \nrevert\n for our model, we can use our database's static \ndelete(...)\n method to indicate that we would like to delete the schema.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconnection\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\ndelete\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconnection\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nTo delete a schema, you pass a model type and connection as the two required parameters. That's it.\n\n\nYou can always choose to skip a reversion by simplying returning \nconn.future(())\n. But note that they are especially useful when testing and debugging your migrations.\n\n\nAdd this custom migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in your \nconfigure.swift\n file.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nCreateGalaxy\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nMake sure to also set the \ndefaultDatabase\n property on your model when using a custom migration. \n\n\nGalaxy\n.\ndefaultDatabase\n \n=\n \n.\n#\ndbid\n#\n\n\n\n\n\n\nUpdating a Schema\n\n\nAfter you deploy your application to production, you may find it necessary to add or remove fields on an existing model. You can achieve this by creating a new migration. \n\n\nFor this example, let's assume we want to add a new property \nmass\n to the \nGalaxy\n model from the previous section.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nGalaxy\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \nvar\n \nid\n:\n \nID\n?\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nmass\n:\n \nInt\n\n\n}\n\n\n\n\n\n\nSince our previous migration created a table with fields for both \nid\n and \nname\n, we need to update that table and add a field for \nmass\n. We can do this by using the static \nupdate\n method on \nDatabase\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nOur prepare method will look very similar to the prepare method for a new table, except it will only contain our newly added field.\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\nupdate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nmass\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAll methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See \nSchemaUpdater\n for a list of all available methods.\n\n\nTo revert this change, we must delete the \nmass\n field from the table.\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\nupdate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n        \nbuilder\n.\ndeleteField\n(\nfor\n:\n \n\\\n.\nmass\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAdd this migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in your \nconfigure.swift\n file.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\n// ...\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nAddGalaxyMass\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nMigrating Data\n\n\nWhile migrations are useful for creating and updating schemas in SQL databases, they can also be used for more general purposes in any database. Migrations are passed a connection upon running which can be used to perform arbitrary database queries.\n\n\nFor this example, let's assume we want to do a data cleanup migration on our \nGalaxy\n model and delete any galaxies with a mass of \n0\n. \n\n\nThe first step is to create our new migration type.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nIn the prepare method of this migration, we will perform a query to delete all galaxies which have a mass equal to \n0\n.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nmass\n \n==\n \n0\n).\ndelete\n()\n\n    \n}\n\n\n    \n// ...\n\n\n}\n\n\n\n\n\n\nThere is no way to undo this migration since it is destructive. You can omit the \nrevert(...)\n method by returning a pre-completed future.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ...\n\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconn\n.\nfuture\n(())\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAdd this migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in \nconfigure.swift\n.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\n// ...\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nGalaxyMassCleanup\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)", 
+            "text": "Fluent Migrations\n\n\nMigrations allow you to make organized, testable, and reliable changes to your database's structure--\neven while it's in production.\n\n\nMigrations are often used for preparing a database schema for your models. However, they can also be used to \nmake normal queries to your database.\n\n\nIn this guide we will cover creating both types of migrations.\n\n\nCreating and Deleting Schemas\n\n\nLet's take a look at how we can use migrations to prepare a schema supporting database to store a theoretical \nGalaxy\n model.\n\n\nFill in the Xcode placeholders below with your database's name from \nGetting Started \n Choosing a Driver\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nGalaxy\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \nvar\n \nid\n:\n \nID\n?\n\n    \nvar\n \nname\n:\n \nString\n\n\n}\n\n\n\n\n\n\nAutomatic Model Migrations\n\n\nModels provide a shortcut for declaring database migrations. If you conform a type that conforms to \nModel\n to \nMigration\n, Fluent can infer the model's properties and automatically implement the \nprepare(...)\n and \nrevert(...)\n methods.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nextension\n \nGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n \n}\n\n\n\n\n\n\nThis method is especially useful for quick prototyping and simple setups. For most other situations you should consider creating a normal, custom migration. \n\n\nAdd this automatic migration to your \nMigrationConfig\n using the \nadd(model:database:)\n method. This is done in \nconfigure.swift\n.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nGalaxy\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nThe \nadd(model:database:)\n method will automatically set the model's \ndefaultDatabase\n property. \n\n\nCustom Migrations\n\n\nWe can customize the table created for our model by creating a migration and using the static \ncreate\n and \ndelete\n methods on \nDatabase\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nCreating a Schema\n\n\nThe most important method in a migration is \nprepare(...)\n. This is responsible for effecting the migration's changes. For our \nCreateGalaxy\n migration, we will use our database's static \ncreate\n method to create a schema.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\ncreate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nid\n,\n \nisIdentifier\n:\n \ntrue\n)\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nTo create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the \nSchemaBuilder\n. This builder has convenience methods for declaring fields in the schema.\n\n\nYou can use the \nfield(for: \n#KeyPath#\n)\n method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by \n\\.\n), Fluent can see what type those properties are. For most common types (\nString\n, \nInt\n, \nDouble\n, etc) Fluent will automatically be able to determine the best database field type to use.\n\n\nYou can also choose to manually select which database field type to use for a given field.\n\n\ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n,\n \ntype\n:\n \n#\nDataType\n#\n)\n\n\n\n\n\n\nEach database has it's own unique data types, so refer to your database's documentation for more information.\n\n\n\n\n\n\n\n\ndatabase\n\n\ndocs\n\n\napi docs\n\n\n\n\n\n\n\n\n\n\nPostgreSQL\n\n\nPostgreSQL \n Getting Started\n\n\nComing soon\n\n\n\n\n\n\nMySQL\n\n\nMySQL \n Getting Started\n\n\nComing soon\n\n\n\n\n\n\nSQLite\n\n\nSQLite \n Getting Started\n\n\nSQLiteDataType\n\n\n\n\n\n\n\n\nDeleting a Schema\n\n\nEach migration should also include a method for \nreverting\n the changes it makes. It is used when you boot your \napp with the \n--revert\n option. \n\n\nFor a migration that creates a table in the database, the reversion is quite simple: delete the table.\n\n\nTo implement \nrevert\n for our model, we can use our database's static \ndelete(...)\n method to indicate that we would like to delete the schema.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nCreateGalaxy\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconnection\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\ndelete\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconnection\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nTo delete a schema, you pass a model type and connection as the two required parameters. That's it.\n\n\nYou can always choose to skip a reversion by simplying returning \nconn.future(())\n. But note that they are especially useful when testing and debugging your migrations.\n\n\nAdd this custom migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in your \nconfigure.swift\n file.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nCreateGalaxy\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nMake sure to also set the \ndefaultDatabase\n property on your model when using a custom migration. \n\n\nGalaxy\n.\ndefaultDatabase\n \n=\n \n.\n#\ndbid\n#\n\n\n\n\n\n\nUpdating a Schema\n\n\nAfter you deploy your application to production, you may find it necessary to add or remove fields on an existing model. You can achieve this by creating a new migration. \n\n\nFor this example, let's assume we want to add a new property \nmass\n to the \nGalaxy\n model from the previous section.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nGalaxy\n:\n \n#\nDatabase\n#\nModel\n \n{\n\n    \nvar\n \nid\n:\n \nID\n?\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nmass\n:\n \nInt\n\n\n}\n\n\n\n\n\n\nSince our previous migration created a table with fields for both \nid\n and \nname\n, we need to update that table and add a field for \nmass\n. We can do this by using the static \nupdate\n method on \nDatabase\n.\n\n\nimport\n \nFluent\n#\nDatabase\n#\n\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nOur prepare method will look very similar to the prepare method for a new table, except it will only contain our newly added field.\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\nupdate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n            \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nmass\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAll methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See \nSchemaUpdater\n for a list of all available methods.\n\n\nTo revert this change, we must delete the \nmass\n field from the table.\n\n\nstruct\n \nAddGalaxyMass\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \n#\nDatabase\n#\nDatabase\n.\nupdate\n(\nGalaxy\n.\nself\n,\n \non\n:\n \nconn\n)\n \n{\n \nbuilder\n \nin\n\n        \nbuilder\n.\ndeleteField\n(\nfor\n:\n \n\\\n.\nmass\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAdd this migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in your \nconfigure.swift\n file.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\n// ...\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nAddGalaxyMass\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n\n\n\nMigrating Data\n\n\nWhile migrations are useful for creating and updating schemas in SQL databases, they can also be used for more general purposes in any database. Migrations are passed a connection upon running which can be used to perform arbitrary database queries.\n\n\nFor this example, let's assume we want to do a data cleanup migration on our \nGalaxy\n model and delete any galaxies with a mass of \n0\n. \n\n\nThe first step is to create our new migration type.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ... \n\n\n}\n\n\n\n\n\n\nIn the prepare method of this migration, we will perform a query to delete all galaxies which have a mass equal to \n0\n.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nGalaxy\n.\nquery\n(\non\n:\n \nconn\n).\nfilter\n(\n\\\n.\nmass\n \n==\n \n0\n).\ndelete\n()\n\n    \n}\n\n\n    \n// ...\n\n\n}\n\n\n\n\n\n\nThere is no way to undo this migration since it is destructive. You can omit the \nrevert(...)\n method by returning a pre-completed future.\n\n\nstruct\n \nGalaxyMassCleanup\n:\n \n#\nDatabase\n#\nMigration\n \n{\n\n    \n// ...\n\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconn\n:\n \n#\nDatabase\n#\nConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconn\n.\nfuture\n(())\n\n    \n}\n\n\n}\n\n\n\n\n\n\nAdd this migration to your \nMigrationConfig\n using the \nadd(migration:database:)\n method. This is done in \nconfigure.swift\n.\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\n// ...\n\n\nmigrations\n.\nadd\n(\nmigration\n:\n \nGalaxyMassCleanup\n.\nself\n,\n \ndatabase\n:\n \n.\n#\ndbid\n#\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)", 
             "title": "Migrations"
         }, 
         {
@@ -1252,7 +1252,7 @@
         }, 
         {
             "location": "/fluent/migrations/#creating-a-schema", 
-            "text": "The most important method in a migration is  prepare(...) . This is responsible for effecting the migration's changes. For our  CreateGalaxy  migration, we will use our database's static  create  method to create a schema.  import   Fluent # Database #  struct   CreateGalaxy :   # Database # Migration   { \n     // ...  \n\n     static   func   prepare ( on   conn :   # Database # Connection )   -   Future Void   { \n         return   # Database # Database . create ( Galaxy . self ,   on :   conn )   {   builder   in \n             builder . field ( for :   \\ . id ,   isIdentifier :   true ) \n             builder . field ( for :   \\ . name ) \n         } \n     }  }   To create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the  SchemaBuilder . This builder has convenience methods for declaring fields in the schema.  You can use the  field(for:  #KeyPath# )  method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by  \\. ), Fluent can see what type those properties are. For most common types ( String ,  Int ,  Double , etc) Fluent will automatically be able to determine the best database field type to use.  You can also choose to manually select which database field type to use for a given field.  try   builder . field ( for :   \\ . name ,   type :   # DataType # )   Each database has it's own unique data types, so refer to your database's documentation for more information.   Danger  fixme: links to db's data types", 
+            "text": "The most important method in a migration is  prepare(...) . This is responsible for effecting the migration's changes. For our  CreateGalaxy  migration, we will use our database's static  create  method to create a schema.  import   Fluent # Database #  struct   CreateGalaxy :   # Database # Migration   { \n     // ...  \n\n     static   func   prepare ( on   conn :   # Database # Connection )   -   Future Void   { \n         return   # Database # Database . create ( Galaxy . self ,   on :   conn )   {   builder   in \n             builder . field ( for :   \\ . id ,   isIdentifier :   true ) \n             builder . field ( for :   \\ . name ) \n         } \n     }  }   To create a schema, you must pass a model type and connection as the first two parameters. The third parameter is a closure that accepts the  SchemaBuilder . This builder has convenience methods for declaring fields in the schema.  You can use the  field(for:  #KeyPath# )  method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by  \\. ), Fluent can see what type those properties are. For most common types ( String ,  Int ,  Double , etc) Fluent will automatically be able to determine the best database field type to use.  You can also choose to manually select which database field type to use for a given field.  try   builder . field ( for :   \\ . name ,   type :   # DataType # )   Each database has it's own unique data types, so refer to your database's documentation for more information.     database  docs  api docs      PostgreSQL  PostgreSQL   Getting Started  Coming soon    MySQL  MySQL   Getting Started  Coming soon    SQLite  SQLite   Getting Started  SQLiteDataType", 
             "title": "Creating a Schema"
         }, 
         {
@@ -2512,7 +2512,7 @@
         }, 
         {
             "location": "/version/upgrading/", 
-            "text": "Upgrading Versions\n\n\nThis document provides information about changes between version and tips for migrating your projects. \n\n\n2.4 to 3.0\n\n\nVapor 3 has been rewritten from the ground up to be async and event-driven. This release contains the most changes of any previous release (and most likely any future release). \n\n\nBecause of this, it is recommended that to migrate your projects you start by creating a new, empty template and migrate by copy / pasting code over to the new project.\n\n\nWe recommend reading the \nGetting Started \n Hello, world!\n section for Vapor 3 to familiarize yourself with the new APIs.\n\n\nAsync\n\n\nThe biggest change in Vapor 3 is that the framework is now completely asynchronous. When you call methods that need to perform slow work like network requests or disk access instead of blocking they will now return a \nFuture\nT\n. \n\n\nFutures are values that may not exist yet, so you cannot interact with them directly. Instead, you must use \nmap\n/\nflatMap\n to access the values.\n\n\n// vapor 2\n\n\nlet\n \nres\n \n=\n \ntry\n \ndrop\n.\nclient\n.\nget\n(\nhttp://vapor.codes\n)\n\n\nprint\n(\nres\n.\nstatus\n)\n \n// HTTPStatus\n\n\nreturn\n \nres\n.\nstatus\n\n\n\n// vapor 3\n\n\nlet\n \nf\n \n=\n \ntry\n \nreq\n.\nclient\n().\nget\n(\nhttp://vapor.codes\n).\nmap\n \n{\n \nres\n \nin\n\n    \nprint\n(\nres\n.\nhttp\n.\nstatus\n)\n \n// HTTPStatus\n\n    \nreturn\n \nres\n.\nhttp\n.\nstatus\n\n\n}\n\n\nprint\n(\nf\n)\n \n// Future\nHTTPStatus\n\n\n\n\n\n\nSee \nAsync \n Getting Started\n to learn more.\n\n\nApplication \n Services\n\n\nDroplet\n has been renamed to \nApplication\n and is now a service-container. In Vapor 2, the \nDroplet\n had stored properties for things you would need during development (like views, hashers, etc). In Vapor 3, this is all done via services. \n\n\nWhile the \nApplication\n \nis\n a service-container, you should not use it from your route closures. This is to prevent race conditions since Vapor runs on multiple threads (event loops). Instead, use the \nRequest\n that is supplied to your route closure. This has a \ncopy\n of all of the application's services for you to use.\n\n\n// vapor 2\n\n\nreturn\n \ntry\n \ndrop\n.\nview\n.\nmake\n(\nmyView\n)\n\n\n\n// vapor 3\n\n\nreturn\n \ntry\n \nreq\n.\nmake\n(\nViewRenderer\n.\nself\n).\nrender\n(\nmyView\n)\n\n\n// shorthand\n\n\nreturn\n \ntry\n \nreq\n.\nview\n().\nrender\n(\nmyView\n)\n\n\n\n\n\n\nSee \nService \n Getting Started\n to learn more.\n\n\nDatabase Connections\n\n\nIn Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant. \n\n\nIn order to create a \nQueryBuilder\n in Fluent 3, you will need access to something \nDatabaseConnectable\n. Most often you can just use the incoming \nRequest\n, but you can also create connections manually if you need. \n\n\n// vapor 2\n\n\nUser\n.\nmakeQuery\n().\nall\n()\n\n\n\n// vapor 3\n\n\nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n\n\n\n\nSee \nDatabaseKit \n Getting Started\n to learn more.\n\n\nWork in progress\n\n\nThis migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.\n\n\nJoin the \n#upgrading-to-3\n in Vapor's team chat to ask questions and get help in real time.\n\n\nAlso check out \nGetting started with Vapor 3\n, an in-depth article about the differences between Vapor 2 and 3. This article was written by two developers from an app development company using Vapor.", 
+            "text": "Upgrading Versions\n\n\nThis document provides information about changes between version and tips for migrating your projects. \n\n\n2.4 to 3.0\n\n\nVapor 3 has been rewritten from the ground up to be async and event-driven. This release contains the most changes of any previous release (and most likely any future release). \n\n\nBecause of this, it is recommended that to migrate your projects you start by creating a new, empty template and migrate by copy / pasting code over to the new project.\n\n\nWe recommend reading the \nGetting Started \n Hello, world!\n section for Vapor 3 to familiarize yourself with the new APIs.\n\n\nAsync\n\n\nThe biggest change in Vapor 3 is that the framework is now completely asynchronous. When you call methods that need to perform slow work like network requests or disk access instead of blocking they will now return a \nFuture\nT\n. \n\n\nFutures are values that may not exist yet, so you cannot interact with them directly. Instead, you must use \nmap\n/\nflatMap\n to access the values.\n\n\n// vapor 2\n\n\nlet\n \nres\n \n=\n \ntry\n \ndrop\n.\nclient\n.\nget\n(\nhttp://vapor.codes\n)\n\n\nprint\n(\nres\n.\nstatus\n)\n \n// HTTPStatus\n\n\nreturn\n \nres\n.\nstatus\n\n\n\n// vapor 3\n\n\nlet\n \nf\n \n=\n \ntry\n \nreq\n.\nclient\n().\nget\n(\nhttp://vapor.codes\n).\nmap\n \n{\n \nres\n \nin\n\n    \nprint\n(\nres\n.\nhttp\n.\nstatus\n)\n \n// HTTPStatus\n\n    \nreturn\n \nres\n.\nhttp\n.\nstatus\n\n\n}\n\n\nprint\n(\nf\n)\n \n// Future\nHTTPStatus\n\n\n\n\n\n\nSee \nAsync \n Getting Started\n to learn more.\n\n\nApplication \n Services\n\n\nDroplet\n has been renamed to \nApplication\n and is now a service-container. In Vapor 2, the \nDroplet\n had stored properties for things you would need during development (like views, hashers, etc). In Vapor 3, this is all done via services. \n\n\nWhile the \nApplication\n \nis\n a service-container, you should not use it from your route closures. This is to prevent race conditions since Vapor runs on multiple threads (event loops). Instead, use the \nRequest\n that is supplied to your route closure. This has a \ncopy\n of all of the application's services for you to use.\n\n\n// vapor 2\n\n\nreturn\n \ntry\n \ndrop\n.\nview\n.\nmake\n(\nmyView\n)\n\n\n\n// vapor 3\n\n\nreturn\n \ntry\n \nreq\n.\nmake\n(\nViewRenderer\n.\nself\n).\nrender\n(\nmyView\n)\n\n\n// shorthand\n\n\nreturn\n \ntry\n \nreq\n.\nview\n().\nrender\n(\nmyView\n)\n\n\n\n\n\n\nSee \nService \n Getting Started\n to learn more.\n\n\nDatabase Connections\n\n\nIn Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant. \n\n\nIn order to create a \nQueryBuilder\n in Fluent 3, you will need access to something \nDatabaseConnectable\n. Most often you can just use the incoming \nRequest\n, but you can also create connections manually if you need. \n\n\n// vapor 2\n\n\nUser\n.\nmakeQuery\n().\nall\n()\n\n\n\n// vapor 3\n\n\nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n\n\n\n\nSee \nDatabaseKit \n Getting Started\n to learn more.\n\n\nMigrating SQL Database\n\n\nWhen migrating from Fluent 2 to 3 you may need to update your \nfluent\n table to support the new format. In Fluent 3, the migration log table has the following changes:\n\n\n\n\nid\n is now a \nUUID\n.\n\n\ncreatedAt\n and \nupdatedAt\n must now be \ncamelCase\n.\n\n\n\n\nDepending on how your Fluent database was configured, your tables may already be in the correct format. If not, you can run the following queries to transfer the table data. \n\n\nUse this query if your column names were already set to \ncamelCase\n.\n\n\nALTER\n \nTABLE\n \nfluent\n \nRENAME\n \nTO\n \nfluent_old\n;\n\n\nCREATE\n \nTABLE\n \nfluent\n \n    \nAS\n \n(\nSELECT\n \nUUID\n()\n \nas\n \nid\n,\n \nname\n,\n \nbatch\n,\n \ncreatedAt\n,\n \nupdatedAt\n \nfrom\n \nfluent_old\n);\n\n\n\n\n\n\nUse this query if your column names were \nsnake_case\n.\n\n\nALTER\n \nTABLE\n \nfluent\n \nRENAME\n \nTO\n \nfluent_old\n;\n\n\nCREATE\n \nTABLE\n \nfluent\n \n    \nAS\n \n(\nSELECT\n \nUUID\n()\n \nas\n \nid\n,\n \nname\n,\n \nbatch\n,\n \ncreated_at\n \nas\n \ncreatedAt\n,\n \nupdated_at\n \nas\n \nupdatedAt\n \nfrom\n \nfluent_old\n);\n\n\n\n\n\n\nAfter you have verified the table was transferred properly, you can drop the old fluent table.\n\n\nDROP\n \nTABLE\n \nfluent_old\n;\n\n\n\n\n\n\nWork in progress\n\n\nThis migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.\n\n\nJoin the \n#upgrading-to-3\n in Vapor's team chat to ask questions and get help in real time.\n\n\nAlso check out \nGetting started with Vapor 3\n, an in-depth article about the differences between Vapor 2 and 3. This article was written by two developers from an app development company using Vapor.", 
             "title": "Upgrading"
         }, 
         {
@@ -2540,6 +2540,11 @@
             "text": "In Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant.   In order to create a  QueryBuilder  in Fluent 3, you will need access to something  DatabaseConnectable . Most often you can just use the incoming  Request , but you can also create connections manually if you need.   // vapor 2  User . makeQuery (). all ()  // vapor 3  User . query ( on :   req ). all ()   See  DatabaseKit   Getting Started  to learn more.", 
             "title": "Database Connections"
         }, 
+        {
+            "location": "/version/upgrading/#migrating-sql-database", 
+            "text": "When migrating from Fluent 2 to 3 you may need to update your  fluent  table to support the new format. In Fluent 3, the migration log table has the following changes:   id  is now a  UUID .  createdAt  and  updatedAt  must now be  camelCase .   Depending on how your Fluent database was configured, your tables may already be in the correct format. If not, you can run the following queries to transfer the table data.   Use this query if your column names were already set to  camelCase .  ALTER   TABLE   fluent   RENAME   TO   fluent_old ;  CREATE   TABLE   fluent  \n     AS   ( SELECT   UUID ()   as   id ,   name ,   batch ,   createdAt ,   updatedAt   from   fluent_old );   Use this query if your column names were  snake_case .  ALTER   TABLE   fluent   RENAME   TO   fluent_old ;  CREATE   TABLE   fluent  \n     AS   ( SELECT   UUID ()   as   id ,   name ,   batch ,   created_at   as   createdAt ,   updated_at   as   updatedAt   from   fluent_old );   After you have verified the table was transferred properly, you can drop the old fluent table.  DROP   TABLE   fluent_old ;", 
+            "title": "Migrating SQL Database"
+        }, 
         {
             "location": "/version/upgrading/#work-in-progress", 
             "text": "This migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.  Join the  #upgrading-to-3  in Vapor's team chat to ask questions and get help in real time.  Also check out  Getting started with Vapor 3 , an in-depth article about the differences between Vapor 2 and 3. This article was written by two developers from an app development company using Vapor.", 
diff --git a/build/3.0/sql/overview/index.html b/build/3.0/sql/overview/index.html
index 3e999333..363b36ea 100644
--- a/build/3.0/sql/overview/index.html
+++ b/build/3.0/sql/overview/index.html
@@ -1978,7 +1978,7 @@ The dbid allows you to use multiple databases per application.

Check out Database Kit → Overview → Connections for more information. The rest of this guide will assume you have access to a SQL database connection.

Select

-

Use the select() method on a connection to create a SQLSelectBuilder. This builder helps you create SELECT statements and supports:

+

Use the select() method on a connection to create a SQLSelectBuilder. This builder helps you create SELECT statements and supports:

  • *, columns, and expressions like functions
  • FROM
  • @@ -1986,7 +1986,7 @@ The dbid allows you to use multiple databases per application.

  • GROUP BY
  • ORDER BY
-

The select builder conforms to SQLPredicateBuilder for building WHERE predicates. It also conforms to SQLQueryFetcher for decoding Codable models from the result set.

+

The select builder conforms to SQLPredicateBuilder for building WHERE predicates. It also conforms to SQLQueryFetcher for decoding Codable models from the result set.

Let's take a look at an example SELECT query. Replace the Xcode placeholder with the name of the database you are using, i.e., SQLite.

struct User: SQLTable, Codable {
     static let sqlTableIdentifierString = "users"
diff --git a/build/3.0/version/upgrading/index.html b/build/3.0/version/upgrading/index.html
index 6bbf135a..e6b9c7b4 100644
--- a/build/3.0/version/upgrading/index.html
+++ b/build/3.0/version/upgrading/index.html
@@ -1870,6 +1870,13 @@
     Database Connections
   
   
+
+        
+          
  • + + Migrating SQL Database + +
  • @@ -1959,6 +1966,13 @@ Database Connections +
  • + +
  • + + Migrating SQL Database + +
  • @@ -2042,6 +2056,32 @@

    See DatabaseKit → Getting Started to learn more.

    +

    Migrating SQL Database

    +

    When migrating from Fluent 2 to 3 you may need to update your fluent table to support the new format. In Fluent 3, the migration log table has the following changes:

    +
      +
    • id is now a UUID.
    • +
    • createdAt and updatedAt must now be camelCase.
    • +
    +

    Depending on how your Fluent database was configured, your tables may already be in the correct format. If not, you can run the following queries to transfer the table data.

    +

    Use this query if your column names were already set to camelCase.

    +
    ALTER TABLE fluent RENAME TO fluent_old;
    +CREATE TABLE fluent 
    +    AS (SELECT UUID() as id, name, batch, createdAt, updatedAt from fluent_old);
    +
    + + +

    Use this query if your column names were snake_case.

    +
    ALTER TABLE fluent RENAME TO fluent_old;
    +CREATE TABLE fluent 
    +    AS (SELECT UUID() as id, name, batch, created_at as createdAt, updated_at as updatedAt from fluent_old);
    +
    + + +

    After you have verified the table was transferred properly, you can drop the old fluent table.

    +
    DROP TABLE fluent_old;
    +
    + +

    Work in progress

    This migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.

    Join the #upgrading-to-3 in Vapor's team chat to ask questions and get help in real time.