mirror of https://github.com/vapor/docs.git
195 lines
8.6 KiB
Markdown
195 lines
8.6 KiB
Markdown
# 高度な使い方 {#advanced}
|
|
|
|
Fluentは、データを扱うための汎用的でデータベースに依存しないAPIの作成を目指しています。これにより、どのデータベースドライバーを使用しているかに関わらず、Fluentを学習しやすくなります。汎用的なAPIを作成することで、Swiftでデータベースを扱う際により自然に感じられるようになります。
|
|
|
|
しかし、Fluentでまだサポートされていない基礎となるデータベースドライバーの機能を使用する必要がある場合があります。このガイドでは、特定のデータベースでのみ動作するFluentの高度なパターンとAPIについて説明します。
|
|
|
|
## SQL {#sql}
|
|
|
|
Fluentのすべての SQLデータベースドライバーは[SQLKit](https://github.com/vapor/sql-kit)上に構築されています。この汎用SQL実装は、`FluentSQL`モジュールでFluentと共に提供されています。
|
|
|
|
### SQLデータベース {#sql-database}
|
|
|
|
任意のFluent `Database`は`SQLDatabase`にキャストできます。これには`req.db`、`app.db`、`Migration`に渡される`database`などが含まれます。
|
|
|
|
```swift
|
|
import FluentSQL
|
|
|
|
if let sql = req.db as? SQLDatabase {
|
|
// 基礎となるデータベースドライバーはSQLです。
|
|
let planets = try await sql.raw("SELECT * FROM planets").all(decoding: Planet.self)
|
|
} else {
|
|
// 基礎となるデータベースドライバーはSQLではありません。
|
|
}
|
|
```
|
|
|
|
このキャストは、基礎となるデータベースドライバーがSQLデータベースである場合にのみ機能します。`SQLDatabase`のメソッドについては、[SQLKitのREADME](https://github.com/vapor/sql-kit)で詳しく学べます。
|
|
|
|
### 特定のSQLデータベース {#specific-sql-database}
|
|
|
|
ドライバーをインポートすることで、特定のSQLデータベースにキャストすることもできます。
|
|
|
|
```swift
|
|
import FluentPostgresDriver
|
|
|
|
if let postgres = req.db as? PostgresDatabase {
|
|
// 基礎となるデータベースドライバーはPostgreSQLです。
|
|
postgres.simpleQuery("SELECT * FROM planets").all()
|
|
} else {
|
|
// 基礎となるデータベースはPostgreSQLではありません。
|
|
}
|
|
```
|
|
|
|
執筆時点で、以下のSQLドライバーがサポートされています。
|
|
|
|
|データベース|ドライバー|ライブラリ|
|
|
|-|-|-|
|
|
|`PostgresDatabase`|[vapor/fluent-postgres-driver](https://github.com/vapor/fluent-postgres-driver)|[vapor/postgres-nio](https://github.com/vapor/postgres-nio)|
|
|
|`MySQLDatabase`|[vapor/fluent-mysql-driver](https://github.com/vapor/fluent-mysql-driver)|[vapor/mysql-nio](https://github.com/vapor/mysql-nio)|
|
|
|`SQLiteDatabase`|[vapor/fluent-sqlite-driver](https://github.com/vapor/fluent-sqlite-driver)|[vapor/sqlite-nio](https://github.com/vapor/sqlite-nio)|
|
|
|
|
データベース固有のAPIについての詳細は、各ライブラリのREADMEをご覧ください。
|
|
|
|
### SQLカスタム {#sql-custom}
|
|
|
|
Fluentのクエリとスキーマタイプのほぼすべてが`.custom`ケースをサポートしています。これにより、Fluentがまだサポートしていないデータベース機能を利用できます。
|
|
|
|
```swift
|
|
import FluentPostgresDriver
|
|
|
|
let query = Planet.query(on: req.db)
|
|
if req.db is PostgresDatabase {
|
|
// ILIKEがサポートされています。
|
|
query.filter(\.$name, .custom("ILIKE"), "earth")
|
|
} else {
|
|
// ILIKEはサポートされていません。
|
|
query.group(.or) { or in
|
|
or.filter(\.$name == "earth").filter(\.$name == "Earth")
|
|
}
|
|
}
|
|
query.all()
|
|
```
|
|
|
|
SQLデータベースは、すべての`.custom`ケースで`String`と`SQLExpression`の両方をサポートしています。`FluentSQL`モジュールは、一般的な使用例のための便利なメソッドを提供しています。
|
|
|
|
```swift
|
|
import FluentSQL
|
|
|
|
let query = Planet.query(on: req.db)
|
|
if req.db is SQLDatabase {
|
|
// 基礎となるデータベースドライバーはSQLです。
|
|
query.filter(.sql(raw: "LOWER(name) = 'earth'"))
|
|
} else {
|
|
// 基礎となるデータベースドライバーはSQLではありません。
|
|
}
|
|
```
|
|
|
|
以下は、スキーマビルダーで`.sql(raw:)`の便利な機能を介して`.custom`を使用する例です。
|
|
|
|
```swift
|
|
import FluentSQL
|
|
|
|
let builder = database.schema("planets").id()
|
|
if database is MySQLDatabase {
|
|
// 基礎となるデータベースドライバーはMySQLです。
|
|
builder.field("name", .sql(raw: "VARCHAR(64)"), .required)
|
|
} else {
|
|
// 基礎となるデータベースドライバーはMySQLではありません。
|
|
builder.field("name", .string, .required)
|
|
}
|
|
builder.create()
|
|
```
|
|
|
|
## MongoDB {#mongodb}
|
|
|
|
Fluent MongoDBは、[Fluent](../fluent/overview.md)と[MongoKitten](https://github.com/OpenKitten/MongoKitten/)ドライバー間の統合です。Swiftの強力な型システムとFluentのデータベース非依存インターフェースをMongoDBで活用します。
|
|
|
|
MongoDBで最も一般的な識別子はObjectIdです。`@ID(custom: .id)`を使用してプロジェクトでこれを使用できます。
|
|
SQLで同じモデルを使用する必要がある場合は、`ObjectId`を使用しないでください。代わりに`UUID`を使用してください。
|
|
|
|
```swift
|
|
final class User: Model {
|
|
// テーブルまたはコレクションの名前。
|
|
static let schema = "users"
|
|
|
|
// このUserの一意識別子。
|
|
// この場合、ObjectIdが使用されています
|
|
// Fluentはデフォルトで UUID の使用を推奨しますが、ObjectIdもサポートされています
|
|
@ID(custom: .id)
|
|
var id: ObjectId?
|
|
|
|
// ユーザーのメールアドレス
|
|
@Field(key: "email")
|
|
var email: String
|
|
|
|
// BCryptハッシュとして保存されるユーザーのパスワード
|
|
@Field(key: "password")
|
|
var passwordHash: String
|
|
|
|
// Fluentが使用するための新しい空のUserインスタンスを作成します
|
|
init() { }
|
|
|
|
// すべてのプロパティが設定された新しいUserを作成します。
|
|
init(id: ObjectId? = nil, email: String, passwordHash: String, profile: Profile) {
|
|
self.id = id
|
|
self.email = email
|
|
self.passwordHash = passwordHash
|
|
self.profile = profile
|
|
}
|
|
}
|
|
```
|
|
|
|
### データモデリング {#data-modelling}
|
|
|
|
MongoDBでは、モデルは他のFluent環境と同じように定義されます。SQLデータベースとMongoDBの主な違いは、リレーションシップとアーキテクチャにあります。
|
|
|
|
SQL環境では、2つのエンティティ間の関係のために結合テーブルを作成することが非常に一般的です。しかし、MongoDBでは、配列を使用して関連する識別子を保存できます。MongoDBの設計により、ネストされたデータ構造でモデルを設計する方がより効率的で実用的です。
|
|
|
|
### 柔軟なデータ {#flexible-data}
|
|
|
|
MongoDBでは柔軟なデータを追加できますが、このコードはSQL環境では動作しません。
|
|
グループ化された任意のデータストレージを作成するには、`Document`を使用できます。
|
|
|
|
```swift
|
|
@Field(key: "document")
|
|
var document: Document
|
|
```
|
|
|
|
Fluentはこれらの値に対する厳密に型付けされたクエリをサポートできません。クエリでドット記法のキーパスを使用できます。
|
|
これは、ネストされた値にアクセスするためにMongoDBで受け入れられています。
|
|
|
|
```swift
|
|
Something.query(on: db).filter("document.key", .equal, 5).first()
|
|
```
|
|
|
|
### 正規表現の使用 {#use-of-regular-expressions}
|
|
|
|
`.custom()`ケースを使用し、正規表現を渡してMongoDBをクエリできます。[MongoDB](https://www.mongodb.com/docs/manual/reference/operator/query/regex/)はPerl互換の正規表現を受け入れます。
|
|
|
|
例えば、`name`フィールドで大文字と小文字を区別しない文字をクエリできます:
|
|
|
|
```swift
|
|
import FluentMongoDriver
|
|
|
|
var queryDocument = Document()
|
|
queryDocument["name"]["$regex"] = "e"
|
|
queryDocument["name"]["$options"] = "i"
|
|
|
|
let planets = try Planet.query(on: req.db).filter(.custom(queryDocument)).all()
|
|
```
|
|
|
|
これは'e'と'E'を含む惑星を返します。MongoDBが受け入れる他の複雑な正規表現も作成できます。
|
|
|
|
### 生のアクセス {#raw-access}
|
|
|
|
生の`MongoDatabase`インスタンスにアクセスするには、データベースインスタンスを`MongoDatabaseRepresentable`にキャストします:
|
|
|
|
```swift
|
|
guard let db = req.db as? MongoDatabaseRepresentable else {
|
|
throw Abort(.internalServerError)
|
|
}
|
|
|
|
let mongodb = db.raw
|
|
```
|
|
|
|
ここから、すべてのMongoKitten APIを使用できます。 |