feat: optimize lazy PK resolution and fix OpenHome IdList delimiter

- In track_metadata.rs: cache real_pk at construction time to avoid repeated DB queries per metadata field access.
- In openhome_client.rs: change IdList delimiter from comma to space per OpenHome spec.
This commit is contained in:
2026-03-25 12:59:27 +01:00
parent 8005968ec5
commit bded788431
2 changed files with 20 additions and 15 deletions

View File

@@ -20,6 +20,9 @@ fn map_db_err(err: rusqlite::Error) -> MetadataError {
pub struct AudioCacheTrackMetadata {
cache: Arc<crate::Cache>,
pk: String,
/// Real pk si le lazy pk a été téléchargé, None sinon.
/// Résolu une seule fois à la construction pour éviter N appels DB par champ.
real_pk: Option<String>,
}
impl AudioCacheTrackMetadata {
@@ -28,25 +31,26 @@ impl AudioCacheTrackMetadata {
/// Le type implémente ensuite toutes les méthodes du trait `pmometadata::TrackMetadata`
/// en stockant les données dans la base SQLite de `pmocache`.
pub fn new(cache: Arc<crate::Cache>, pk: impl Into<String>) -> Self {
Self {
cache,
pk: pk.into(),
}
let pk_str: String = pk.into();
// Résolution lazy→real une seule fois à la construction (une seule query DB).
let real_pk = if pmocache::is_lazy_pk(&pk_str) {
cache.db.get_pk_by_lazy_pk(&pk_str).ok().flatten()
} else {
None
};
Self { cache, pk: pk_str, real_pk }
}
fn read_raw(&self, key: &str) -> Result<Option<Value>, MetadataError> {
// Si le pk est un lazy pk déjà téléchargé (pk != lazy_pk dans l'asset),
// lire d'abord sous le real_pk (métadonnées écrites par FlacCacheSink),
// puis fallback sous le lazy_pk (cover_pk, qobuz_track_id semés à l'enregistrement).
if pmocache::is_lazy_pk(&self.pk) {
if let Ok(Some(real_pk)) = self.cache.db.get_pk_by_lazy_pk(&self.pk) {
if let Ok(Some(v)) = self.cache.db.get_a_metadata(&real_pk, key) {
// Si le lazy pk a été téléchargé, lire d'abord sous le real_pk
// (métadonnées écrites par FlacCacheSink), puis fallback sous le lazy_pk
// pour les clés semées avant téléchargement (cover_pk, etc.).
if let Some(real_pk) = &self.real_pk {
if let Ok(Some(v)) = self.cache.db.get_a_metadata(real_pk, key) {
return Ok(Some(v));
}
// Fallback vers lazy_pk pour les clés semées avant téléchargement (cover_pk, etc.)
return self.cache.db.get_a_metadata(&self.pk, key).map_err(map_db_err);
}
}
self.cache
.db
.get_a_metadata(&self.pk, key)

View File

@@ -185,11 +185,12 @@ impl OhPlaylistClient {
return Ok(Vec::new());
}
// OpenHome spec: IdList is space-delimited (not comma-delimited)
let id_list_csv = id_list
.iter()
.map(|id| id.to_string())
.collect::<Vec<_>>()
.join(",");
.join(" ");
let args = [("IdList", id_list_csv.as_str())];
let call_result =