96 lines
2.9 KiB
Swift
96 lines
2.9 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import GRDB
|
|
|
|
public enum BatchingPreference {
|
|
case batched(UInt = Batching.kDefaultBatchSize)
|
|
case unbatched
|
|
}
|
|
|
|
extension SDSCodableModelDatabaseInterfaceImpl {
|
|
/// Traverse all records, in no particular order.
|
|
func enumerateModels<Model: SDSCodableModel>(
|
|
modelType: Model.Type,
|
|
transaction: DBReadTransaction,
|
|
batchingPreference: BatchingPreference,
|
|
block: (Model, inout Bool) -> Void,
|
|
) {
|
|
let batchSize = batchSize(batchingPreference: batchingPreference)
|
|
enumerateModels(
|
|
modelType: modelType,
|
|
transaction: transaction,
|
|
sql: nil,
|
|
arguments: nil,
|
|
batchSize: batchSize,
|
|
block: block,
|
|
)
|
|
}
|
|
|
|
/// Traverse all records, in no particular order.
|
|
func enumerateModels<Model: SDSCodableModel>(
|
|
modelType: Model.Type,
|
|
transaction: DBReadTransaction,
|
|
sql: String,
|
|
arguments: StatementArguments,
|
|
batchingPreference: BatchingPreference,
|
|
block: (Model, inout Bool) -> Void,
|
|
) {
|
|
let batchSize = batchSize(batchingPreference: batchingPreference)
|
|
enumerateModels(
|
|
modelType: modelType,
|
|
transaction: transaction,
|
|
sql: sql,
|
|
arguments: arguments,
|
|
batchSize: batchSize,
|
|
block: block,
|
|
)
|
|
}
|
|
|
|
/// The batch size for enumeration.
|
|
private func batchSize(batchingPreference: BatchingPreference) -> UInt {
|
|
switch batchingPreference {
|
|
case .batched(let size):
|
|
return size
|
|
case .unbatched:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
/// Traverse all records, in no particular order.
|
|
/// - Parameter batchSize
|
|
/// If nonzero, enumeration is performed in autoreleased batches.
|
|
private func enumerateModels<Model: SDSCodableModel>(
|
|
modelType: Model.Type,
|
|
transaction: DBReadTransaction,
|
|
sql: String? = nil,
|
|
arguments: StatementArguments? = nil,
|
|
batchSize: UInt,
|
|
block: (Model, inout Bool) -> Void,
|
|
) {
|
|
failIfThrows {
|
|
var recordCursor: RecordCursor<Model>
|
|
if let sql, let arguments {
|
|
recordCursor = try Model.fetchCursor(
|
|
transaction.database,
|
|
sql: sql,
|
|
arguments: arguments,
|
|
)
|
|
} else {
|
|
recordCursor = try modelType.fetchCursor(transaction.database)
|
|
}
|
|
|
|
try Batching.loop(batchSize: batchSize) { stop in
|
|
guard let value = try recordCursor.next() else {
|
|
stop = true
|
|
return
|
|
}
|
|
value.anyDidEnumerateOne(transaction: transaction)
|
|
block(value, &stop)
|
|
}
|
|
}
|
|
}
|
|
}
|