Ga naar inhoud

Geavanceerd

Fluent streeft ernaar een algemene, database-agnostische API te maken voor het werken met uw data. Dit maakt het makkelijker om Fluent te leren, ongeacht welke database driver je gebruikt. Het maken van gegeneraliseerde API's kan er ook voor zorgen dat het werken met je database zich meer thuis voelt in Swift.

Het kan echter zijn dat u een functie van uw onderliggende database driver moet gebruiken die nog niet door Fluent wordt ondersteund. Deze gids behandelt geavanceerde patronen en API's in Fluent die alleen werken met bepaalde databases.

SQL

Alle SQL database drivers van Fluent zijn gebouwd op SQLKit. Deze algemene SQL-implementatie wordt met Fluent meegeleverd in de FluentSQL module.

SQL Database

Elke Fluent Database kan worden gecast naar een SQLDatabase. Dit omvat req.db, app.db, de database doorgegeven aan Migration, enz.

import FluentSQL

if let sql = req.db as? SQLDatabase {
    // Het onderliggende databasestuurprogramma is SQL.
    let planets = try await sql.raw("SELECT * FROM planets").all(decoding: Planet.self)
} else {
    // Het onderliggende databasestuurprogramma is _niet_ SQL.
}

Deze cast werkt alleen als de onderliggende database driver een SQL database is. Leer meer over SQLDatabase's methodes in SQLKit's README.

Specifieke SQL Database

U kunt ook naar specifieke SQL-databases casten door het stuurprogramma te importeren.

import FluentPostgresDriver

if let postgres = req.db as? PostgresDatabase {
    // Het onderliggende databasestuurprogramma is PostgreSQL.
    postgres.simpleQuery("SELECT * FROM planets").all()
} else {
    // De onderliggende database is _niet_ PostgreSQL.
}

Op het moment van schrijven worden de volgende SQL drivers ondersteund.

Database Driver Library
PostgresDatabase vapor/fluent-postgres-driver vapor/postgres-nio
MySQLDatabase vapor/fluent-mysql-driver vapor/mysql-nio
SQLiteDatabase vapor/fluent-sqlite-driver vapor/sqlite-nio

Bezoek de README van de bibliotheek voor meer informatie over de database-specifieke API's.

SQL Custom

Bijna alle query en schema types van Fluent ondersteunen een .custom case. Hiermee kunt u databasefuncties gebruiken die Fluent nog niet ondersteunt.

import FluentPostgresDriver

let query = Planet.query(on: req.db)
if req.db is PostgresDatabase {
    // ILIKE ondersteund.
    query.filter(\.$name, .custom("ILIKE"), "earth")
} else {
    // ILIKE niet ondersteund.
    query.group(.or) { or in
        or.filter(\.$name == "earth").filter(\.$name == "Earth")
    }
}
query.all()

SQL databases ondersteunen zowel String als SQLExpression in alle .custom gevallen. De FluentSQL module biedt handige methodes voor veel voorkomende gevallen.

import FluentSQL

let query = Planet.query(on: req.db)
if req.db is SQLDatabase {
    // Het onderliggende databasestuurprogramma is SQL.
    query.filter(.sql(raw: "LOWER(name) = 'earth'"))
} else {
    // Het onderliggende databasestuurprogramma is _niet_ SQL.
}

Hieronder staat een voorbeeld van .custom via het .sql(raw:) gemak dat wordt gebruikt met de schema bouwer.

import FluentSQL

let builder = database.schema("planets").id()
if database is MySQLDatabase {
    // Het onderliggende databasestuurprogramma is MySQL.
    builder.field("name", .sql(raw: "VARCHAR(64)"), .required)
} else {
    // Het onderliggende databasestuurprogramma is _niet_ MySQL.
    builder.field("name", .string, .required)
}
builder.create()

MongoDB

Fluent MongoDB is een integratie tussen Fluent en de MongoKitten driver. Het maakt gebruik van het sterke typesysteem van Swift en de database agnostische interface van Fluent met MongoDB.

De meest voorkomende identifier in MongoDB is ObjectId. U kunt deze gebruiken voor uw project met @ID(custom: .id). Als u dezelfde modellen met SQL wilt gebruiken, gebruik dan niet ObjectId. Gebruik in plaats daarvan UUID.

final class User: Model {
    // Naam van de tabel of verzameling.
    static let schema = "users"

    // Unieke identificatie voor deze Gebruiker.
    // In dit geval wordt ObjectId gebruikt
    // Fluent raadt aan om standaard UUID te gebruiken, maar ObjectId wordt ook ondersteund
    @ID(custom: .id)
    var id: ObjectId?

    // Het e-mailadres van de gebruiker
    @Field(key: "email")
    var email: String

    // Het wachtwoord van de gebruiker wordt opgeslagen als een BCrypt hash
    @Field(key: "password")
    var passwordHash: String

    // Creëert een nieuwe, lege User instantie, voor gebruik door Fluent
    init() { }

    // Creëert een nieuwe Gebruiker met alle eigenschappen ingesteld.
    init(id: ObjectId? = nil, email: String, passwordHash: String, profile: Profile) {
        self.id = id
        self.email = email
        self.passwordHash = passwordHash
        self.profile = profile
    }
}

Data Modelleren

In MongoDB worden Modellen op dezelfde manier gedefinieerd als in elke andere Fluent omgeving. Het belangrijkste verschil tussen SQL-databases en MongoDB ligt in relaties en architectuur.

In SQL-omgevingen, is het heel gebruikelijk om join tabellen voor relaties tussen twee entiteiten te creëren. In MongoDB, echter, kan een array worden gebruikt om gerelateerde identifiers op te slaan. Door het ontwerp van MongoDB is het efficiënter en praktischer om uw modellen te ontwerpen met geneste gegevensstructuren.

Flexibele Data

U kunt flexibele gegevens toevoegen in MongoDB, maar deze code zal niet werken in SQL-omgevingen. Om gegroepeerde willekeurige data opslag te maken kun je Document gebruiken.

@Field(key: "document")
var document: Document

Fluent kan geen query's van strikte types op deze waarden ondersteunen. U kunt een met punten genoteerd sleutelpad in uw query gebruiken om query's uit te voeren. Dit wordt in MongoDB geaccepteerd om toegang te krijgen tot geneste waarden.

Something.query(on: db).filter("document.key", .equal, 5).first()

Gebruik van reguliere expressies

Door een reguliere expressie door te geven met de .custom() case, kan U de MongoDB raadplegen. MongoDB accepteert reguliere expressies die compatibel zijn met Perl.

Zo kan U bijvoorbeeld zoeken naar hoofdletterongevoelige tekens onder het veld naam:

import FluentMongoDriver

var queryDocument = Document()
queryDocument["name"]["$regex"] = "e"
queryDocument["name"]["$options"] = "i"
let planets = try Planet.query(on: req.db).filter(.custom(nameDocument)).all()

Dit geeft planeten terug die 'e' en 'E' bevatten. U kunt ook elke andere complexe RegEx maken die door MongoDB wordt geaccepteerd.

Raw Access

Om toegang te krijgen tot de ruwe MongoDatabase instantie, cast je de database instantie naar MongoDatabaseRepresentable als zodanig:

guard let db = req.db as? MongoDatabaseRepresentable else {
  throw Abort(.internalServerError)
}

let mongodb = db.raw

Vanaf hier kunt u gebruik maken van alle van de MongoKitten API's.