QueryInterfaceRequest

public struct QueryInterfaceRequest<RowDecoder>
extension QueryInterfaceRequest: FetchRequest
extension QueryInterfaceRequest: SelectionRequest
extension QueryInterfaceRequest: FilteredRequest
extension QueryInterfaceRequest: OrderedRequest
extension QueryInterfaceRequest: AggregatingRequest
extension QueryInterfaceRequest: JoinableRequest
extension QueryInterfaceRequest: TableRequest
extension QueryInterfaceRequest: DerivableRequest

QueryInterfaceRequest is a request that generates SQL for you.

For example:

try dbQueue.read { db in
    let request = Player
        .filter(Column("score") > 1000)
        .order(Column("name"))
    let players = try request.fetchAll(db) // [Player]
}

See https://github.com/groue/GRDB.swift#the-query-interface

Request Derivation

  • Creates a request which selects selection promise.

    // SELECT id, email FROM player
    var request = Player.all()
    request = request.select { db in [Column("id"), Column("email")] }
    

    Any previous selection is replaced:

    // SELECT email FROM player
    request
        .select { db in [Column("id")] }
        .select { db in [Column("email")] }
    

    Declaration

    Swift

    public func select(_ selection: @escaping (Database) throws -> [SQLSelectable]) -> QueryInterfaceRequest
  • Creates a request which selects selection, and fetches values of type type.

    try dbQueue.read { db in
        // SELECT max(score) FROM player
        let request = Player.all().select([max(Column("score"))], as: Int.self)
        let maxScore: Int? = try request.fetchOne(db)
    }
    

    Declaration

    Swift

    public func select<RowDecoder>(_ selection: [SQLSelectable], as type: RowDecoder.Type = RowDecoder.self)
    -> QueryInterfaceRequest<RowDecoder>
  • Creates a request which selects selection, and fetches values of type type.

    try dbQueue.read { db in
        // SELECT max(score) FROM player
        let request = Player.all().select(max(Column("score")), as: Int.self)
        let maxScore: Int? = try request.fetchOne(db)
    }
    

    Declaration

    Swift

    public func select<RowDecoder>(_ selection: SQLSelectable..., as type: RowDecoder.Type = RowDecoder.self)
    -> QueryInterfaceRequest<RowDecoder>
  • Creates a request which selects sql, and fetches values of type type.

    try dbQueue.read { db in
        // SELECT max(score) FROM player
        let request = Player.all().select(sql: "max(score)", as: Int.self)
        let maxScore: Int? = try request.fetchOne(db)
    }
    

    Declaration

    Swift

    public func select<RowDecoder>(
        sql: String,
        arguments: StatementArguments = StatementArguments(),
        as type: RowDecoder.Type = RowDecoder.self)
    -> QueryInterfaceRequest<RowDecoder>
  • Creates a request which selects an SQL literal, and fetches values of type type.

    Literals allow you to safely embed raw values in your SQL, without any risk of syntax errors or SQL injection:

    // SELECT IFNULL(name, 'Anonymous') FROM player
    let defaultName = "Anonymous"
    let request = Player.all().select(
        literal: "IFNULL(name, \(defaultName))",
        as: String.self)
    let name: String? = try request.fetchOne(db)
    

    Declaration

    Swift

    public func select<RowDecoder>(
        literal sqlLiteral: SQL,
        as type: RowDecoder.Type = RowDecoder.self)
    -> QueryInterfaceRequest<RowDecoder>
  • Creates a request which appends selection promise.

    // SELECT id, email, name FROM player
    var request = Player.all()
    request = request
        .select([Column("id"), Column("email")])
        .annotated(with: { db in [Column("name")] })
    

    Declaration

    Swift

    public func annotated(with selection: @escaping (Database) throws -> [SQLSelectable]) -> QueryInterfaceRequest
  • Creates a request with the provided predicate promise added to the eventual set of already applied predicates.

    // SELECT * FROM player WHERE 1
    var request = Player.all()
    request = request.filter { db in true }
    

    Declaration

    Swift

    public func filter(_ predicate: @escaping (Database) throws -> SQLExpressible) -> QueryInterfaceRequest
  • Creates a request with the provided orderings promise.

    // SELECT * FROM player ORDER BY name
    var request = Player.all()
    request = request.order { _ in [Column("name")] }
    

    Any previous ordering is replaced:

    // SELECT * FROM player ORDER BY name
    request
        .order{ _ in [Column("email")] }
        .reversed()
        .order{ _ in [Column("name")] }
    

    Declaration

    Swift

    public func order(_ orderings: @escaping (Database) throws -> [SQLOrderingTerm]) -> QueryInterfaceRequest
  • Creates a request that reverses applied orderings.

    // SELECT * FROM player ORDER BY name DESC
    var request = Player.all().order(Column("name"))
    request = request.reversed()
    

    If no ordering was applied, the returned request is identical.

    // SELECT * FROM player
    var request = Player.all()
    request = request.reversed()
    

    Declaration

    Swift

    public func reversed() -> QueryInterfaceRequest
  • Creates a request without any ordering.

    // SELECT * FROM player
    var request = Player.all().order(Column("name"))
    request = request.unordered()
    

    Declaration

    Swift

    public func unordered() -> QueryInterfaceRequest
  • Creates a request grouped according to expressions promise.

    Declaration

    Swift

    public func group(_ expressions: @escaping (Database) throws -> [SQLExpressible]) -> QueryInterfaceRequest
  • Creates a request with the provided predicate promise added to the eventual set of already applied predicates.

    Declaration

    Swift

    public func having(_ predicate: @escaping (Database) throws -> SQLExpressible) -> QueryInterfaceRequest
  • Creates a request that allows you to define expressions that target a specific database table.

    In the example below, the “team.avgScore < player.score” condition in the ON clause could be not achieved without table aliases.

    struct Player: TableRecord {
        static let team = belongsTo(Team.self)
    }
    
    // SELECT player.*, team.*
    // JOIN team ON ... AND team.avgScore < player.score
    let playerAlias = TableAlias()
    let request = Player
        .all()
        .aliased(playerAlias)
        .including(required: Player.team.filter(Column("avgScore") < playerAlias[Column("score")])
    

    Declaration

    Swift

    public func aliased(_ alias: TableAlias) -> QueryInterfaceRequest
  • Declaration

    Swift

    public func distinct() -> QueryInterfaceRequest
  • Creates a request which fetches limit rows, starting at offset.

    // SELECT * FROM player LIMIT 10 OFFSET 20
    var request = Player.all()
    request = request.limit(10, offset: 20)
    

    Any previous limit is replaced.

    Declaration

    Swift

    public func limit(_ limit: Int, offset: Int?) -> QueryInterfaceRequest
  • Declaration

    Swift

    public func with<RowDecoder>(_ cte: CommonTableExpression<RowDecoder>) -> QueryInterfaceRequest<RowDecoder>
  • Creates a request bound to type RowDecoder.

    The returned request can fetch if the type RowDecoder is fetchable (Row, value, record).

    // Int?
    let maxScore = try Player
        .select(max(scoreColumn))
        .asRequest(of: Int.self)    // <--
        .fetchOne(db)
    

    Declaration

    Swift

    public func asRequest<RowDecoder>(of type: RowDecoder.Type) -> QueryInterfaceRequest<RowDecoder>

    Parameters

    type

    The fetched type RowDecoder

    Return Value

    A request bound to type RowDecoder.

Batch Delete

  • Deletes matching rows; returns the number of deleted rows.

    Throws

    A DatabaseError is thrown whenever an SQLite error occurs.

    Declaration

    Swift

    @discardableResult
    public func deleteAll(_ db: Database) throws -> Int

    Parameters

    db

    A database connection.

    Return Value

    The number of deleted rows

Batch Update

  • Updates matching rows; returns the number of updated rows.

    For example:

    try dbQueue.write { db in
        // UPDATE player SET score = 0
        try Player.all().updateAll(db, [Column("score").set(to: 0)])
    }
    

    Throws

    A DatabaseError is thrown whenever an SQLite error occurs.

    Declaration

    Swift

    @discardableResult
    public func updateAll(
        _ db: Database,
        onConflict conflictResolution: Database.ConflictResolution? = nil,
        _ assignments: [ColumnAssignment]) throws -> Int

    Parameters

    db

    A database connection.

    conflictResolution

    A policy for conflict resolution.

    assignments

    An array of column assignments.

    Return Value

    The number of updated rows.

  • Updates matching rows; returns the number of updated rows.

    For example:

    try dbQueue.write { db in
        // UPDATE player SET score = 0
        try Player.all().updateAll(db, Column("score").set(to: 0))
    }
    

    Throws

    A DatabaseError is thrown whenever an SQLite error occurs.

    Declaration

    Swift

    @discardableResult
    public func updateAll(
        _ db: Database,
        onConflict conflictResolution: Database.ConflictResolution? = nil,
        _ assignment: ColumnAssignment,
        _ otherAssignments: ColumnAssignment...)
    throws -> Int

    Parameters

    db

    A database connection.

    conflictResolution

    A policy for conflict resolution.

    assignment

    A column assignment.

    otherAssignments

    Eventual other column assignments.

    Return Value

    The number of updated rows.

Available where RowDecoder: Identifiable, RowDecoder.ID: DatabaseValueConvertible

  • Creates a request which selects the primary key.

    // SELECT id FROM player WHERE ...
    let request = try Player.filter(...).selectID()
    

    Declaration

    Swift

    public func selectID() -> QueryInterfaceRequest<RowDecoder.ID>

Available where RowDecoder: Identifiable, RowDecoder.ID: _OptionalProtocol, RowDecoder.ID.Wrapped: DatabaseValueConvertible

  • Creates a request which selects the primary key.

    // SELECT id FROM player WHERE ...
    let request = try Player.filter(...).selectID()
    

    Declaration

    Swift

    public func selectID() -> QueryInterfaceRequest<RowDecoder.ID.Wrapped>