You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.8 KiB
42 lines
1.8 KiB
import Testing
|
|
import Foundation
|
|
import GRDB
|
|
@testable import Music
|
|
|
|
@MainActor
|
|
struct DBBackupFTS5Tests {
|
|
|
|
// Pins down the root cause: does DatabaseService.backup() produce a copy whose
|
|
// FTS5 `tracks_ft` table is functional? GRDB's ValueObservation introspects the
|
|
// whole schema on start, and that introspection throws "no such table: tracks_ft"
|
|
// if the FTS5 shadow tables didn't survive the copy.
|
|
@Test
|
|
func backupCopyHasFunctionalFTS5Table() throws {
|
|
// 1. Build a source DB (DatabasePool/WAL, like the running app) with 3 tracks.
|
|
let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
|
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
|
|
defer { try? FileManager.default.removeItem(at: tempDir) }
|
|
let srcPath = tempDir.appendingPathComponent("src.sqlite").path
|
|
let src = try DatabaseService(path: srcPath)
|
|
for i in 1...3 {
|
|
var t = Track.fixture(fileURL: "/s\(i).mp3", title: "Song \(i)")
|
|
try src.insert(&t)
|
|
}
|
|
|
|
// 2. Copy the DB exactly as the host serves it today.
|
|
let copyPath = tempDir.appendingPathComponent("copy.sqlite").path
|
|
try src.backup(to: copyPath)
|
|
|
|
// 3. Open the copy and run the same schema-introspection query GRDB runs when
|
|
// a ValueObservation starts. If FTS5 didn't transfer, this throws.
|
|
let copy = try DatabaseService(path: copyPath)
|
|
try copy.dbPool.read { db in
|
|
_ = try Row.fetchAll(
|
|
db,
|
|
sql: "SELECT rootpage, sql FROM sqlite_master WHERE (type = 'table' OR type = 'view')"
|
|
)
|
|
// And an actual FTS5 query must work.
|
|
_ = try Row.fetchAll(db, sql: "SELECT * FROM tracks_ft LIMIT 1")
|
|
}
|
|
}
|
|
}
|
|
|