MutablePersistableRecord
A type that can be persisted in the database, and mutates on insertion.
protocol MutablePersistableRecord : EncodableRecord, TableRecord
Browse conforming typesOverview
A MutablePersistableRecord
instance mutates on insertion. This protocol is suited for record types that are a struct
, and target a database table where ids are generated on insertion. Such records implement the didInsert(_:)
callback in order to grab this id. For example:
// CREATE TABLE player (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// name TEXT NOT NULL,
// score INTEGER NOT NULL
// )
struct Player: Encodable {
var id: Int64?
var name: String
var score: Int
}
extension Player: MutablePersistableRecord {
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
try dbQueue.write { db in
var player = Player(id: nil, name:: "Arthur", score: 1000)
try player.insert(db)
print(player.id) // Some id that is not nil
}
Other record types (classes, and generally records that do not mutate on insertion) should prefer the PersistableRecord
protocol instead.
Conforming to the MutablePersistableRecord Protocol
To conform to MutablePersistableRecord
, provide an implementation for the encode(to:)
method. This implementation is ready-made for Encodable
types.
You configure the database table where records are persisted with the TableRecord
inherited protocol.
Testing if a Record Exists in the Database
func exists(Database
) throws -> Bool Returns whether the primary key of the record matches a row in the database.
Inserting a Record
func insert(Database, onConflict: Database.ConflictResolution?
) throws Executes an
INSERT
statement.func inserted(Database, onConflict: Database.ConflictResolution?
) throws -> Self Executes an
INSERT
statement, and returns the inserted record.func upsert(Database
) throws Executes an
INSERT ON CONFLICT DO UPDATE
statement.
Inserting a Record and Fetching the Inserted Row
func insertAndFetch(Database, onConflict: Database.ConflictResolution?
) throws -> Self Executes an
INSERT RETURNING
statement, and returns a new record built from the inserted row.func insertAndFetch<T>(Database, onConflict: Database.ConflictResolution?, as: T.Type
) throws -> T Executes an
INSERT RETURNING
statement, and returns a new record built from the inserted row.func insertAndFetch<T>(Database, onConflict: Database.ConflictResolution?, selection: [any SQLSelectable], fetch: (Statement) throws -> T
) throws -> T Executes an
INSERT RETURNING
statement, and returns the selected columns from the inserted row.func upsertAndFetch(Database, onConflict: [String], doUpdate: ((_ excluded: TableAlias) -> [ColumnAssignment])?
) throws -> Self Executes an
INSERT ON CONFLICT DO UPDATE RETURNING
statement, and returns the upserted record.func upsertAndFetch<T>(Database, as: T.Type, onConflict: [String], doUpdate: ((_ excluded: TableAlias) -> [ColumnAssignment])?
) throws -> T Executes an
INSERT ON CONFLICT DO UPDATE RETURNING
statement, and returns the upserted record.
Updating a Record
See inherited TableRecord
methods for batch updates.
func update(Database, onConflict: Database.ConflictResolution?
) throws Executes an
UPDATE
statement on all columns.func update(Database, onConflict: Database.ConflictResolution?, columns: some Collection<String>
) throws Executes an
UPDATE
statement on the provided columns.func update(Database, onConflict: Database.ConflictResolution?, columns: some Collection<some ColumnExpression>
) throws Executes an
UPDATE
statement on the provided columns.func updateChanges<Record>(Database, onConflict: Database.ConflictResolution?, from: Record
) throws -> Bool If the record has any difference from the other record, executes an
UPDATE
statement so that those differences and only those differences are updated in the database.func updateChanges(Database, onConflict: Database.ConflictResolution?, modify: (inout Self) throws -> Void
) throws -> Bool Modifies the record according to the provided
modify
closure, and executes anUPDATE
statement that updates the modified columns, if and only if the record was modified.
Updating a Record and Fetching the Updated Row
func updateAndFetch(Database, onConflict: Database.ConflictResolution?
) throws -> Self Executes an
UPDATE RETURNING
statement on all columns, and returns a new record built from the updated row.func updateAndFetch<T>(Database, onConflict: Database.ConflictResolution?, as: T.Type
) throws -> T Executes an
UPDATE RETURNING
statement on all columns, and returns a new record built from the updated row.func updateAndFetch<T>(Database, onConflict: Database.ConflictResolution?, columns: some Collection<String>, selection: [any SQLSelectable], fetch: (Statement) throws -> T
) throws -> T Executes an
UPDATE RETURNING
statement on the provided columns, and returns the selected columns from the updated row.func updateAndFetch<T>(Database, onConflict: Database.ConflictResolution?, columns: some Collection<some ColumnExpression>, selection: [any SQLSelectable], fetch: (Statement) throws -> T
) throws -> T Executes an
UPDATE RETURNING
statement on the provided columns, and returns the selected columns from the updated row.func updateAndFetch<T>(Database, onConflict: Database.ConflictResolution?, selection: [any SQLSelectable], fetch: (Statement) throws -> T
) throws -> T Executes an
UPDATE RETURNING
statement on all columns, and returns the selected columns from the updated row.func updateChangesAndFetch(Database, onConflict: Database.ConflictResolution?, modify: (inout Self) throws -> Void
) throws -> Self? Modifies the record according to the provided
modify
closure, and executes anUPDATE RETURNING
statement that updates the modified columns, if and only if the record was modified. The method returns a new record built from the updated row.func updateChangesAndFetch<T>(Database, onConflict: Database.ConflictResolution?, as: T.Type, modify: (inout Self) throws -> Void
) throws -> T? Modifies the record according to the provided
modify
closure, and executes anUPDATE RETURNING
statement that updates the modified columns, if and only if the record was modified. The method returns a new record built from the updated row.func updateChangesAndFetch<T>(Database, onConflict: Database.ConflictResolution?, selection: [any SQLSelectable], fetch: (Statement) throws -> T, modify: (inout Self) throws -> Void
) throws -> T? Modifies the record according to the provided
modify
closure, and executes anUPDATE RETURNING
statement that updates the modified columns, if and only if the record was modified. The method returns a new record built from the updated row.
Saving a Record
func save(Database, onConflict: Database.ConflictResolution?
) throws Executes an
INSERT
orUPDATE
statement.func saved(Database, onConflict: Database.ConflictResolution?
) throws -> Self Executes an
INSERT
orUPDATE
statement, and returns the saved record.
Saving a Record and Fetching the Saved Row
func saveAndFetch(Database, onConflict: Database.ConflictResolution?
) throws -> Self Executes an
INSERT RETURNING
orUPDATE RETURNING
statement, and returns a new record built from the saved row.func saveAndFetch<T>(Database, onConflict: Database.ConflictResolution?, as: T.Type
) throws -> T Executes an
INSERT RETURNING
orUPDATE RETURNING
statement, and returns a new record built from the saved row.func saveAndFetch<T>(Database, onConflict: Database.ConflictResolution?, selection: [any SQLSelectable], fetch: (Statement) throws -> T
) throws -> T Executes an
INSERT RETURNING
orUPDATE RETURNING
statement, and returns the selected columns from the saved row.
Deleting a Record
See inherited TableRecord
methods for batch deletes.
func delete(Database
) throws -> Bool Executes a DELETE statement.
Persistence Callbacks
func willDelete(Database
) throws Persistence callback called before the record is deleted.
func willInsert(Database
) throws Persistence callback called before the record is inserted.
func willSave(Database
) throws Persistence callback called before the record is updated or inserted.
func willUpdate(Database, columns: Set<String>
) throws Persistence callback called before the record is updated.
func didDelete(deleted: Bool
) Persistence callback called upon successful deletion.
func didInsert(InsertionSuccess
) Persistence callback called upon successful insertion.
func didSave(PersistenceSuccess
) Persistence callback called upon successful update or insertion.
func didUpdate(PersistenceSuccess
) Persistence callback called upon successful update.
func aroundDelete(Database, delete: () throws -> Bool
) throws Persistence callback called around the destruction of the record.
func aroundInsert(Database, insert: () throws -> InsertionSuccess
) throws Persistence callback called around the record insertion.
func aroundSave(Database, save: () throws -> PersistenceSuccess
) throws Persistence callback called around the record update or insertion.
func aroundUpdate(Database, columns: Set<String>, update: () throws -> PersistenceSuccess
) throws Persistence callback called around the record update.
struct InsertionSuccess
The result of a successful record insertion.
struct PersistenceSuccess
The result of a successful record persistence (insert or update).
Configuring Persistence
static var persistenceConflictPolicy: PersistenceConflictPolicy
The policy that handles SQLite conflicts when records are inserted or updated.
struct PersistenceConflictPolicy
The
MutablePersistableRecord
protocol uses this type in order to handle SQLite conflicts when records are inserted or updated.