feat(db): add custom_album_covers table and methods

Schema for user-uploaded custom album covers (keyed by album_id).
Database methods: set, get, remove, get_all.

cc
This commit is contained in:
vicrodh committed 2026-02-24 09:58:27 -06:00
1 parent 03507c0a49
commit 5dc83145bb
1 file changed
+96
+96
View File
@@ -192,6 +192,13 @@ impl LibraryDatabase {
CREATE INDEX IF NOT EXISTS idx_artist_images_fetched ON artist_images(fetched_at);
-- Custom album covers (user-uploaded covers for Qobuz albums)
CREATE TABLE IF NOT EXISTS custom_album_covers (
album_id TEXT PRIMARY KEY,
custom_image_path TEXT NOT NULL,
created_at INTEGER NOT NULL
);
-- Downloaded purchases registry (permanent — user owns these files)
CREATE TABLE IF NOT EXISTS downloaded_purchases (
track_id INTEGER PRIMARY KEY,
@@ -3551,6 +3558,95 @@ impl LibraryDatabase {
Ok(())
}
// === Custom Album Covers ===
/// Set a custom album cover
pub fn set_custom_album_cover(
&self,
album_id: &str,
custom_image_path: &str,
) -> Result<(), LibraryError> {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
self.conn
.execute(
"INSERT OR REPLACE INTO custom_album_covers (album_id, custom_image_path, created_at)
VALUES (?1, ?2, ?3)",
params![album_id, custom_image_path, now],
)
.map_err(|e| {
LibraryError::Database(format!("Failed to set custom album cover: {}", e))
})?;
Ok(())
}
/// Get custom album cover path for a single album
pub fn get_custom_album_cover(
&self,
album_id: &str,
) -> Result<Option<String>, LibraryError> {
let mut stmt = self
.conn
.prepare(
"SELECT custom_image_path FROM custom_album_covers WHERE album_id = ?1",
)
.map_err(|e| LibraryError::Database(format!("Failed to prepare query: {}", e)))?;
let result = stmt
.query_row(params![album_id], |row| row.get::<_, String>(0))
.optional()
.map_err(|e| {
LibraryError::Database(format!("Failed to query custom album cover: {}", e))
})?;
Ok(result)
}
/// Remove a custom album cover
pub fn remove_custom_album_cover(
&self,
album_id: &str,
) -> Result<(), LibraryError> {
self.conn
.execute(
"DELETE FROM custom_album_covers WHERE album_id = ?1",
params![album_id],
)
.map_err(|e| {
LibraryError::Database(format!("Failed to remove custom album cover: {}", e))
})?;
Ok(())
}
/// Get all custom album covers (album_id -> file_path)
pub fn get_all_custom_album_covers(
&self,
) -> Result<std::collections::HashMap<String, String>, LibraryError> {
let mut stmt = self
.conn
.prepare("SELECT album_id, custom_image_path FROM custom_album_covers")
.map_err(|e| LibraryError::Database(format!("Failed to prepare query: {}", e)))?;
let rows = stmt
.query_map([], |row| {
Ok((row.get::<_, String>(0)?, row.get::<_, String>(1)?))
})
.map_err(|e| {
LibraryError::Database(format!("Failed to query custom album covers: {}", e))
})?;
let mut map = std::collections::HashMap::new();
for row in rows {
if let Ok((album_id, path)) = row {
map.insert(album_id, path);
}
}
Ok(map)
}
// === Offline Mode: Local Content Detection ===
/// Check if a track exists locally by Qobuz track ID