Bug gixes, features added, GUI updates and more

This commit is contained in:
2026-02-12 14:29:35 +01:00
parent 52447b5e17
commit 7265d22438
21 changed files with 2187 additions and 123 deletions

View File

@@ -40,6 +40,14 @@ struct SettingRecord: Codable, FetchableRecord, PersistableRecord, Sendable {
var value: String
}
struct HistoryRecord: Codable, FetchableRecord, PersistableRecord, Sendable {
static let databaseTableName = "command_history"
var id: String
var input: String
var timestamp: String
}
// MARK: - DatabaseService
final class DatabaseService: Sendable {
@@ -48,6 +56,9 @@ final class DatabaseService: Sendable {
private let dbQueue: DatabaseQueue
private let isoFormatter: ISO8601DateFormatter
// Command history limit - keep most recent 5000 entries
private static let maxHistoryEntries = 5000
nonisolated private init() {
isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
@@ -102,6 +113,20 @@ final class DatabaseService: Sendable {
}
}
migrator.registerMigration("v3") { db in
try db.create(table: "command_history") { t in
t.primaryKey("id", .text)
t.column("input", .text).notNull()
t.column("timestamp", .text).notNull()
}
try db.create(
index: "command_history_on_timestamp",
on: "command_history",
columns: ["timestamp"]
)
}
return migrator
}
@@ -315,4 +340,68 @@ final class DatabaseService: Sendable {
return true
}
}
// MARK: - Command History Operations
nonisolated func saveCommandHistory(input: String) {
let now = Date()
let record = HistoryRecord(
id: UUID().uuidString,
input: input,
timestamp: isoFormatter.string(from: now)
)
try? dbQueue.write { db in
try record.insert(db)
// Clean up old entries if we exceed the limit
let count = try HistoryRecord.fetchCount(db)
if count > Self.maxHistoryEntries {
// Delete oldest entries to get back to limit
let excess = count - Self.maxHistoryEntries
try db.execute(
sql: """
DELETE FROM command_history
WHERE id IN (
SELECT id FROM command_history
ORDER BY timestamp ASC
LIMIT ?
)
""",
arguments: [excess]
)
}
}
}
nonisolated func loadCommandHistory() throws -> [(input: String, timestamp: Date)] {
try dbQueue.read { db in
let records = try HistoryRecord
.order(Column("timestamp").desc)
.fetchAll(db)
return records.compactMap { record in
guard let date = isoFormatter.date(from: record.timestamp) else {
return nil
}
return (input: record.input, timestamp: date)
}
}
}
nonisolated func searchCommandHistory(query: String) throws -> [(input: String, timestamp: Date)] {
try dbQueue.read { db in
let records = try HistoryRecord
.filter(Column("input").like("%\(query)%"))
.order(Column("timestamp").desc)
.fetchAll(db)
return records.compactMap { record in
guard let date = isoFormatter.date(from: record.timestamp) else {
return nil
}
return (input: record.input, timestamp: date)
}
}
}
}