// // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // import Foundation /// Abstract protocol for storing values by key. /// In production, typically backed by `SDSKeyValueStore`, which uses the GRDB /// database to persist keys and values to disk. /// In test code, typically backed by `InMemoryKeyValueStore`, which just keeps /// everything in memory to avoid setting up an entire db schema on every test case run. /// /// Instances of `KeyValueStore` should be created using a `KeyValueStoreFactory`. /// /// Methods are identical to those on `SDSKeyValueStore`. public protocol KeyValueStore { init(collection: String) // MARK: - Existence func hasValue(_ key: String, transaction: DBReadTransaction) -> Bool // MARK: - String func getString(_ key: String, transaction: DBReadTransaction) -> String? func setString(_ value: String?, key: String, transaction: DBWriteTransaction) // MARK: - Date func getDate(_ key: String, transaction: DBReadTransaction) -> Date? func setDate(_ value: Date, key: String, transaction: DBWriteTransaction) // MARK: - Bool func getBool(_ key: String, transaction: DBReadTransaction) -> Bool? func getBool(_ key: String, defaultValue: Bool, transaction: DBReadTransaction) -> Bool func setBool(_ value: Bool, key: String, transaction: DBWriteTransaction) func setBoolIfChanged( _ value: Bool, defaultValue: Bool, key: String, transaction: DBWriteTransaction ) // MARK: - UInt func getUInt(_ key: String, transaction: DBReadTransaction) -> UInt? // TODO: Handle numerics more generally. func getUInt(_ key: String, defaultValue: UInt, transaction: DBReadTransaction) -> UInt func setUInt(_ value: UInt, key: String, transaction: DBWriteTransaction) // MARK: - Data func getData(_ key: String, transaction: DBReadTransaction) -> Data? func setData(_ value: Data?, key: String, transaction: DBWriteTransaction) // MARK: - Numeric func getNSNumber(_ key: String, transaction: DBReadTransaction) -> NSNumber? // MARK: - Int func getInt(_ key: String, transaction: DBReadTransaction) -> Int? func getInt(_ key: String, defaultValue: Int, transaction: DBReadTransaction) -> Int func setInt(_ value: Int, key: String, transaction: DBWriteTransaction) // MARK: - Int32 func getInt32(_ key: String, transaction: DBReadTransaction) -> Int32? func getInt32(_ key: String, defaultValue: Int32, transaction: DBReadTransaction) -> Int32 func setInt32(_ value: Int32, key: String, transaction: DBWriteTransaction) // MARK: - UInt32 func getUInt32(_ key: String, transaction: DBReadTransaction) -> UInt32? func getUInt32(_ key: String, defaultValue: UInt32, transaction: DBReadTransaction) -> UInt32 func setUInt32(_ value: UInt32, key: String, transaction: DBWriteTransaction) // MARK: - UInt64 func getUInt64(_ key: String, transaction: DBReadTransaction) -> UInt64? func getUInt64(_ key: String, defaultValue: UInt64, transaction: DBReadTransaction) -> UInt64 func setUInt64(_ value: UInt64, key: String, transaction: DBWriteTransaction) // MARK: - Int64 func getInt64(_ key: String, transaction: DBReadTransaction) -> Int64? func getInt64(_ key: String, defaultValue: Int64, transaction: DBReadTransaction) -> Int64 func setInt64(_ value: Int64, key: String, transaction: DBWriteTransaction) // MARK: - Double func getDouble(_ key: String, transaction: DBReadTransaction) -> Double? func getDouble(_ key: String, defaultValue: Double, transaction: DBReadTransaction) -> Double func setDouble(_ value: Double, key: String, transaction: DBWriteTransaction) // MARK: - Object func getObject(forKey key: String, transaction: DBReadTransaction) -> Any? func setObject(_ anyValue: Any?, key: String, transaction: DBWriteTransaction) // MARK: - func removeValue(forKey key: String, transaction: DBWriteTransaction) func removeValues(forKeys keys: [String], transaction: DBWriteTransaction) func removeAll(transaction: DBWriteTransaction) func enumerateKeysAndObjects(transaction: DBReadTransaction, block: (String, Any, UnsafeMutablePointer) -> Void) func enumerateKeys(transaction: DBReadTransaction, block: (String, UnsafeMutablePointer) -> Void) func allValues(transaction: DBReadTransaction) -> [Any] func allDataValues(transaction: DBReadTransaction) -> [Data] func allBoolValuesMap(transaction: DBReadTransaction) -> [String: Bool] func allUIntValuesMap(transaction: DBReadTransaction) -> [String: UInt] func anyDataValue(transaction: DBReadTransaction) -> Data? func allKeys(transaction: DBReadTransaction) -> [String] func numberOfKeys(transaction: DBReadTransaction) -> UInt // MARK: - func setCodable(_ value: T, key: String, transaction: DBWriteTransaction) throws func setCodable(optional value: T, key: String, transaction: DBWriteTransaction) throws func getCodableValue(forKey key: String, transaction: DBReadTransaction) throws -> T? func allCodableValues(transaction: DBReadTransaction) throws -> [T] }