53 lines
1.7 KiB
Swift
53 lines
1.7 KiB
Swift
import Foundation
|
|
import TermindDomain
|
|
|
|
import struct TermindDomain.Host
|
|
|
|
@MainActor
|
|
public protocol CommandHistoryRepository: AnyObject {
|
|
func entries(for hostID: Host.ID) throws -> [CommandHistoryEntry]
|
|
func trim(to limit: Int) throws
|
|
func insert(_ entry: CommandHistoryEntry, limit: Int) throws
|
|
func update(_ entry: CommandHistoryEntry) throws
|
|
func delete(_ id: CommandHistoryEntry.ID) throws
|
|
func clear(for hostID: Host.ID) throws
|
|
}
|
|
|
|
@MainActor
|
|
public final class InMemoryCommandHistoryRepository: CommandHistoryRepository {
|
|
private var values: [CommandHistoryEntry]
|
|
|
|
public init(entries: [CommandHistoryEntry] = []) { values = entries }
|
|
|
|
public func entries(for hostID: Host.ID) throws -> [CommandHistoryEntry] {
|
|
values.filter { $0.hostID == hostID }.sorted { $0.executedAt > $1.executedAt }
|
|
}
|
|
|
|
public func trim(to limit: Int) throws {
|
|
let entriesByHost = Dictionary(grouping: values, by: \.hostID)
|
|
let retained = Set(
|
|
entriesByHost.values.flatMap { entries in
|
|
entries.sorted { $0.executedAt > $1.executedAt }.prefix(limit).map(\.id)
|
|
})
|
|
values.removeAll { !retained.contains($0.id) }
|
|
}
|
|
|
|
public func insert(_ entry: CommandHistoryEntry, limit: Int) throws {
|
|
values.append(entry)
|
|
try trim(to: limit)
|
|
}
|
|
|
|
public func update(_ entry: CommandHistoryEntry) throws {
|
|
guard let index = values.firstIndex(where: { $0.id == entry.id }) else { return }
|
|
values[index] = entry
|
|
}
|
|
|
|
public func delete(_ id: CommandHistoryEntry.ID) throws {
|
|
values.removeAll { $0.id == id }
|
|
}
|
|
|
|
public func clear(for hostID: Host.ID) throws {
|
|
values.removeAll { $0.hostID == hostID }
|
|
}
|
|
}
|