mirror of https://github.com/vapor/docs.git
commit
99f440d44f
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg
|
||||
width="50px"
|
||||
height="50px"
|
||||
viewBox="0 0 50 50"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>Vapor</title>
|
||||
<desc>The Vapor droplet logo in pink and blue.</desc>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="1.11022302e-14%"
|
||||
y1="5.88522518%"
|
||||
x2="1.11022302e-14%"
|
||||
y2="59.5616958%"
|
||||
id="pink-and-blue"
|
||||
>
|
||||
<stop stop-color="#F7CAC9" offset="0%"></stop>
|
||||
<stop stop-color="#92A8D1" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="droplet" fill="url(#pink-and-blue)">
|
||||
<path
|
||||
d="M17.6186417,50 C17.6186417,50 35.2941176,27.6875238 35.2941176,17.8366268 C35.2941176,7.98572985 27.3932603,0 17.6470588,0 C7.90085736,0 0,7.98572985 0,17.8366268 C0,27.6875238 17.6186417,50 17.6186417,50 Z"
|
||||
transform="translate(17.647059, 25.000000) scale(1, -1) translate(-17.647059, -25.000000)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg
|
||||
width="50px"
|
||||
height="50px"
|
||||
viewBox="0 0 50 50"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>Vapor</title>
|
||||
<desc>The Vapor droplet logo in white.</desc>
|
||||
<g id="droplet" fill="#FFFFFF">
|
||||
<path
|
||||
d="M17.6186417,50 C17.6186417,50 35.2941176,27.6875238 35.2941176,17.8366268 C35.2941176,7.98572985 27.3932603,0 17.6470588,0 C7.90085736,0 0,7.98572985 0,17.8366268 C0,27.6875238 17.6186417,50 17.6186417,50 Z"
|
||||
transform="translate(17.647059, 25.000000) scale(1, -1) translate(-17.647059, -25.000000)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 699 B |
|
|
@ -0,0 +1,203 @@
|
|||
# SQLite Overview
|
||||
|
||||
Let's dive into the [vapor/sqlite](https://github.com/vapor/sqlite) package and
|
||||
see how to connect to and query a database.
|
||||
|
||||
!!! warning
|
||||
This documentation provides an overview for the SQLite API.
|
||||
If you are using SQLite with Fluent, you will likely never need to use
|
||||
this API. Use [Fluent's APIs](../fluent/overview.md) instead.
|
||||
|
||||
Follow the instructions in the [package](package.md) section to add the SQLite package to your project. Once its added, you should be able to use `import SQLite.`
|
||||
|
||||
## Database
|
||||
|
||||
The first step to making a query is to create a `Database`.
|
||||
|
||||
### In Memory
|
||||
|
||||
In-memory SQLite databases are great for testing as they aren't persisted between application boots.
|
||||
|
||||
```swift
|
||||
import SQLite
|
||||
|
||||
let db = Database(storage: .memory)
|
||||
```
|
||||
|
||||
### File path
|
||||
|
||||
SQLite requires a single file to persist the database contents.
|
||||
|
||||
```swift
|
||||
import SQLite
|
||||
|
||||
let db = Database(storage: .file(path: "/tmp/db.sqlite"))
|
||||
```
|
||||
|
||||
!!! tip
|
||||
If the database file does not already exist, it will be created.
|
||||
|
||||
## Connection
|
||||
|
||||
Once you have initialized your database, you can create a connection.
|
||||
|
||||
```swift
|
||||
let conn = try db.makeConnection(on: .global())
|
||||
```
|
||||
|
||||
!!! note
|
||||
Pay special attention to which `DispatchQueue` you pass to `makeConnection(on:)`.
|
||||
This will be the queue SQLite calls you back on.
|
||||
|
||||
!!! tip
|
||||
If you are using SQLite with Vapor, make sure to pass the [worker](async/worker.md)'s queue here.
|
||||
|
||||
## Query
|
||||
|
||||
Once you have a `Connection`, you can use it to create a `Query`.
|
||||
|
||||
```swift
|
||||
let query = conn.query("SELECT * FROM users")
|
||||
```
|
||||
|
||||
### Binding Values
|
||||
|
||||
If you are executing a query that has input values, you should bind these using parameters.
|
||||
|
||||
```swift
|
||||
let query = conn.query("INSERT INTO users (name, age) VALUES (?, ?)")
|
||||
query.bind("Albert")
|
||||
query.bind(138)
|
||||
```
|
||||
|
||||
You can also bind values using method chaining.
|
||||
|
||||
```swift
|
||||
let query = conn.query("INSERT INTO users (name, age) VALUES (?, ?)")
|
||||
.bind("Albert")
|
||||
.bind(138)
|
||||
```
|
||||
|
||||
### Output Stream
|
||||
|
||||
If you expect output from your query, you must attach a stream. The easiest way
|
||||
to do this is by using the `drain` convenience.
|
||||
|
||||
```swift
|
||||
query.drain { row in
|
||||
print(row)
|
||||
}
|
||||
```
|
||||
|
||||
You can also use `drain(into:)` and pass in a custom `InputStream` to capture the query's results.
|
||||
|
||||
#### Row
|
||||
|
||||
The `Query` will output `Row`s. These are simple structs.
|
||||
|
||||
```swift
|
||||
struct Row {
|
||||
var fields: [String: Field]
|
||||
subscript(field: String) -> Data? { get }
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You can subscript a `Row` object to get the optional `Data`.
|
||||
|
||||
```swift
|
||||
let nameData = row["name"] // Data?
|
||||
```
|
||||
|
||||
`Data` is an enum that contains all possible types of SQLite data.
|
||||
|
||||
```swift
|
||||
public enum Data {
|
||||
case integer(Int)
|
||||
case float(Double)
|
||||
case text(String)
|
||||
case blob(Foundation.Data)
|
||||
case null
|
||||
}
|
||||
```
|
||||
|
||||
For each option, there are convenience properties for casting the `Data` enum.
|
||||
|
||||
```swift
|
||||
let name = row["name"]?.text // String
|
||||
```
|
||||
|
||||
|
||||
### Run
|
||||
|
||||
Once your query is ready to execute, you simply call `.execute()`. This returns a `Future<Void>`
|
||||
that will be completed when the query is done executing.
|
||||
|
||||
```swift
|
||||
query.execute().then {
|
||||
print("done!")
|
||||
}
|
||||
```
|
||||
|
||||
#### All
|
||||
|
||||
If you simply want to fetch all of the results, you can use the `.all()` convenience.
|
||||
This will automatically create a stream and return a future containing your results.
|
||||
|
||||
```swift
|
||||
query.all().then { rows in
|
||||
print(rows)
|
||||
}
|
||||
```
|
||||
|
||||
#### Sync
|
||||
|
||||
For situations where blocking is appropriate (perhaps in tests) you can use `.sync()` to block
|
||||
until the query's results are ready and return them directly.
|
||||
|
||||
```swift
|
||||
// don't do this unless blocking is OK
|
||||
let rows = try conn.query("SELECT * FROM users").sync()
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
Now for the complete example:
|
||||
|
||||
```swift
|
||||
import SQLite
|
||||
|
||||
let db = Database(storage: .memory)
|
||||
let conn = try db.makeConnection(on: .global()) // take care to use correct queue
|
||||
conn.query("SELECT * FROM users")
|
||||
.all()
|
||||
.then { rows in
|
||||
print(rows)
|
||||
}
|
||||
.catch { err in
|
||||
print(err)
|
||||
}
|
||||
|
||||
// wait for results
|
||||
```
|
||||
|
||||
An example with values being bound:
|
||||
|
||||
```swift
|
||||
import SQLite
|
||||
|
||||
let db = Database(storage: .memory)
|
||||
let conn = try db.makeConnection(on: .global()) // take care to use correct queue
|
||||
conn.query("INSERT INTO users (name, age) VALUES (?, ?)")
|
||||
.bind("Albert")
|
||||
.bind(138)
|
||||
.execute()
|
||||
.then {
|
||||
print("done")
|
||||
}
|
||||
.catch { err in
|
||||
print(err)
|
||||
}
|
||||
|
||||
// wait for results
|
||||
```
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# Using SQLite
|
||||
|
||||
The [vapor/sqlite](https://github.com/vapor/sqlite) package is a lightweight, nonblocking/async wrapper around SQLite 3's C API. It provides an intuitive Swift interface for working with SQLite that can be used with any Swift project.
|
||||
|
||||
On top of `[vapor/sqlite](https://github.com/vapor/sqlite)`, we have built `[vapor/fluent-sqlite](https://github.com/vapor/fluent-sqlite)`. This package conforms our SQLite wrapper to Fluent's [driver](fluent/driver.md) protocol, allowing SQLite databases to be used with Fluent.
|
||||
|
||||
## With Fluent
|
||||
|
||||
This package is included with Fluent by default, and serves as Fluent's default database type. To use SQLite with Fluent, just [include Fluent])(fluent/package.md) in your project.
|
||||
|
||||
Then use the following to import `SQLite`.
|
||||
|
||||
```swift
|
||||
import SQLite
|
||||
```
|
||||
|
||||
If you need access to the Fluent driver specifically, use:
|
||||
|
||||
```swift
|
||||
import FluentSQLite
|
||||
```
|
||||
|
||||
## Without Fluent
|
||||
|
||||
This package was built to be a powerful interface for SQLite whether or not you use Fluent. To include this SQLite package in your project, simply add it to your Package manifest.
|
||||
|
||||
```swift
|
||||
// swift-tools-version:4.0
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Project",
|
||||
dependencies: [
|
||||
...
|
||||
.package(url: "https://github.com/vapor/sqlite.git", .upToNextMajor(from: "3.0.0")),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Project", dependencies: ["Async", ... ])
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
Use `import SQLite` to access the Swift SQLite APIs.
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
.md-header {
|
||||
box-shadow: 0px 0px 8px #657590!important;
|
||||
}
|
||||
|
||||
.md-main__inner {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.md-nav__button img {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.md-logo {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.md-sidebar__inner .md-logo {
|
||||
width: 60px!important;
|
||||
}
|
||||
|
||||
.md-header-nav__title {
|
||||
line-height: 4.6rem;
|
||||
}
|
||||
|
||||
@media only screen and (min-width:75em) {
|
||||
.md-header-nav__button img {
|
||||
width: 28px!important;
|
||||
height: 28px!important;
|
||||
}
|
||||
|
||||
.md-main__inner {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width:100em) {
|
||||
.md-header-nav__button img {
|
||||
width: 32px!important;
|
||||
height: 32px!important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width:125em) {
|
||||
.md-header-nav__button img {
|
||||
width: 38px!important;
|
||||
height: 38px!important;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pages:
|
|||
- 'Route Collection': 'vapor/route-collection.md'
|
||||
- 'Route Group': 'vapor/route-group.md'
|
||||
- Async:
|
||||
- 'Index': 'async/index.md'
|
||||
- 'Package': 'async/package.md'
|
||||
- 'Promise & Future': 'async/promise-future.md'
|
||||
- 'Stream': 'async/stream.md'
|
||||
- HTTP:
|
||||
|
|
@ -45,6 +45,9 @@ pages:
|
|||
- 'Message authentication': 'crypto/mac.md'
|
||||
- 'Password hashing': 'crypto/passwords.md'
|
||||
- 'Random': 'crypto/random.md'
|
||||
- SQLite:
|
||||
- 'Package': 'sqlite/package.md'
|
||||
- 'Overview': 'sqlite/overview.md'
|
||||
# - 'Advanced':
|
||||
# - 'RequestParser': 'http/request-parser.md'
|
||||
# - 'RequestSerializer': 'http/request-serializer.md'
|
||||
|
|
|
|||
Loading…
Reference in New Issue