Database
public final class Database
A Database connection.
You don’t create a database directly. Instead, you use a DatabaseQueue, or a DatabasePool:
let dbQueue = DatabaseQueue(...)
// The Database is the `db` in the closure:
try dbQueue.inDatabase { db in
try db.execute(...)
}
-
See BusyMode and https://www.sqlite.org/c3ref/busy_handler.html
Declaration
Swift
public typealias BusyCallback = (_ numberOfTries: Int) -> Bool
-
When there are several connections to a database, a connection may try to access the database while it is locked by another connection.
The BusyMode enum describes the behavior of GRDB when such a situation occurs:
.immediateError: The SQLITE_BUSY error is immediately returned to the connection that tries to access the locked database.
.timeout: The SQLITE_BUSY error will be returned only if the database remains locked for more than the specified duration.
.callback: Perform your custom lock handling.
To set the busy mode of a database, use Configuration:
let configuration = Configuration(busyMode: .timeout(1)) let dbQueue = DatabaseQueue(path: "...", configuration: configuration)
Relevant SQLite documentation:
- https://www.sqlite.org/c3ref/busy_timeout.html
- https://www.sqlite.org/c3ref/busy_handler.html
- https://www.sqlite.org/lang_transaction.html
- https://www.sqlite.org/wal.html
Declaration
Swift
public enum BusyMode
-
The available checkpoint modes.
See moreDeclaration
Swift
public enum CheckpointMode: Int32
-
Declaration
Swift
public struct CollationName : RawRepresentable, Hashable
-
Declaration
Swift
public enum ConflictResolution : String
-
An SQL column type.
try db.create(table: "persons") { t in t.column("id", .integer).primaryKey() t.column("title", .text) }
See https://www.sqlite.org/datatype3.html
See moreDeclaration
Swift
public struct ColumnType : RawRepresentable, Hashable
-
Declaration
Swift
public enum ForeignKeyAction : String
-
An SQLite transaction kind. See https://www.sqlite.org/lang_transaction.html
See moreDeclaration
Swift
public enum TransactionKind
-
The end of a transaction: Commit, or Rollback
See moreDeclaration
Swift
public enum TransactionCompletion
-
log function that takes an error message.
Declaration
Swift
public typealias LogErrorFunction = (_ resultCode: ResultCode, _ message: String) -> Void
-
The error logging function.
Quoting https://www.sqlite.org/errlog.html:
SQLite can be configured to invoke a callback function containing an error code and a terse error message whenever anomalies occur. This mechanism is very helpful in tracking obscure problems that occur rarely and in the field. Application developers are encouraged to take advantage of the error logging facility of SQLite in their products, as it is very low CPU and memory cost but can be a huge aid for debugging.
Declaration
Swift
public static var logError: LogErrorFunction? = nil
-
The database configuration
Declaration
Swift
public let configuration: Configuration
-
The raw SQLite connection, suitable for the SQLite C API.
Declaration
Swift
public let sqliteConnection: SQLiteConnection
-
The rowID of the most recently inserted row.
If no row has ever been inserted using this database connection, returns zero.
For more detailed information, see https://www.sqlite.org/c3ref/last_insert_rowid.html
Declaration
Swift
public var lastInsertedRowID: Int64
-
The number of rows modified, inserted or deleted by the most recent successful INSERT, UPDATE or DELETE statement.
For more detailed information, see https://www.sqlite.org/c3ref/changes.html
Declaration
Swift
public var changesCount: Int
-
The total number of rows modified, inserted or deleted by all successful INSERT, UPDATE or DELETE statements since the database connection was opened.
For more detailed information, see https://www.sqlite.org/c3ref/total_changes.html
Declaration
Swift
public var totalChangesCount: Int
-
True if the database connection is currently in a transaction.
Declaration
Swift
public var isInsideTransaction: Bool
-
Returns a new prepared statement that can be reused.
let statement = try db.makeSelectStatement("SELECT COUNT(*) FROM persons WHERE age > ?") let moreThanTwentyCount = try Int.fetchOne(statement, arguments: [20])! let moreThanThirtyCount = try Int.fetchOne(statement, arguments: [30])!
Throws
A DatabaseError whenever SQLite could not parse the sql query.Declaration
Swift
public func makeSelectStatement(_ sql: String) throws -> SelectStatement
Parameters
sql
An SQL query.
Return Value
A SelectStatement.
-
Returns a prepared statement that can be reused.
let statement = try db.cachedSelectStatement("SELECT COUNT(*) FROM persons WHERE age > ?") let moreThanTwentyCount = try Int.fetchOne(statement, arguments: [20])! let moreThanThirtyCount = try Int.fetchOne(statement, arguments: [30])!
The returned statement may have already been used: it may or may not contain values for its eventual arguments.
Throws
A DatabaseError whenever SQLite could not parse the sql query.Declaration
Swift
public func cachedSelectStatement(_ sql: String) throws -> SelectStatement
Parameters
sql
An SQL query.
Return Value
An UpdateStatement.
-
Returns a new prepared statement that can be reused.
let statement = try db.makeUpdateStatement("INSERT INTO persons (name) VALUES (?)") try statement.execute(arguments: ["Arthur"]) try statement.execute(arguments: ["Barbara"])
Throws
A DatabaseError whenever SQLite could not parse the sql query.Declaration
Swift
public func makeUpdateStatement(_ sql: String) throws -> UpdateStatement
Parameters
sql
An SQL query.
Return Value
An UpdateStatement.
-
Returns a prepared statement that can be reused.
let statement = try db.cachedUpdateStatement("INSERT INTO persons (name) VALUES (?)") try statement.execute(arguments: ["Arthur"]) try statement.execute(arguments: ["Barbara"])
The returned statement may have already been used: it may or may not contain values for its eventual arguments.
Throws
A DatabaseError whenever SQLite could not parse the sql query.Declaration
Swift
public func cachedUpdateStatement(_ sql: String) throws -> UpdateStatement
Parameters
sql
An SQL query.
Return Value
An UpdateStatement.
-
Executes one or several SQL statements, separated by semi-colons.
try db.execute( "INSERT INTO persons (name) VALUES (:name)", arguments: ["name": "Arthur"]) try db.execute( "INSERT INTO persons (name) VALUES (?);" + "INSERT INTO persons (name) VALUES (?);" + "INSERT INTO persons (name) VALUES (?);", arguments; ['Arthur', 'Barbara', 'Craig'])
This method may throw a DatabaseError.
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func execute(_ sql: String, arguments: StatementArguments? = nil) throws
Parameters
sql
An SQL query.
arguments
Optional statement arguments.
-
Add or redefine an SQL function.
let fn = DatabaseFunction("succ", argumentCount: 1) { databaseValues in let dbv = databaseValues.first! guard let int = dbv.value() as Int? else { return nil } return int + 1 } db.add(function: fn) try Int.fetchOne(db, "SELECT succ(1)")! // 2
Declaration
Swift
public func add(function: DatabaseFunction)
-
Remove an SQL function.
Declaration
Swift
public func remove(function: DatabaseFunction)
-
Add or redefine a collation.
let collation = DatabaseCollation("localized_standard") { (string1, string2) in return (string1 as NSString).localizedStandardCompare(string2) } db.add(collation: collation) try db.execute("CREATE TABLE files (name TEXT COLLATE localized_standard")
Declaration
Swift
public func add(collation: DatabaseCollation)
-
Remove a collation.
Declaration
Swift
public func remove(collation: DatabaseCollation)
-
Clears the database schema cache.
You may need to clear the cache manually if the database schema is modified by another connection.
Declaration
Swift
public func clearSchemaCache()
-
Returns whether a table exists.
Declaration
Swift
public func tableExists(_ tableName: String) throws -> Bool
-
The primary key for table named
tableName
; nil if table has no primary key.Throws
A DatabaseError if table does not exist.Declaration
Swift
public func primaryKey(_ tableName: String) throws -> PrimaryKeyInfo?
-
The number of columns in the table named
tableName
.Throws
A DatabaseError if table does not exist.Declaration
Swift
public func columnCount(in tableName: String) throws -> Int
-
The indexes on table named
tableName
; returns the empty array if the table does not exist.Note: SQLite does not define any index for INTEGER PRIMARY KEY columns: this method does not return any index that represents this primary key.
If you want to know if a set of columns uniquely identify a row, prefer table(_:hasUniqueKey:) instead.
Declaration
Swift
public func indexes(on tableName: String) throws -> [IndexInfo]
-
True if a sequence of columns uniquely identifies a row, that is to say if the columns are the primary key, or if there is a unique index on them.
Declaration
Swift
public func table<T: Sequence>(_ tableName: String, hasUniqueKey columns: T) throws -> Bool where T.Iterator.Element == String
-
Executes a block inside a database transaction.
try dbQueue.inDatabase do { try db.inTransaction { try db.execute("INSERT ...") return .commit } }
If the block throws an error, the transaction is rollbacked and the error is rethrown.
This method is not reentrant: you can’t nest transactions.
Throws
The error thrown by the block.Declaration
Swift
public func inTransaction(_ kind: TransactionKind? = nil, _ block: () throws -> TransactionCompletion) throws
Parameters
kind
The transaction type (default nil). If nil, the transaction type is configuration.defaultTransactionKind, which itself defaults to .immediate. See https://www.sqlite.org/lang_transaction.html for more information.
block
A block that executes SQL statements and return either .commit or .rollback.
-
Executes a block inside a savepoint.
try dbQueue.inDatabase do { try db.inSavepoint { try db.execute("INSERT ...") return .commit } }
If the block throws an error, the savepoint is rollbacked and the error is rethrown.
This method is reentrant: you can nest savepoints.
Throws
The error thrown by the block.Declaration
Swift
public func inSavepoint(_ block: () throws -> TransactionCompletion) throws
Parameters
block
A block that executes SQL statements and return either .commit or .rollback.
-
Add a transaction observer, so that it gets notified of database changes.
The transaction observer is weakly referenced: it is not retained, and stops getting notifications after it is deallocated.
Declaration
Swift
public func add(transactionObserver: TransactionObserver)
Parameters
transactionObserver
A transaction observer.
-
Remove a transaction observer.
Declaration
Swift
public func remove(transactionObserver: TransactionObserver)
-
Undocumented
Declaration
Swift
public final class Database
-
Creates a database table.
try db.create(table: "pointOfInterests") { t in t.column("id", .integer).primaryKey() t.column("title", .text) t.column("favorite", .boolean).notNull().default(false) t.column("longitude", .double).notNull() t.column("latitude", .double).notNull() }
See https://www.sqlite.org/lang_createtable.html and https://www.sqlite.org/withoutrowid.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func create(table name: String, temporary: Bool = false, ifNotExists: Bool = false, withoutRowID: Bool, body: (TableDefinition) -> Void) throws
Parameters
name
The table name.
temporary
If true, creates a temporary table.
ifNotExists
If false, no error is thrown if table already exists.
withoutRowID
If true, uses WITHOUT ROWID optimization.
body
A closure that defines table columns and constraints.
-
Creates a database table.
try db.create(table: "pointOfInterests") { t in t.column("id", .integer).primaryKey() t.column("title", .text) t.column("favorite", .boolean).notNull().default(false) t.column("longitude", .double).notNull() t.column("latitude", .double).notNull() }
See https://www.sqlite.org/lang_createtable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func create(table name: String, temporary: Bool = false, ifNotExists: Bool = false, body: (TableDefinition) -> Void) throws
Parameters
name
The table name.
temporary
If true, creates a temporary table.
ifNotExists
If false, no error is thrown if table already exists.
body
A closure that defines table columns and constraints.
-
Renames a database table.
See https://www.sqlite.org/lang_altertable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func rename(table name: String, to newName: String) throws
-
Modifies a database table.
try db.alter(table: "persons") { t in t.add(column: "url", .text) }
See https://www.sqlite.org/lang_altertable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func alter(table name: String, body: (TableAlteration) -> Void) throws
Parameters
name
The table name.
body
A closure that defines table alterations.
-
Deletes a database table.
See https://www.sqlite.org/lang_droptable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func drop(table name: String) throws
-
Undocumented
Declaration
Swift
public final class Database
-
Creates an index.
try db.create(index: "personByEmail", on: "person", columns: ["email"])
SQLite can also index expressions (https://www.sqlite.org/expridx.html) and use specific collations. To create such an index, use a raw SQL query.
try db.execute("CREATE INDEX ...")
Declaration
Swift
public func create(index name: String, on table: String, columns: [String], unique: Bool = false, ifNotExists: Bool = false) throws
Parameters
name
The index name.
table
The name of the indexed table.
columns
The indexed columns.
unique
If true, creates a unique index.
ifNotExists
If false, no error is thrown if index already exists.
-
Creates a partial index.
try db.create(index: "personByEmail", on: "person", columns: ["email"], condition: Column("email") != nil)
See https://www.sqlite.org/lang_createindex.html, and https://www.sqlite.org/partialindex.html
Declaration
Swift
public func create(index name: String, on table: String, columns: [String], unique: Bool = false, ifNotExists: Bool = false, condition: SQLExpressible) throws
Parameters
name
The index name.
table
The name of the indexed table.
columns
The indexed columns.
unique
If true, creates a unique index.
ifNotExists
If false, no error is thrown if index already exists.
condition
The condition that indexed rows must verify.
-
Deletes a database index.
See https://www.sqlite.org/lang_dropindex.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func drop(index name: String) throws
-
Creates a virtual database table.
try db.create(virtualTable: "vocabulary", using: "spellfix1")
See https://www.sqlite.org/lang_createtable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func create(virtualTable name: String, ifNotExists: Bool = false, using module: String) throws
Parameters
name
The table name.
ifNotExists
If false, no error is thrown if table already exists.
module
The name of an SQLite virtual table module.
-
Creates a virtual database table.
let module = ... try db.create(virtualTable: "pointOfInterests", using: module) { t in ... }
The type of the closure argument
t
depends on the type of the module argument: refer to this module’s documentation.Use this method to create full-text tables using the FTS3, FTS4, or FTS5 modules:
try db.create(virtualTable: "books", using: FTS4()) { t in t.column("title") t.column("author") t.column("body") }
See https://www.sqlite.org/lang_createtable.html
Throws
A DatabaseError whenever an SQLite error occurs.Declaration
Swift
public func create<Module: VirtualTableModule>(virtualTable tableName: String, ifNotExists: Bool = false, using module: Module, _ body: ((Module.TableDefinition) -> Void)? = nil) throws
Parameters
name
The table name.
ifNotExists
If false, no error is thrown if table already exists.
module
a VirtualTableModule
body
An optional closure that defines the virtual table.