Phase 4 seam: in-memory DatabaseService + DB injection for ContextSelectionService
DatabaseService gains a testable init(dbQueue:) plus a makeInMemory() convenience and schema-introspection helpers (tableExists/columnNames), so migration tests don't need the test target to import GRDB directly. ContextSelectionService now takes an injected DatabaseService (defaults to .shared) and its DB-coupled methods (smartSelection, getSummariesForExcludedRange, isMessageStarred) are bumped to internal. No logic changes to existing call sites.
This commit is contained in:
@@ -154,7 +154,14 @@ final class DatabaseService: Sendable {
|
||||
(try? isoStyle.parse(string)) ?? (try? Date(string, strategy: .iso8601))
|
||||
}
|
||||
|
||||
nonisolated private init() {
|
||||
/// Test seam: build a DatabaseService around a caller-provided queue (e.g. an in-memory `DatabaseQueue()`).
|
||||
/// Each test should create its own fresh instance — never mutate `.shared` from a test.
|
||||
nonisolated init(dbQueue: DatabaseQueue) {
|
||||
self.dbQueue = dbQueue
|
||||
try! migrator.migrate(dbQueue)
|
||||
}
|
||||
|
||||
nonisolated private convenience init() {
|
||||
let fileManager = FileManager.default
|
||||
let appSupport = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
||||
let dbDirectory = appSupport.appendingPathComponent("oAI", isDirectory: true)
|
||||
@@ -163,12 +170,25 @@ final class DatabaseService: Sendable {
|
||||
|
||||
let dbPath = dbDirectory.appendingPathComponent("oai_conversations.db").path
|
||||
Log.db.info("Opening database at \(dbPath)")
|
||||
dbQueue = try! DatabaseQueue(path: dbPath)
|
||||
|
||||
try! migrator.migrate(dbQueue)
|
||||
self.init(dbQueue: try! DatabaseQueue(path: dbPath))
|
||||
}
|
||||
|
||||
private nonisolated var migrator: DatabaseMigrator {
|
||||
/// Test seam: a throwaway in-memory instance with all migrations applied. Avoids requiring
|
||||
/// `import GRDB` from the test target just to construct a `DatabaseQueue()`.
|
||||
nonisolated static func makeInMemory() -> DatabaseService {
|
||||
DatabaseService(dbQueue: try! DatabaseQueue())
|
||||
}
|
||||
|
||||
/// Test seam: schema introspection, so migration tests don't need `import GRDB` either.
|
||||
nonisolated func tableExists(_ name: String) -> Bool {
|
||||
(try? dbQueue.read { db in try db.tableExists(name) }) ?? false
|
||||
}
|
||||
|
||||
nonisolated func columnNames(in table: String) -> [String] {
|
||||
(try? dbQueue.read { db in try db.columns(in: table).map(\.name) }) ?? []
|
||||
}
|
||||
|
||||
nonisolated var migrator: DatabaseMigrator {
|
||||
var migrator = DatabaseMigrator()
|
||||
|
||||
migrator.registerMigration("v1") { db in
|
||||
|
||||
Reference in New Issue
Block a user