Signal-iOS/SignalServiceKit/Storage/Database/SDSDatabaseStorage/V2/DBTransaction.swift

63 lines
2.5 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public import GRDB
/// Wrapper around `SDSAnyReadTransaction` that allows the generation
/// of a "fake" instance in tests without touching existing code.
///
/// There should only ever be three concrete implementations of this protocol:
/// * ``SDSDB.ReadTx``
/// * ``InMemoryDB.ReadTransaction``
/// * ``MockTransaction``
///
/// Classes wishing to access the database directly (things like FooStore) should
/// access the database connection directly by using ``databaseConnection``.
/// Classes that do not directly access the database should not access the database connection.
///
/// Shims can bridge to `SDSAnyReadTransaction` by using ``SDSDB.shimOnlyBridge``;
/// this is made intentionally cumbersome as it should **never** be used in
/// any concrete class and **only** in shim classes that bridge to old-style code.
public protocol DBReadTransaction: AnyObject {}
/// Wrapper around `SDSAnyWriteTransaction` that allows the generation
/// of a "fake" instance in tests without touching existing code.
///
/// There should only ever be two concrete implementations of this
/// protocol: `SDSDB.WriteTx` and `MockWriteTransaction`
///
/// Classes wishing to access the database directly (things like FooStore) should
/// access the database connection directly by using ``databaseConnection``.
/// Classes that do not directly access the database should not access the database connection.
///
/// Shims can bridge to `SDSAnyWriteTransaction` by using ``SDSDB.shimOnlyBridge``;
/// this is made intentionally cumbersome as it should **never** be used in
/// any concrete class and **only** in shim classes that bridge to old-style code.
public protocol DBWriteTransaction: DBReadTransaction {
func addFinalization(forKey key: String, block: @escaping () -> Void)
func addSyncCompletion(_ block: @escaping () -> Void)
func addAsyncCompletion(on scheduler: Scheduler, _ block: @escaping () -> Void)
}
public func databaseConnection(_ tx: DBReadTransaction) -> GRDB.Database {
#if TESTABLE_BUILD
if let tx = tx as? InMemoryDB.ReadTransaction {
return tx.db
}
#endif
return SDSDB.shimOnlyBridge(tx).unwrapGrdbRead.database
}
public func databaseConnection(_ tx: DBWriteTransaction) -> GRDB.Database {
#if TESTABLE_BUILD
if let tx = tx as? InMemoryDB.WriteTransaction {
return tx.db
}
#endif
return SDSDB.shimOnlyBridge(tx).unwrapGrdbWrite.database
}