Protocols

The following protocols are available globally.

  • A type that supplies the values of some external resource, one at a time.

    Overview

    The most common way to iterate over the elements of a cursor is to use a while loop:

    let cursor = ...
    while let element = try cursor.next() {
        ...
    }
    

    Relationship with standard Sequence and IteratorProtocol

    Cursors share traits with lazy sequences and iterators from the Swift standard library. Differences are:

    • Cursor types are classes, and have a lifetime.
    • Cursor iteration may throw errors.
    • A cursor can not be repeated.

    The protocol comes with default implementations for many operations similar to those defined by Swift’s LazySequenceProtocol:

    • func contains(Self.Element)
    • func contains(where: (Self.Element) throws -> Bool)
    • func enumerated()
    • func filter((Self.Element) throws -> Bool)
    • func first(where: (Self.Element) throws -> Bool)
    • func flatMap<ElementOfResult>((Self.Element) throws -> ElementOfResult?)
    • func flatMap<SegmentOfResult>((Self.Element) throws -> SegmentOfResult)
    • func forEach((Self.Element) throws -> Void)
    • func joined()
    • func map<T>((Self.Element) throws -> T)
    • func reduce<Result>(Result, (Result, Self.Element) throws -> Result)
    See more

    Declaration

    Swift

    public protocol Cursor : class
  • A transaction observer is notified of all changes and transactions committed or rollbacked on a database.

    Adopting types must be a class.

    See more

    Declaration

    Swift

    public protocol TransactionObserver : class
  • The protocol for all types that can fetch values from a database.

    It is adopted by DatabaseQueue and DatabasePool.

    The protocol comes with isolation guarantees that describe the behavior of adopting types in a multithreaded application.

    Types that adopt the protocol can provide in practice stronger guarantees. For example, DatabaseQueue provides a stronger isolation level than DatabasePool.

    Warning: Isolation guarantees stand as long as there is no external connection to the database. Should you have to cope with external connections, protect yourself with transactions, and be ready to setup a busy handler.

    See more

    Declaration

    Swift

    public protocol DatabaseReader : class
  • Types that adopt DatabaseValueConvertible can be initialized from database values.

    The protocol comes with built-in methods that allow to fetch cursors, arrays, or single values:

    try String.fetchCursor(db, "SELECT name FROM ...", arguments:...) // DatabaseCursor<String>
    try String.fetchAll(db, "SELECT name FROM ...", arguments:...)    // [String]
    try String.fetchOne(db, "SELECT name FROM ...", arguments:...)    // String?
    
    let statement = try db.makeSelectStatement("SELECT name FROM ...")
    try String.fetchCursor(statement, arguments:...) // DatabaseCursor<String>
    try String.fetchAll(statement, arguments:...)    // [String]
    try String.fetchOne(statement, arguments:...)    // String?
    

    DatabaseValueConvertible is adopted by Bool, Int, String, etc.

    See more

    Declaration

    Swift

    public protocol DatabaseValueConvertible : SQLExpressible
  • The protocol for all types that can update a database.

    It is adopted by DatabaseQueue and DatabasePool.

    The protocol comes with isolation guarantees that describe the behavior of adopting types in a multithreaded application.

    Types that adopt the protocol can in practice provide stronger guarantees. For example, DatabaseQueue provides a stronger isolation level than DatabasePool.

    Warning: Isolation guarantees stand as long as there is no external connection to the database. Should you have to cope with external connections, protect yourself with transactions, and be ready to setup a busy handler.

    See more

    Declaration

    Swift

    public protocol DatabaseWriter : DatabaseReader
  • Types that adopt TableMapping declare a particular relationship with a database table.

    Types that adopt both TableMapping and RowConvertible are granted with built-in methods that allow to fetch instances identified by key:

    try Person.fetchOne(db, key: 123)  // Person?
    try Citizenship.fetchOne(db, key: ["personId": 12, "countryId": 45]) // Citizenship?
    

    TableMapping is adopted by Record.

    See more

    Declaration

    Swift

    public protocol TableMapping
  • Types that adopt MutablePersistable can be inserted, updated, and deleted.

    This protocol is intented for types that have an INTEGER PRIMARY KEY, and are interested in the inserted RowID: they can mutate themselves upon successful insertion with the didInsert(with:for:) method.

    The insert() and save() methods are mutating methods.

    See more

    Declaration

    Swift

    public protocol MutablePersistable : TableMapping
  • Types that adopt Persistable can be inserted, updated, and deleted.

    This protocol is intented for types that don’t have an INTEGER PRIMARY KEY.

    Unlike MutablePersistable, the insert() and save() methods are not mutating methods.

    See more

    Declaration

    Swift

    public protocol Persistable : MutablePersistable
  • The protocol for all types that define a way to fetch values from a database.

    Requests can feed the fetching methods of any fetchable type (Row, value, record):

    let request: Request = ...
    try Row.fetchCursor(db, request) // DatabaseCursor<Row>
    try String.fetchAll(db, request) // [String]
    try Person.fetchOne(db, request) // Person?
    
    See more

    Declaration

    Swift

    public protocol Request
  • The protocol for all types that define a way to fetch values from a database, with an attached type.

    Typed requests can fetch if their associated type Fetched is fetchable (Row, value, record)

    let request: ... // Some TypedRequest that fetches Person
    try request.fetchCursor(db) // DatabaseCursor<Person>
    try request.fetchAll(db)    // [Person]
    try request.fetchOne(db)    // Person?
    
    See more

    Declaration

    Swift

    public protocol TypedRequest : Request
  • This protocol is an implementation detail of GRDB. Don’t use it.

    Declaration

    Swift

    public protocol _OptionalFetchable
  • LayoutedRowAdapter is a protocol that supports the RowAdapter protocol.

    GRBD ships with a ready-made type that adopts this protocol: LayoutedColumnMapping.

    See more

    Declaration

    Swift

    public protocol LayoutedRowAdapter
  • RowLayout is a protocol that supports the RowAdapter protocol. It describes a layout of a base row.

    See more

    Declaration

    Swift

    public protocol RowLayout
  • RowAdapter is a protocol that helps two incompatible row interfaces working together.

    GRDB ships with four concrete types that adopt the RowAdapter protocol:

    • ColumnMapping: renames row columns
    • SuffixRowAdapter: hides the first columns of a row
    • RangeRowAdapter: only exposes a range of columns
    • ScopeAdapter: groups several adapters together to define named scopes

    To use a row adapter, provide it to any method that fetches:

    let adapter = SuffixRowAdapter(fromIndex: 2)
    let sql = "SELECT 1 AS foo, 2 AS bar, 3 AS baz"
    
    // <Row baz:3>
    try Row.fetchOne(db, sql, adapter: adapter)
    
    See more

    Declaration

    Swift

    public protocol RowAdapter
  • Types that adopt RowConvertible can be initialized from a database Row.

    let row = try Row.fetchOne(db, "SELECT ...")!
    let person = Person(row)
    

    The protocol comes with built-in methods that allow to fetch cursors, arrays, or single records:

    try Person.fetchCursor(db, "SELECT ...", arguments:...) // DatabaseCursor<Person>
    try Person.fetchAll(db, "SELECT ...", arguments:...)    // [Person]
    try Person.fetchOne(db, "SELECT ...", arguments:...)    // Person?
    
    let statement = try db.makeSelectStatement("SELECT ...")
    try Person.fetchCursor(statement, arguments:...) // DatabaseCursor<Person>
    try Person.fetchAll(statement, arguments:...)    // [Person]
    try Person.fetchOne(statement, arguments:...)    // Person?
    

    RowConvertible is adopted by Record.

    See more

    Declaration

    Swift

    public protocol RowConvertible
  • This protocol is an implementation detail of the query interface. Do not use it directly.

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

    Low Level Query Interface

    SQLSpecificExpressible is a protocol for all query interface types that can be turned into an SQL expression. Other types whose existence is not purely dedicated to the query interface should adopt the SQLExpressible protocol instead.

    For example, Column is a type that only exists to help you build requests, and it adopts SQLSpecificExpressible.

    On the other side, Int adopts SQLExpressible (via DatabaseValueConvertible).

    See more

    Declaration

    Swift

    public protocol SQLSpecificExpressible : SQLExpressible
  • When a type adopts both DatabaseValueConvertible and StatementColumnConvertible, it is granted with faster access to the SQLite database values.

    See more

    Declaration

    Swift

    public protocol StatementColumnConvertible
  • The protocol for SQLite virtual table modules. It lets you define a DSL for the Database.create(virtualTable:using:) method:

    let module = ...
    try db.create(virtualTable: "items", using: module) { t in
        ...
    }
    

    GRDB ships with three concrete classes that implement this protocol: FTS3, FTS4 and FTS5.

    See more

    Declaration

    Swift

    public protocol VirtualTableModule