Record
Record is a class that wraps a table row, or the result of any query. It is designed to be subclassed.
-
Creates a Record.
-
Creates a Record from a row.
-
The name of a database table.
This table name is required by the insert, update, save, delete, and exists methods.
class Player : Record { override class var databaseTableName: String { return "player" } }
The implementation of the base class Record raises a fatal error.
-
The policy that handles SQLite conflicts when records are inserted or updated.
The default implementation uses the ABORT policy for both insertions and updates, and has GRDB generate regular INSERT and UPDATE queries.
-
The default request selection.
Unless this method is overridden, requests select all columns:
// SELECT * FROM player try Player.fetchAll(db)
You can override this property and provide an explicit list of columns:
class RestrictedPlayer : Record { override static var databaseSelection: [any SQLSelectable] { return [Column("id"), Column("name")] } } // SELECT id, name FROM player try RestrictedPlayer.fetchAll(db)
You can also add extra columns such as the
rowid
column:class ExtendedPlayer : Player { override static var databaseSelection: [any SQLSelectable] { return [AllColumns(), Column.rowID] } } // SELECT *, rowid FROM player try ExtendedPlayer.fetchAll(db)
-
Defines the values persisted in the database.
Store in the container parameter all values that should be stored in the columns of the database table (see Record.databaseTableName()).
Primary key columns, if any, must be included.
class Player : Record { var id: Int64? var name: String? override func encode(to container: inout PersistenceContainer) throws { container["id"] = id container["name"] = name } }
The implementation of the base class Record does not store any value in the container.
-
A boolean that indicates whether the record has changes that have not been saved.
This flag is purely informative, and does not prevent insert(), update(), and save() from performing their database queries.
A record is edited if has been changed since last database synchronization (fetch, update, insert). Comparison is performed between values (values stored in the
encode(to:)
method, and values loaded from the database). Property setters do not trigger this flag.You can rely on the Record base class to compute this flag for you, or you may set it to true or false when you know better. Setting it to false does not prevent it from turning true on subsequent modifications of the record.
-
A dictionary of changes that have not been saved.
Its keys are column names, and values the old values that have been changed since last fetching or saving of the record.
Unless the record has actually been fetched or saved, the old values are nil.
See
hasDatabaseChanges
for more information.Throws
An error is thrown if the record can’t be encoded to its database representation.
-
Called before the record is inserted.
If you override this method, you must call
super
at some point in your implementation. -
Called around the record insertion.
If you override this method, you must call
super
at some point in your implementation (this calls theinsert
parameter).For example:
class Player: Record { func aroundInsert(_ db: Database, insert: () throws -> InsertionSuccess) throws { print("Player will insert") try super.aroundInsert(db, insert: insert) print("Player did insert") } }
-
Called upon successful insertion.
You can override this method in order to grab the auto-incremented id:
class Player: Record { var id: Int64? var name: String override func didInsert(_ inserted: InsertionSuccess) { super.didInsert(inserted) id = inserted.rowID } }
If you override this method, you must call
super
at some point in your implementation. -
Called before the record is updated.
If you override this method, you must call
super
at some point in your implementation. -
Called around the record update.
If you override this method, you must call
super
at some point in your implementation (this calls theupdate
parameter).For example:
class Player: Record { override func aroundUpdate(_ db: Database, columns: Set<String>, update: () throws -> PersistenceSuccess) throws { print("Player will update") try super.aroundUpdate(db, columns: columns, update: update) print("Player did update") } }
-
Called upon successful update.
If you override this method, you must call
super
at some point in your implementation. -
Called before the record is updated or inserted.
If you override this method, you must call
super
at some point in your implementation. -
Called around the record update or insertion.
If you override this method, you must call
super
at some point in your implementation (this calls theupdate
parameter).For example:
class Player: Record { override func aroundSave(_ db: Database, save: () throws -> PersistenceSuccess) throws { print("Player will save") try super.aroundSave(db, save: save) print("Player did save") } }
-
Called upon successful update or insertion.
If you override this method, you must call
super
at some point in your implementation. -
Called before the record is deleted.
If you override this method, you must call
super
at some point in your implementation. -
Called around the destruction of the record.
If you override this method, you must call
super
at some point in your implementation (this calls thedelete
parameter).For example:
class Player: Record { override func aroundDelete(_ db: Database, delete: () throws -> Bool) throws { print("Player will delete") try super.aroundDelete(db, delete: delete) print("Player did delete") } }
-
Called upon successful deletion.
If you override this method, you must call
super
at some point in your implementation.
-
If the record has been changed, executes an UPDATE statement so that those changes and only those changes are saved in the database.
On success, this method sets the hasDatabaseChanges flag to false.
This method is guaranteed to have saved the eventual changes in the database if it returns without error.
Throws
A DatabaseError is thrown whenever an SQLite error occurs. PersistenceError.recordNotFound is thrown if the primary key does not match any row in the database and record could not be updated.