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)
Declaration
Swift
public protocol Cursor : class
-
The protocol for custom SQLite aggregates.
For example:
See morestruct MySum : DatabaseAggregate { var sum: Int = 0 mutating func step(_ dbValues: [DatabaseValue]) { if let int = Int.fromDatabaseValue(dbValues[0]) { sum += int } } func finalize() -> DatabaseValueConvertible? { return sum } } let dbQueue = DatabaseQueue() let fn = DatabaseFunction("mysum", argumentCount: 1, aggregate: MySum.self) dbQueue.add(function: fn) try dbQueue.inDatabase { db in try db.execute("CREATE TABLE test(i)") try db.execute("INSERT INTO test(i) VALUES (1)") try db.execute("INSERT INTO test(i) VALUES (2)") try Int.fetchOne(db, "SELECT mysum(i) FROM test")! // 3 }
Declaration
Swift
public protocol DatabaseAggregate
-
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 moreDeclaration
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:...) // Cursor of 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:...) // Cursor of String try String.fetchAll(statement, arguments:...) // [String] try String.fetchOne(statement, arguments:...) // String?
DatabaseValueConvertible is adopted by Bool, Int, String, etc.
See moreDeclaration
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 moreDeclaration
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 Player.fetchOne(db, key: 123) // Player? try Citizenship.fetchOne(db, key: ["citizenId": 12, "countryId": 45]) // Citizenship?
TableMapping is adopted by Record.
See moreDeclaration
Swift
public protocol TableMapping
-
The protocol for custom FTS5 tokenizers.
See more
-
The protocol for FTS5 tokenizers
See more
-
The protocol for custom FTS5 tokenizers that wrap another tokenizer.
Types that adopt FTS5WrapperTokenizer don’t have to implement the low-level FTS5Tokenizer.tokenize(context:flags:pText:nText:tokenCallback:).
Instead, they process regular Swift strings.
Here is the implementation for a trivial tokenizer that wraps the built-in ascii tokenizer without any custom processing:
See moreclass TrivialAsciiTokenizer : FTS5WrapperTokenizer { static let name = "trivial" let wrappedTokenizer: FTS5Tokenizer init(db: Database, arguments: [String]) throws { wrappedTokenizer = try db.makeTokenizer(.ascii()) } func accept(token: String, flags: FTS5TokenFlags, for tokenization: FTS5Tokenization, tokenCallback: FTS5WrapperTokenCallback) throws { try tokenCallback(token, flags) } }
-
Types that adopt MutablePersistable can be inserted, updated, and deleted.
See moreDeclaration
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 moreDeclaration
Swift
public protocol Persistable : MutablePersistable
-
The protocol for all types that define a way to fetch database rows.
Requests can feed the fetching methods of any fetchable type (Row, value, record):
See morelet request: Request = ... try Row.fetchCursor(db, request) // RowCursor try String.fetchAll(db, request) // [String] try Player.fetchOne(db, request) // Player?
Declaration
Swift
public protocol Request
-
The protocol for requests that know how to decode database rows.
Typed requests can fetch if their associated type RowDecoder is able to decode rows (Row, value, record)
See morestruct Player: RowConvertible { ... } let request: ... // Some TypedRequest that fetches Player try request.fetchCursor(db) // Cursor of Player try request.fetchAll(db) // [Player] try request.fetchOne(db) // Player?
Declaration
Swift
public protocol TypedRequest : Request
-
LayoutedRowAdapter is a protocol that supports the RowAdapter protocol.
GRBD ships with a ready-made type that adopts this protocol: LayoutedColumnMapping.
See moreDeclaration
Swift
public protocol LayoutedRowAdapter
-
RowLayout is a protocol that supports the RowAdapter protocol. It describes a layout of a base row.
See moreDeclaration
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:
See morelet 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)
Declaration
Swift
public protocol RowAdapter
-
Types that adopt RowConvertible can be initialized from a database Row.
let row = try Row.fetchOne(db, "SELECT ...")! let player = Player(row)
The protocol comes with built-in methods that allow to fetch cursors, arrays, or single records:
try Player.fetchCursor(db, "SELECT ...", arguments:...) // Cursor of Player try Player.fetchAll(db, "SELECT ...", arguments:...) // [Player] try Player.fetchOne(db, "SELECT ...", arguments:...) // Player? let statement = try db.makeSelectStatement("SELECT ...") try Player.fetchCursor(statement, arguments:...) // Cursor of Player try Player.fetchAll(statement, arguments:...) // [Player] try Player.fetchOne(statement, arguments:...) // Player?
RowConvertible is adopted by Record.
See moreDeclaration
Swift
public protocol RowConvertible
-
Declaration
Swift
public protocol SQLCollection
-
The protocol for all types that can be turned into an SQL expression.
It is adopted by protocols like DatabaseValueConvertible, and types like Column.
See https://github.com/groue/GRDB.swift/#the-query-interface
See moreDeclaration
Swift
public protocol SQLExpressible
-
SQLSpecificExpressible is a protocol for all database-specific types that can be turned into an SQL expression. Types whose existence is not purely dedicated to the database 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 moreDeclaration
Swift
public protocol SQLSpecificExpressible : SQLExpressible
-
SQLExpression is the protocol for types that represent an SQL expression, as described at https://www.sqlite.org/lang_expr.html
GRDB ships with a variety of types that already adopt this protocol, and allow to represent many SQLite expressions:
- Column
- DatabaseValue
- SQLExpressionLiteral
- SQLExpressionUnary
- SQLExpressionBinary
- SQLExpressionExists
- SQLExpressionFunction
- SQLExpressionCollate
Declaration
Swift
public protocol SQLExpression : SQLSpecificExpressible, SQLSelectable, SQLOrderingTerm
-
The protocol for all types that can be used as an SQL ordering term, as described at https://www.sqlite.org/syntax/ordering-term.html
See moreDeclaration
Swift
public protocol SQLOrderingTerm
-
SQLSelectable is the protocol for types that can be selected, as described at https://www.sqlite.org/syntax/result-column.html
See moreDeclaration
Swift
public protocol SQLSelectable
-
The StatementColumnConvertible protocol grants access to the low-level C interface that extracts values from query results: https://www.sqlite.org/c3ref/column_blob.html. It can bring performance improvements.
To use it, have a value type adopt both StatementColumnConvertible and DatabaseValueConvertible. GRDB will then automatically apply the optimization whenever direct access to SQLite is possible:
let rows = Row.fetchCursor(db, "SELECT ...") while let row = try rows.next() { let int: Int = row[0] // there } let ints = Int.fetchAll(db, "SELECT ...") // there struct Player { init(row: Row) { name = row["name"] // there score = row["score"] // there } }
StatementColumnConvertible is already adopted by all Swift integer types, Float, Double, String, and Bool.
See moreDeclaration
Swift
public protocol StatementColumnConvertible
-
A transaction observer is notified of all changes and transactions committed or rollbacked on a database.
Adopting types must be a class.
See moreDeclaration
Swift
public protocol TransactionObserver : class
-
This protocol is an implementation detail of GRDB. Don’t use it.
Declaration
Swift
public protocol _OptionalProtocol
-
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 moreDeclaration
Swift
public protocol VirtualTableModule