DatabaseWriter

public protocol DatabaseWriter : DatabaseReader

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.

  • Synchronously executes a block that takes a database connection, and returns its result.

    Eventual concurrent database updates are postponed until the block has executed.

    This method is not reentrant.

    Declaration

    Swift

    func write<T>(_ block: (Database) throws -> T) rethrows -> T
  • Synchronously executes a block that takes a database connection, and returns its result.

    Eventual concurrent database updates are postponed until the block has executed.

    This method is reentrant. It should be avoided because it fosters dangerous concurrency practices.

    Declaration

    Swift

    func unsafeReentrantWrite<T>(_ block: (Database) throws -> T) rethrows -> T
  • Synchronously or asynchronously executes a read-only block that takes a database connection.

    This method must be called from a writing dispatch queue, outside of any transaction. You’ll get a fatal error otherwise.

    The block argument is guaranteed to see the database in the last committed state at the moment this method is called. Eventual concurrent database updates are not visible inside the block.

    For example:

    try writer.write { db in
        try db.execute("DELETE FROM players")
        try writer.readFromCurrentState { db in
            // Guaranteed to be zero
            try Int.fetchOne(db, "SELECT COUNT(*) FROM players")!
        }
        try db.execute("INSERT INTO players ...")
    }
    

    Declaration

    Swift

    func readFromCurrentState(_ block: @escaping (Database) -> Void) throws