mirror of https://github.com/vapor/docs.git
deploy
This commit is contained in:
parent
9fdd6d0cd1
commit
c0d6ef7568
|
|
@ -2165,7 +2165,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
|
|||
|
||||
<h2 id="creating-a-model">Creating a Model<a class="headerlink" href="#creating-a-model" title="Permanent link">¶</a></h2>
|
||||
<p>Now let's create your first model. Models represent tables in your database and they are the primary method of interacting with your data. </p>
|
||||
<p>Each driver provides convenience model protocols (<code>PostgreSQLModel</code>, <code>SQLiteModel</code>, etc) that extend Fluent's base <a href="#fixme"><code>Model</code></a> protocol. These convenience types make declaring models more concise by using standard values for ID key and type.</p>
|
||||
<p>Each driver provides convenience model protocols (<code>PostgreSQLModel</code>, <code>SQLiteModel</code>, etc) that extend Fluent's base <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html"><code>Model</code></a> protocol. These convenience types make declaring models more concise by using standard values for ID key and type.</p>
|
||||
<p>Fill in the Xcode placeholders below with the name of your chosen database, i.e., <code>PostgreSQL</code>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
<span class="kd">import</span> <span class="nc">Vapor</span>
|
||||
|
|
@ -2211,12 +2211,34 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
|
|||
<h3 id="custom-credentials">Custom Credentials<a class="headerlink" href="#custom-credentials" title="Permanent link">¶</a></h3>
|
||||
<p>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. </p>
|
||||
<p>See the documentation for your specific database type for more information about custom configuration.</p>
|
||||
<div class="admonition danger">
|
||||
<p class="admonition-title">Danger</p>
|
||||
<p>fixme: Add links to config structs.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>database</th>
|
||||
<th>docs</th>
|
||||
<th>api docs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PostgreSQL</td>
|
||||
<td><a href="../../postgresql/getting-started/">PostgreSQL → Getting Started</a></td>
|
||||
<td><em>Coming soon</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MySQL</td>
|
||||
<td><a href="../../mysql/getting-started/">MySQL → Getting Started</a></td>
|
||||
<td><em>Coming soon</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SQLite</td>
|
||||
<td><a href="../../sqlite/getting-started/">SQLite → Getting Started</a></td>
|
||||
<td><a href="https://api.vapor.codes/sqlite/latest/SQLite/Classes/SQLiteDatabase.html"><code>SQLiteDatabase</code></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2 id="creating-a-migration">Creating a Migration<a class="headerlink" href="#creating-a-migration" title="Permanent link">¶</a></h2>
|
||||
<p>If your database driver uses schemas (is a SQL database), you will need to create a <a href="#fixme"><code>Migration</code></a> 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.</p>
|
||||
<p>If your database driver uses schemas (is a SQL database), you will need to create a <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Migration.html"><code>Migration</code></a> 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.</p>
|
||||
<p>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.</p>
|
||||
<p>You can add the migration conformance to a model as an extension or on the base type declaration.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
|
|
@ -2228,7 +2250,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
|
|||
|
||||
<p>Take a look at <a href="../migrations/">Fluent → Migration</a> if you are interested in learning more about custom migrations.</p>
|
||||
<h3 id="configuring-migrations">Configuring Migrations<a class="headerlink" href="#configuring-migrations" title="Permanent link">¶</a></h3>
|
||||
<p>Once you have created a migration, you must register it to Fluent using <a href="#fixme"><code>MigrationConfig</code></a>. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<p>Once you have created a migration, you must register it to Fluent using <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html"><code>MigrationConfig</code></a>. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<p>Fill in the database ID (<code>dbid</code>) from the table above, i.e., <code>psql</code>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
<span class="kd">import</span> <span class="nc">Vapor</span>
|
||||
|
|
@ -2244,7 +2266,7 @@ It takes advantage of Swift's strong type system to provide an elegant foundatio
|
|||
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
<p>If the migration you are adding is also a model, you can use the <a href="#fixme"><code>add(model:on:)</code></a> convenience to automatically set the model's <a href="#fixme"><code>defaultDatabase</code></a> property. Otherwise, use the <a href="#fixme"><code>add(migration:on)</code></a> method.</p>
|
||||
<p>If the migration you are adding is also a model, you can use the <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html#/s:6Fluent15MigrationConfigV3add5model8databaseyxm_11DatabaseKit0G10IdentifierVy0G0AA0B0PQzGtAaKRzAA5ModelRzAjaOPQzAMRSlF"><code>add(model:on:)</code></a> convenience to automatically set the model's <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE15defaultDatabase0D3Kit0D10IdentifierVy0D0QzGSgvpZ"><code>defaultDatabase</code></a> property. Otherwise, use the <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html#/s:6Fluent15MigrationConfigV3add9migration8databaseyxm_11DatabaseKit0G10IdentifierVy0G0QzGtAA0B0RzlF"><code>add(migration:on)</code></a> method.</p>
|
||||
</div>
|
||||
<p>Once you have the <code>MigrationConfig</code> added, you should be able to run your application and see the following:</p>
|
||||
<div class="codehilite"><pre><span></span>Migrating <<span class="c1">#dbid#> DB</span>
|
||||
|
|
@ -2264,7 +2286,7 @@ Server starting on http://localhost:8080
|
|||
<p>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.</p>
|
||||
<h2 id="raw-queries">Raw Queries<a class="headerlink" href="#raw-queries" title="Permanent link">¶</a></h2>
|
||||
<p>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". </p>
|
||||
<p>To perform raw queries, you need access to a database connection. Vapor's <a href="#fixme"><code>Request</code></a> type has a number of conveniences for creating new database connections. The recommended method is <code>withPooledConnection(to:)</code>. Learn about other methods in <a href="../../database-kit/overview/#connections">DatabaseKit → Overview → Connections</a>.</p>
|
||||
<p>To perform raw queries, you need access to a database connection. Vapor's <a href="https://api.vapor.codes/vapor/latest/Vapor/Classes/Request.html"><code>Request</code></a> type has a number of conveniences for creating new database connections. The recommended method is <code>withPooledConnection(to:)</code>. Learn about other methods in <a href="../../database-kit/overview/#connections">DatabaseKit → Overview → Connections</a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">router</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="s">"raw"</span><span class="p">)</span> <span class="p">{</span> <span class="n">req</span> <span class="p">-></span> <span class="n">Future</span><span class="p"><</span><span class="nb">String</span><span class="p">></span> <span class="k">in</span>
|
||||
<span class="k">return</span> <span class="n">req</span><span class="p">.</span><span class="n">withPooledConnection</span><span class="p">(</span><span class="n">to</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span> <span class="p">{</span> <span class="n">conn</span> <span class="k">in</span>
|
||||
<span class="c1">// perform raw query using conn</span>
|
||||
|
|
|
|||
|
|
@ -2051,7 +2051,7 @@ make normal queries to your database.</p>
|
|||
|
||||
|
||||
<h3 id="automatic-model-migrations">Automatic Model Migrations<a class="headerlink" href="#automatic-model-migrations" title="Permanent link">¶</a></h3>
|
||||
<p>Models provide a shortcut for declaring database migrations. If you conform a type that conforms to <a href="#fixme"><code>Model</code></a> to <a href="#fixme"><code>Migration</code></a>, Fluent can infer the model's properties and automatically implement the <code>prepare(...)</code> and <code>revert(...)</code> methods.</p>
|
||||
<p>Models provide a shortcut for declaring database migrations. If you conform a type that conforms to <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html"><code>Model</code></a> to <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Migration.html"><code>Migration</code></a>, Fluent can infer the model's properties and automatically implement the <code>prepare(...)</code> and <code>revert(...)</code> methods.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
|
||||
<span class="kd">extension</span> <span class="nc">Galaxy</span><span class="p">:</span> <span class="o"><</span><span class="p">#</span><span class="n">Database</span><span class="p">#</span><span class="o">></span><span class="n">Migration</span> <span class="p">{</span> <span class="p">}</span>
|
||||
|
|
@ -2059,16 +2059,16 @@ make normal queries to your database.</p>
|
|||
|
||||
|
||||
<p>This method is especially useful for quick prototyping and simple setups. For most other situations you should consider creating a normal, custom migration. </p>
|
||||
<p>Add this automatic migration to your <a href="#fixme"><code>MigrationConfig</code></a> using the <code>add(model:database:)</code> method. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<p>Add this automatic migration to your <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html"><code>MigrationConfig</code></a> using the <code>add(model:database:)</code> method. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">migrations</span> <span class="p">=</span> <span class="n">MigrationConfig</span><span class="p">()</span>
|
||||
<span class="n">migrations</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">model</span><span class="p">:</span> <span class="n">Galaxy</span><span class="p">.</span><span class="kc">self</span><span class="p">,</span> <span class="n">database</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span>
|
||||
<span class="n">services</span><span class="p">.</span><span class="n">register</span><span class="p">(</span><span class="n">migrations</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>The <code>add(model:database:)</code> method will automatically set the model's <a href="#fixme"><code>defaultDatabase</code></a> property. </p>
|
||||
<p>The <code>add(model:database:)</code> method will automatically set the model's <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE15defaultDatabase0D3Kit0D10IdentifierVy0D0QzGSgvpZ"><code>defaultDatabase</code></a> property. </p>
|
||||
<h3 id="custom-migrations">Custom Migrations<a class="headerlink" href="#custom-migrations" title="Permanent link">¶</a></h3>
|
||||
<p>We can customize the table created for our model by creating a migration and using the static <code>create</code> and <code>delete</code> methods on <a href="#fixme"><code>Database</code></a>.</p>
|
||||
<p>We can customize the table created for our model by creating a migration and using the static <code>create</code> and <code>delete</code> methods on <a href="https://api.vapor.codes/database-kit/latest/DatabaseKit/Protocols/Database.html"><code>Database</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
|
||||
<span class="kd">struct</span> <span class="nc">CreateGalaxy</span><span class="p">:</span> <span class="o"><</span><span class="p">#</span><span class="n">Database</span><span class="p">#</span><span class="o">></span><span class="n">Migration</span> <span class="p">{</span>
|
||||
|
|
@ -2094,7 +2094,7 @@ make normal queries to your database.</p>
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>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 <a href="#fixme"><code>SchemaBuilder</code></a>. This builder has convenience methods for declaring fields in the schema.</p>
|
||||
<p>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 <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/SchemaBuilder.html"><code>SchemaBuilder</code></a>. This builder has convenience methods for declaring fields in the schema.</p>
|
||||
<p>You can use the <code>field(for: <#KeyPath#>)</code> method to quickly create fields for each of your model's properties. Since this method accepts key paths to the model (indicated by <code>\.</code>), Fluent can see what type those properties are. For most common types (<code>String</code>, <code>Int</code>, <code>Double</code>, etc) Fluent will automatically be able to determine the best database field type to use.</p>
|
||||
<p>You can also choose to manually select which database field type to use for a given field.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="k">try</span> <span class="n">builder</span><span class="p">.</span><span class="n">field</span><span class="p">(</span><span class="k">for</span><span class="p">:</span> <span class="err">\</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">type</span><span class="p">:</span> <span class="o"><</span><span class="p">#</span><span class="n">DataType</span><span class="p">#</span><span class="o">></span><span class="p">)</span>
|
||||
|
|
@ -2102,10 +2102,32 @@ make normal queries to your database.</p>
|
|||
|
||||
|
||||
<p>Each database has it's own unique data types, so refer to your database's documentation for more information.</p>
|
||||
<div class="admonition danger">
|
||||
<p class="admonition-title">Danger</p>
|
||||
<p>fixme: links to db's data types</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>database</th>
|
||||
<th>docs</th>
|
||||
<th>api docs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PostgreSQL</td>
|
||||
<td><a href="../../postgresql/getting-started/">PostgreSQL → Getting Started</a></td>
|
||||
<td><em>Coming soon</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MySQL</td>
|
||||
<td><a href="../../mysql/getting-started/">MySQL → Getting Started</a></td>
|
||||
<td><em>Coming soon</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SQLite</td>
|
||||
<td><a href="../../sqlite/getting-started/">SQLite → Getting Started</a></td>
|
||||
<td><a href="https://api.vapor.codes/sqlite/latest/SQLite/Enums/SQLiteDataType.html"><code>SQLiteDataType</code></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h4 id="deleting-a-schema">Deleting a Schema<a class="headerlink" href="#deleting-a-schema" title="Permanent link">¶</a></h4>
|
||||
<p>Each migration should also include a method for <em>reverting</em> the changes it makes. It is used when you boot your
|
||||
app with the <code>--revert</code> option. </p>
|
||||
|
|
@ -2124,7 +2146,7 @@ app with the <code>--revert</code> option. </p>
|
|||
|
||||
<p>To delete a schema, you pass a model type and connection as the two required parameters. That's it.</p>
|
||||
<p>You can always choose to skip a reversion by simplying returning <code>conn.future(())</code>. But note that they are especially useful when testing and debugging your migrations.</p>
|
||||
<p>Add this custom migration to your <a href="#fixme"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in your <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a> file.</p>
|
||||
<p>Add this custom migration to your <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in your <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a> file.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">migrations</span> <span class="p">=</span> <span class="n">MigrationConfig</span><span class="p">()</span>
|
||||
<span class="n">migrations</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">migration</span><span class="p">:</span> <span class="n">CreateGalaxy</span><span class="p">.</span><span class="kc">self</span><span class="p">,</span> <span class="n">database</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span>
|
||||
<span class="n">services</span><span class="p">.</span><span class="n">register</span><span class="p">(</span><span class="n">migrations</span><span class="p">)</span>
|
||||
|
|
@ -2149,7 +2171,7 @@ app with the <code>--revert</code> option. </p>
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Since our previous migration created a table with fields for both <code>id</code> and <code>name</code>, we need to update that table and add a field for <code>mass</code>. We can do this by using the static <code>update</code> method on <a href="#fixme"><code>Database</code></a>.</p>
|
||||
<p>Since our previous migration created a table with fields for both <code>id</code> and <code>name</code>, we need to update that table and add a field for <code>mass</code>. We can do this by using the static <code>update</code> method on <a href="https://api.vapor.codes/database-kit/latest/DatabaseKit/Protocols/Database.html"><code>Database</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Fluent</span><span class="o"><</span><span class="p">#</span><span class="nc">Database</span><span class="p">#</span><span class="o">></span>
|
||||
|
||||
<span class="kd">struct</span> <span class="nc">AddGalaxyMass</span><span class="p">:</span> <span class="o"><</span><span class="p">#</span><span class="n">Database</span><span class="p">#</span><span class="o">></span><span class="n">Migration</span> <span class="p">{</span>
|
||||
|
|
@ -2171,7 +2193,7 @@ app with the <code>--revert</code> option. </p>
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>All methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See <a href="#fixme"><code>SchemaUpdater</code></a> for a list of all available methods.</p>
|
||||
<p>All methods available when creating a schema will be available while updating alongside some new methods for deleting fields. See <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/SchemaUpdater.html"><code>SchemaUpdater</code></a> for a list of all available methods.</p>
|
||||
<p>To revert this change, we must delete the <code>mass</code> field from the table.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">struct</span> <span class="nc">AddGalaxyMass</span><span class="p">:</span> <span class="o"><</span><span class="p">#</span><span class="n">Database</span><span class="p">#</span><span class="o">></span><span class="n">Migration</span> <span class="p">{</span>
|
||||
<span class="c1">// ... </span>
|
||||
|
|
@ -2184,7 +2206,7 @@ app with the <code>--revert</code> option. </p>
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Add this migration to your <a href="#fixme"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in your <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a> file.</p>
|
||||
<p>Add this migration to your <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in your <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a> file.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">migrations</span> <span class="p">=</span> <span class="n">MigrationConfig</span><span class="p">()</span>
|
||||
<span class="c1">// ...</span>
|
||||
<span class="n">migrations</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">migration</span><span class="p">:</span> <span class="n">AddGalaxyMass</span><span class="p">.</span><span class="kc">self</span><span class="p">,</span> <span class="n">database</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span>
|
||||
|
|
@ -2224,7 +2246,7 @@ app with the <code>--revert</code> option. </p>
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Add this migration to your <a href="#fixme"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<p>Add this migration to your <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/MigrationConfig.html"><code>MigrationConfig</code></a> using the <code>add(migration:database:)</code> method. This is done in <a href="../../getting-started/structure/#configureswift"><code>configure.swift</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">migrations</span> <span class="p">=</span> <span class="n">MigrationConfig</span><span class="p">()</span>
|
||||
<span class="c1">// ...</span>
|
||||
<span class="n">migrations</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">migration</span><span class="p">:</span> <span class="n">GalaxyMassCleanup</span><span class="p">.</span><span class="kc">self</span><span class="p">,</span> <span class="n">database</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span>
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off">
|
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label>
|
||||
|
||||
<a href="#querying-models" tabindex="1" class="md-skip">
|
||||
<a href="#fluent-queries" tabindex="1" class="md-skip">
|
||||
Skip to content
|
||||
</a>
|
||||
|
||||
|
|
@ -2170,12 +2170,12 @@
|
|||
<a href="https://github.com/vapor/documentation/edit/master/3.0/docs/fluent/querying.md" title="Edit this page" class="md-icon md-content__icon"></a>
|
||||
|
||||
|
||||
<h1 id="querying-models">Querying Models<a class="headerlink" href="#querying-models" title="Permanent link">¶</a></h1>
|
||||
<h1 id="fluent-queries">Fluent Queries<a class="headerlink" href="#fluent-queries" title="Permanent link">¶</a></h1>
|
||||
<p>Once you have a <a href="../models/">model</a> you can start querying your database to create, read, update, and delete data.</p>
|
||||
<h2 id="connection">Connection<a class="headerlink" href="#connection" title="Permanent link">¶</a></h2>
|
||||
<p>The first thing you need to query your database, is a connection to it. Luckily, they are easy to get.</p>
|
||||
<h3 id="request">Request<a class="headerlink" href="#request" title="Permanent link">¶</a></h3>
|
||||
<p>The easiest way to connect to your database is simply using the incoming <code>Request</code>. This will use the model's <a href="#fixme"><code>defaultDatabase</code></a> property to automatically fetch a pooled connection to the database. </p>
|
||||
<p>The easiest way to connect to your database is simply using the incoming <code>Request</code>. This will use the model's <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE15defaultDatabase0D3Kit0D10IdentifierVy0D0QzGSgvpZ"><code>defaultDatabase</code></a> property to automatically fetch a pooled connection to the database. </p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">router</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="s">"galaxies"</span><span class="p">)</span> <span class="p">{</span> <span class="n">req</span> <span class="k">in</span>
|
||||
<span class="k">return</span> <span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">req</span><span class="p">).</span><span class="n">all</span><span class="p">()</span>
|
||||
<span class="p">}</span>
|
||||
|
|
@ -2184,7 +2184,7 @@
|
|||
|
||||
<p>You can use convenience methods on a <code>Container</code> to create connections manually. Learn more about that in <a href="../../database-kit/overview/#connections">DatabaseKit → Overview → Connections</a>.</p>
|
||||
<h2 id="create">Create<a class="headerlink" href="#create" title="Permanent link">¶</a></h2>
|
||||
<p>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 <a href="#fixme"><code>create(on:)</code></a>.</p>
|
||||
<p>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 <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6create2on3NIO15EventLoopFutureCyxG11DatabaseKit0I11Connectable_p_tF"><code>create(on:)</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">router</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="s">"galaxies"</span><span class="p">)</span> <span class="p">{</span> <span class="n">req</span> <span class="k">in</span>
|
||||
<span class="kd">let</span> <span class="nv">galaxy</span><span class="p">:</span> <span class="n">Galaxy</span> <span class="p">=</span> <span class="p">...</span>
|
||||
<span class="k">return</span> <span class="n">galaxy</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">req</span><span class="p">)</span>
|
||||
|
|
@ -2193,28 +2193,28 @@
|
|||
|
||||
|
||||
<p>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.</p>
|
||||
<p>If your model also conforms to <a href="#fixme"><code>Content</code></a> you can return the result of the Fluent query directly.</p>
|
||||
<p>If your model also conforms to <a href="https://api.vapor.codes/vapor/latest/Vapor/Protocols/Content.html"><code>Content</code></a> you can return the result of the Fluent query directly.</p>
|
||||
<h2 id="read">Read<a class="headerlink" href="#read" title="Permanent link">¶</a></h2>
|
||||
<p>To read models from the database, you can use <a href="#fixme"><code>query(on:)</code></a> or <a href="#fixme"><code>find(_:on:)</code></a>.</p>
|
||||
<p>To read models from the database, you can use <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6create2on3NIO15EventLoopFutureCyxG11DatabaseKit0I11Connectable_p_tF"><code>query(on:)</code></a> or <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE4find_2on3NIO15EventLoopFutureCyxSgG2IDQz_11DatabaseKit0J11Connectable_ptFZ"><code>find(_:on:)</code></a>.</p>
|
||||
<h3 id="find">Find<a class="headerlink" href="#find" title="Permanent link">¶</a></h3>
|
||||
<p>The easiest way to find a single model is by passing its ID to <a href="#fixme"><code>find(_:on:)</code></a>.</p>
|
||||
<p>The easiest way to find a single model is by passing its ID to <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE4find_2on3NIO15EventLoopFutureCyxSgG2IDQz_11DatabaseKit0J11Connectable_ptFZ"><code>find(_:on:)</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="bp">find</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>The result will be a future containing an optional value. You can use <a href="#fixme"><code>unwrap(or:)</code></a> to unwrap the future value or throw an error.</p>
|
||||
<p>The result will be a future containing an optional value. You can use <a href="https://api.vapor.codes/core/latest/Core/Extensions/Future.html#/s:3NIO15EventLoopFutureC4CoreAD12OptionalTypeRzlE6unwrap2orACy07WrappedG0QzGs5Error_pyXA_tF"><code>unwrap(or:)</code></a> to unwrap the future value or throw an error.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="bp">find</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="n">unwrap</span><span class="p">(</span><span class="n">or</span><span class="p">:</span> <span class="n">Abort</span><span class="p">(...))</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h3 id="query">Query<a class="headerlink" href="#query" title="Permanent link">¶</a></h3>
|
||||
<p>You can use the <a href="#fixme"><code>query(on:)</code></a> method to build database queries with filters, joins, sorts, and more. </p>
|
||||
<p>You can use the <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6create2on3NIO15EventLoopFutureCyxG11DatabaseKit0I11Connectable_p_tF"><code>query(on:)</code></a> method to build database queries with filters, joins, sorts, and more. </p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="bp">filter</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">name</span> <span class="p">==</span> <span class="s">"Milky Way"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h3 id="filter">Filter<a class="headerlink" href="#filter" title="Permanent link">¶</a></h3>
|
||||
<p>The <a href="#fixme"><code>filter(_:)</code></a> method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.</p>
|
||||
<p>The <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC6filteryACyxq_GXDAA14FilterOperatorVyxq_GF"><code>filter(_:)</code></a> method accepts filters created from Fluent's operators. This provides a concise, Swifty way for building Fluent queries.</p>
|
||||
<p>Calls to filter can be chained and even grouped.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="bp">filter</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">mass</span> <span class="o">>=</span> <span class="mi">500</span><span class="p">).</span><span class="bp">filter</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">type</span> <span class="p">==</span> <span class="p">.</span><span class="n">spiral</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
|
@ -2285,9 +2285,9 @@
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Once a table has been joined using <a href="#fixme"><code>join(_:to:)</code></a>, you can use fully-qualified key paths to filter results based on data in the joined table.</p>
|
||||
<p>Once a table has been joined using <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderCA2A14JoinSupportingRzrlE4join_2to6methodACyxq_GXDs7KeyPathCyqd__qd_0_G_AJyqd_1_qd_2_G0bD6MethodQztr2_lF"><code>join(_:to:)</code></a>, you can use fully-qualified key paths to filter results based on data in the joined table.</p>
|
||||
<p>The above query fetches all galaxies that have a planet named Earth.</p>
|
||||
<p>You can even decode the joined models using <a href="#fixme"><code>alsoDecode(...)</code></a>.</p>
|
||||
<p>You can even decode the joined models using <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC10alsoDecodeyACyxq__qd__tGqd__mAA5ModelRd__lF"><code>alsoDecode(...)</code></a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">)</span>
|
||||
<span class="c1">// join Planet and filter</span>
|
||||
<span class="p">.</span><span class="n">alsoDecode</span><span class="p">(</span><span class="n">Planet</span><span class="p">.</span><span class="kc">self</span><span class="p">).</span><span class="n">all</span><span class="p">()</span>
|
||||
|
|
@ -2296,20 +2296,20 @@
|
|||
|
||||
<p>The above query will decode an array of <code>(Galaxy, Planet)</code> tuples.</p>
|
||||
<h3 id="fetch">Fetch<a class="headerlink" href="#fetch" title="Permanent link">¶</a></h3>
|
||||
<p>To fetch the results of a query, use <a href="#fixme"><code>all()</code></a>, <a href="#fixme"><code>chunk(max:)</code></a>, <a href="#fixme"><code>first()</code></a> or an aggregate method.</p>
|
||||
<p>To fetch the results of a query, use <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC3all3NIO15EventLoopFutureCySayq_GGyF"><code>all()</code></a>, <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC5chunk3max7closure3NIO15EventLoopFutureCyytGSi_ySayq_GKctF"><code>chunk(max:closure:)</code></a>, <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC5first3NIO15EventLoopFutureCyq_SgGyF"><code>first()</code></a> or an aggregate method.</p>
|
||||
<h4 id="all">All<a class="headerlink" href="#all" title="Permanent link">¶</a></h4>
|
||||
<p>The most common method for fetching results is with <code>all()</code>. This will return all matching results according to any fliters applied. </p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="n">all</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>When combined with <a href="#fixme"><code>range(_:)</code></a>, you can efficiently limit how many results are returned by the database.</p>
|
||||
<p>When combined with <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC5rangeyACyxq_GXDSnySiGF"><code>range(_:)</code></a>, you can efficiently limit how many results are returned by the database.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="n">range</span><span class="p">(..<</span><span class="mi">50</span><span class="p">).</span><span class="n">all</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h4 id="chunk">Chunk<a class="headerlink" href="#chunk" title="Permanent link">¶</a></h4>
|
||||
<p>For situations where memory conservation is important, use <a href="#fixme"><code>chunk(...)</code></a>. This method returns the result set in multiple calls of a maximum chunk size.</p>
|
||||
<p>For situations where memory conservation is important, use <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC5chunk3max7closure3NIO15EventLoopFutureCyytGSi_ySayq_GKctF"><code>chunk(...)</code></a>. This method returns the result set in multiple calls of a maximum chunk size.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="n">chunk</span><span class="p">(</span><span class="bp">max</span><span class="p">:</span> <span class="mi">32</span><span class="p">)</span> <span class="p">{</span> <span class="n">galaxies</span> <span class="k">in</span>
|
||||
<span class="bp">print</span><span class="p">(</span><span class="n">galaxies</span><span class="p">)</span> <span class="c1">// Array of 32 or less galaxies</span>
|
||||
<span class="p">}</span>
|
||||
|
|
@ -2317,14 +2317,14 @@
|
|||
|
||||
|
||||
<h4 id="first">First<a class="headerlink" href="#first" title="Permanent link">¶</a></h4>
|
||||
<p>The <a href="#fixme"><code>first()</code></a> method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.</p>
|
||||
<p>The <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html#/s:6Fluent12QueryBuilderC5first3NIO15EventLoopFutureCyq_SgGyF"><code>first()</code></a> method is a convenience for fetching the first result of a query. It will automatically apply a range restriction to avoid transferring unnecessary data.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">Galaxy</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">).</span><span class="bp">filter</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">name</span> <span class="p">==</span> <span class="s">"Milky Way"</span><span class="p">).</span><span class="bp">first</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This method is more efficient than calling <code>all</code> and getting the first item in the array.</p>
|
||||
<h2 id="update">Update<a class="headerlink" href="#update" title="Permanent link">¶</a></h2>
|
||||
<p>After a model has been fetched from the database and mutated, you can use <a href="#fixme"><code>update(on:)</code></a> to save the changes.</p>
|
||||
<p>After a model has been fetched from the database and mutated, you can use <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6update2on10originalID3NIO15EventLoopFutureCyxG11DatabaseKit0K11Connectable_p_0F0QzSgtF"><code>update(on:)</code></a> to save the changes.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">planet</span><span class="p">:</span> <span class="n">Planet</span> <span class="p">...</span> <span class="c1">// fetched from database</span>
|
||||
<span class="n">planet</span><span class="p">.</span><span class="n">name</span> <span class="p">=</span> <span class="s">"Earth"</span>
|
||||
<span class="n">planet</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">)</span>
|
||||
|
|
@ -2332,7 +2332,7 @@
|
|||
|
||||
|
||||
<h2 id="delete">Delete<a class="headerlink" href="#delete" title="Permanent link">¶</a></h2>
|
||||
<p>After a model has been fetched from the database, you can use <a href="#fixme"><code>delete(on:)</code></a> to delete it.</p>
|
||||
<p>After a model has been fetched from the database, you can use <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6delete5force2on3NIO15EventLoopFutureCyytGSb_11DatabaseKit0J11Connectable_ptF"><code>delete(on:)</code></a> to delete it.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">var</span> <span class="nv">planet</span><span class="p">:</span> <span class="n">Planet</span> <span class="p">...</span> <span class="c1">// fetched from database</span>
|
||||
<span class="n">planet</span><span class="p">.</span><span class="n">delete</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="n">conn</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -1994,7 +1994,7 @@
|
|||
|
||||
|
||||
<p>For more information on defining models see <a href="../models/">Fluent → Models</a>.</p>
|
||||
<p>Fluent provides two helpers for working with parent-child relations: <a href="#fixme"><code>Parent</code></a> and <a href="#fixme"><code>Children</code></a>. These helpers can be created using extensions on the related models for convenient access.</p>
|
||||
<p>Fluent provides two helpers for working with parent-child relations: <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/Parent.html"><code>Parent</code></a> and <a href="https://api.vapor.codes/fluent/latest/Fluent/Structs/Children.html"><code>Children</code></a>. These helpers can be created using extensions on the related models for convenient access.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">Galaxy</span> <span class="p">{</span>
|
||||
<span class="c1">// this galaxy's related planets</span>
|
||||
<span class="kd">var</span> <span class="nv">planets</span><span class="p">:</span> <span class="n">Children</span><span class="p"><</span><span class="n">Galaxy</span><span class="p">,</span> <span class="n">Planet</span><span class="p">></span> <span class="p">{</span>
|
||||
|
|
@ -2004,7 +2004,7 @@
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Here the <a href="#fixme"><code>children(_:)</code></a> method is used on <code>Galaxy</code> to create the relation. The resulting type has two generic arguments in the signature that can be thought of as <code><From, To</code>>. Since this relation goes <em>from</em> galaxy <em>to</em> planet, they are ordered as such in the generic arguments.</p>
|
||||
<p>Here the <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE8childrenyAA8ChildrenVyxqd__Gs7KeyPathCyqd__2IDQzGAaBRd__8DatabaseQyd__AMRtzlF"><code>children(_:)</code></a> method is used on <code>Galaxy</code> to create the relation. The resulting type has two generic arguments in the signature that can be thought of as <code><From, To</code>>. Since this relation goes <em>from</em> galaxy <em>to</em> planet, they are ordered as such in the generic arguments.</p>
|
||||
<p>Note that this method is not static. That is because it must access the galaxy's identifier to perform the relation lookup. </p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">Planet</span> <span class="p">{</span>
|
||||
<span class="c1">// this planet's related galaxy</span>
|
||||
|
|
@ -2015,7 +2015,7 @@
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>Here the <a href="#fixme"><code>parent(_:)</code></a> method is used on <code>Planet</code> to create the inverse relation. The resulting type also has two generic arguments. In this case, they are reversed since this relation now goes <em>from</em> planet <em>to</em> galaxy.</p>
|
||||
<p>Here the <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/Model.html#/s:6Fluent5ModelPAAE6parentyAA6ParentVyxqd__Gs7KeyPathCyx2IDQyd__GAaBRd__8DatabaseQyd__AMRtzlF"><code>parent(_:)</code></a> method is used on <code>Planet</code> to create the inverse relation. The resulting type also has two generic arguments. In this case, they are reversed since this relation now goes <em>from</em> planet <em>to</em> galaxy.</p>
|
||||
<p>Note that this method is also not static. That is because it must access the referenced identifier to perform the relation lookup.</p>
|
||||
<p>Now that the models and relation properties are created, they can be used to create, read, update, and delete related data.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">galaxy</span><span class="p">:</span> <span class="n">Galaxy</span> <span class="p">=</span> <span class="p">...</span>
|
||||
|
|
@ -2023,7 +2023,7 @@
|
|||
</pre></div>
|
||||
|
||||
|
||||
<p>The <code>query(on:)</code> method on a relation creates an instance of <a href="#fixme"><code>QueryBuilder</code></a> filtered to the related models. See <a href="../querying/">Fluent → Querying</a> for more information on working with the query builder.</p>
|
||||
<p>The <code>query(on:)</code> method on a relation creates an instance of <a href="https://api.vapor.codes/fluent/latest/Fluent/Classes/QueryBuilder.html"><code>QueryBuilder</code></a> filtered to the related models. See <a href="../querying/">Fluent → Querying</a> for more information on working with the query builder.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">planet</span><span class="p">:</span> <span class="n">Planet</span> <span class="p">=</span> <span class="p">...</span>
|
||||
<span class="kd">let</span> <span class="nv">galaxy</span> <span class="p">=</span> <span class="n">planet</span><span class="p">.</span><span class="n">galaxy</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="p">...)</span>
|
||||
</pre></div>
|
||||
|
|
@ -2107,7 +2107,7 @@
|
|||
|
||||
|
||||
<h3 id="modifiable-pivot">Modifiable Pivot<a class="headerlink" href="#modifiable-pivot" title="Permanent link">¶</a></h3>
|
||||
<p>If the pivot conforms to <a href="#fixme"><code>ModifiablePivot</code></a>, then Fluent can help to create and delete pivots (called attaching and detaching).</p>
|
||||
<p>If the pivot conforms to <a href="https://api.vapor.codes/fluent/latest/Fluent/Protocols/ModifiablePivot.html"><code>ModifiablePivot</code></a>, then Fluent can help to create and delete pivots (called attaching and detaching).</p>
|
||||
<p>Conforming a pivot is fairly simple. Fluent just needs to be able to initialize the pivot from two related models.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">PlanetTag</span><span class="p">:</span> <span class="n">ModifiablePivot</span> <span class="p">{</span>
|
||||
<span class="kd">init</span><span class="p">(</span><span class="kc">_</span> <span class="n">planet</span><span class="p">:</span> <span class="n">Planet</span><span class="p">,</span> <span class="kc">_</span> <span class="n">tag</span><span class="p">:</span> <span class="n">Tag</span><span class="p">)</span> <span class="kr">throws</span> <span class="p">{</span>
|
||||
|
|
|
|||
|
|
@ -1881,7 +1881,7 @@
|
|||
|
||||
<h1 id="fluent-transactions">Fluent Transactions<a class="headerlink" href="#fluent-transactions" title="Permanent link">¶</a></h1>
|
||||
<p>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.</p>
|
||||
<p>To perform a transaction, you need access to something that can connect to the database. This is usually an incoming HTTP request. Use the <a href="#fixme"><code>transaction(on:_:)</code></a> method.</p>
|
||||
<p>To perform a transaction, you need access to something that can connect to the database. This is usually an incoming HTTP request. Use the <a href="https://api.vapor.codes/fluent/latest/Fluent/Extensions/DatabaseConnectable.html#/s:11DatabaseKit0A11ConnectableP6FluentE11transaction2on_3NIO15EventLoopFutureCyqd_0_GAA0A10IdentifierVyqd__G_AJ10ConnectionQyd__KctAD21TransactionSupportingRd__r0_lF"><code>transaction(on:_:)</code></a> method.</p>
|
||||
<p>Fill in the Xcode placeholders below with your database's name from <a href="../getting-started/#choosing-a-driver">Getting Started → Choosing a Driver</a>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="n">req</span><span class="p">.</span><span class="n">transaction</span><span class="p">(</span><span class="n">on</span><span class="p">:</span> <span class="p">.</span><span class="o"><</span><span class="p">#</span><span class="n">dbid</span><span class="p">#</span><span class="o">></span><span class="p">)</span> <span class="p">{</span> <span class="n">conn</span> <span class="k">in</span>
|
||||
<span class="c1">// use conn as your connection</span>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1978,7 +1978,7 @@ The <code>dbid</code> allows you to use multiple databases per application.</p>
|
|||
|
||||
<p>Check out <a href="../../database-kit/overview.md/#connections">Database Kit → Overview → Connections</a> for more information. The rest of this guide will assume you have access to a SQL database connection.</p>
|
||||
<h2 id="select">Select<a class="headerlink" href="#select" title="Permanent link">¶</a></h2>
|
||||
<p>Use the <a href="#fixme"><code>select()</code></a> method on a connection to create a <a href="#fixme"><code>SQLSelectBuilder</code></a>. This builder helps you create <code>SELECT</code> statements and supports:</p>
|
||||
<p>Use the <a href="https://api.vapor.codes/sql/latest/SQL/Protocols/SQLConnection.html#/s:3SQL13SQLConnectionPAAE6selectAA16SQLSelectBuilderCyxGyF"><code>select()</code></a> method on a connection to create a <a href="https://api.vapor.codes/sql/latest/SQL/Classes/SQLSelectBuilder.html"><code>SQLSelectBuilder</code></a>. This builder helps you create <code>SELECT</code> statements and supports:</p>
|
||||
<ul>
|
||||
<li><code>*</code>, columns, and expressions like functions</li>
|
||||
<li><code>FROM</code></li>
|
||||
|
|
@ -1986,7 +1986,7 @@ The <code>dbid</code> allows you to use multiple databases per application.</p>
|
|||
<li><code>GROUP BY</code></li>
|
||||
<li><code>ORDER BY</code></li>
|
||||
</ul>
|
||||
<p>The select builder conforms to <a href="#fixme"><code>SQLPredicateBuilder</code></a> for building <code>WHERE</code> predicates. It also conforms to <a href="#fixme"><code>SQLQueryFetcher</code></a> for decoding <code>Codable</code> models from the result set.</p>
|
||||
<p>The select builder conforms to <a href="https://api.vapor.codes/sql/latest/SQL/Protocols/SQLPredicateBuilder.html"><code>SQLPredicateBuilder</code></a> for building <code>WHERE</code> predicates. It also conforms to <a href="https://api.vapor.codes/sql/latest/SQL/Protocols/SQLQueryFetcher.html"><code>SQLQueryFetcher</code></a> for decoding <code>Codable</code> models from the result set.</p>
|
||||
<p>Let's take a look at an example <code>SELECT</code> query. Replace the Xcode placeholder with the name of the database you are using, i.e., <code>SQLite</code>. </p>
|
||||
<div class="codehilite"><pre><span></span><span class="kd">struct</span> <span class="nc">User</span><span class="p">:</span> <span class="n">SQLTable</span><span class="p">,</span> <span class="n">Codable</span> <span class="p">{</span>
|
||||
<span class="kd">static</span> <span class="kd">let</span> <span class="nv">sqlTableIdentifierString</span> <span class="p">=</span> <span class="s">"users"</span>
|
||||
|
|
|
|||
|
|
@ -1870,6 +1870,13 @@
|
|||
Database Connections
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#migrating-sql-database" title="Migrating SQL Database" class="md-nav__link">
|
||||
Migrating SQL Database
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
|
|
@ -1959,6 +1966,13 @@
|
|||
Database Connections
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#migrating-sql-database" title="Migrating SQL Database" class="md-nav__link">
|
||||
Migrating SQL Database
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
|
|
@ -2042,6 +2056,32 @@
|
|||
|
||||
|
||||
<p>See <a href="../../database-kit/getting-started/">DatabaseKit → Getting Started</a> to learn more.</p>
|
||||
<h3 id="migrating-sql-database">Migrating SQL Database<a class="headerlink" href="#migrating-sql-database" title="Permanent link">¶</a></h3>
|
||||
<p>When migrating from Fluent 2 to 3 you may need to update your <code>fluent</code> table to support the new format. In Fluent 3, the migration log table has the following changes:</p>
|
||||
<ul>
|
||||
<li><code>id</code> is now a <code>UUID</code>.</li>
|
||||
<li><code>createdAt</code> and <code>updatedAt</code> must now be <code>camelCase</code>.</li>
|
||||
</ul>
|
||||
<p>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. </p>
|
||||
<p>Use this query if your column names were already set to <code>camelCase</code>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">fluent</span> <span class="k">RENAME</span> <span class="k">TO</span> <span class="n">fluent_old</span><span class="p">;</span>
|
||||
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">fluent</span>
|
||||
<span class="k">AS</span> <span class="p">(</span><span class="k">SELECT</span> <span class="n">UUID</span><span class="p">()</span> <span class="k">as</span> <span class="n">id</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">createdAt</span><span class="p">,</span> <span class="n">updatedAt</span> <span class="k">from</span> <span class="n">fluent_old</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Use this query if your column names were <code>snake_case</code>.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">fluent</span> <span class="k">RENAME</span> <span class="k">TO</span> <span class="n">fluent_old</span><span class="p">;</span>
|
||||
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">fluent</span>
|
||||
<span class="k">AS</span> <span class="p">(</span><span class="k">SELECT</span> <span class="n">UUID</span><span class="p">()</span> <span class="k">as</span> <span class="n">id</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">created_at</span> <span class="k">as</span> <span class="n">createdAt</span><span class="p">,</span> <span class="n">updated_at</span> <span class="k">as</span> <span class="n">updatedAt</span> <span class="k">from</span> <span class="n">fluent_old</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>After you have verified the table was transferred properly, you can drop the old fluent table.</p>
|
||||
<div class="codehilite"><pre><span></span><span class="k">DROP</span> <span class="k">TABLE</span> <span class="n">fluent_old</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h3 id="work-in-progress">Work in progress<a class="headerlink" href="#work-in-progress" title="Permanent link">¶</a></h3>
|
||||
<p>This migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.</p>
|
||||
<p>Join the <a href="https://discordapp.com/invite/BnXmVGA">#upgrading-to-3</a> in Vapor's team chat to ask questions and get help in real time.</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue