feat(remote): add DatabaseService.fetchTracksByIds for efficient ID-based lookups

feat/music-streaming
Laurent 1 month ago
parent c754858f21
commit c3b97eb201
  1. 14
      Music/Services/DatabaseService.swift
  2. 20
      MusicTests/DatabaseServiceTests.swift

@ -201,6 +201,20 @@ nonisolated final class DatabaseService: Sendable {
} }
} }
func fetchTracksByIds(_ ids: [Int64]) throws -> [Track] {
guard !ids.isEmpty else { return [] }
let tracks = try dbPool.read { db in
let placeholders = databaseQuestionMarks(count: ids.count)
return try Track.fetchAll(
db,
sql: "SELECT * FROM tracks WHERE id IN (\(placeholders))",
arguments: StatementArguments(ids)
)
}
let trackMap = Dictionary(uniqueKeysWithValues: tracks.compactMap { t in t.id.map { ($0, t) } })
return ids.compactMap { trackMap[$0] }
}
func fetchRecentlyAdded(limit: Int) throws -> [Track] { func fetchRecentlyAdded(limit: Int) throws -> [Track] {
try dbPool.read { db in try dbPool.read { db in
try Track.fetchAll( try Track.fetchAll(

@ -264,6 +264,26 @@ struct DatabaseServiceTests {
#expect(total == 0) #expect(total == 0)
} }
// Inserts 5 tracks, fetches 3 by ID, verifies only those 3 are returned
// in the order of the requested IDs.
@Test func fetchTracksByIds() throws {
let db = try DatabaseService(inMemory: true)
var tracks = (0..<5).map { i in
Track.fixture(fileURL: "/track\(i).mp3", title: "Track \(i)")
}
for i in tracks.indices {
try db.insert(&tracks[i])
}
let ids: [Int64] = [tracks[2].id!, tracks[0].id!, tracks[4].id!]
let result = try db.fetchTracksByIds(ids)
#expect(result.count == 3)
#expect(result[0].id == tracks[2].id)
#expect(result[1].id == tracks[0].id)
#expect(result[2].id == tracks[4].id)
}
// Inserts tracks in different months and verifies fetchMonthlyAdditions returns // Inserts tracks in different months and verifies fetchMonthlyAdditions returns
// the correct per-month counts covering the requested range including empty months. // the correct per-month counts covering the requested range including empty months.
// Uses a UTC calendar to match the implementation, which uses UTC month boundaries // Uses a UTC calendar to match the implementation, which uses UTC month boundaries

Loading…
Cancel
Save