des debug

This commit is contained in:
2025-11-26 10:35:45 +01:00
parent aeddcc9c64
commit d1ca476c4f
3 changed files with 110 additions and 2 deletions

View File

@@ -377,8 +377,28 @@ impl<C: CacheConfig> Cache<C> {
/// Deux URLs différentes pointant vers le même contenu auront le même pk,
/// permettant une déduplication automatique.
pub async fn add_from_url(&self, url: &str, collection: Option<&str>) -> Result<String> {
// 1. Télécharger les 512 premiers octets pour calculer le pk
let header = crate::download::peek_header(url, 512)
// 0. Vérifier d'abord si cette URL est déjà en cache (optimisation réseau)
if let Ok(Some(existing_pk)) = self.db.get_pk_by_origin_url(url) {
// Vérifier que le fichier est toujours complet et valide
if self.check_cached_and_complete(&existing_pk).await? {
tracing::debug!(
"URL {} already in cache with pk {}, skipping download",
url,
existing_pk
);
self.db.update_hit(&existing_pk)?;
return Ok(existing_pk);
} else {
tracing::debug!(
"URL {} found in DB with pk {} but file is incomplete, re-downloading",
url,
existing_pk
);
}
}
// 1. Télécharger les 2048 premiers octets pour calculer le pk
let header = crate::download::peek_header(url, 2048)
.await
.map_err(|e| anyhow!("Failed to peek header: {}", e))?;

View File

@@ -372,7 +372,25 @@ impl DB {
}
/// Enregistre l'URL d'origine liée à un élément du cache.
///
/// Cette méthode détecte automatiquement les collisions de pk :
/// si le pk existe déjà avec une URL différente, un log d'erreur est émis.
pub fn set_origin_url(&self, pk: &str, origin_url: &str) -> rusqlite::Result<()> {
// Vérifier si ce pk a déjà une URL d'origine différente (détection de collision)
if let Ok(Some(existing_url)) = self.get_origin_url(pk) {
if existing_url != origin_url {
tracing::error!(
"🚨 COLLISION DE PK DÉTECTÉE: pk='{}' existe déjà avec origin_url='{}' mais tentative d'enregistrement avec origin_url='{}'",
pk,
existing_url,
origin_url
);
tracing::error!(
" Cela indique que deux fichiers différents ont généré le même pk. Considérez augmenter la taille du header pour le calcul du pk."
);
}
}
self.set_a_metadata(pk, "origin_url", Value::String(origin_url.to_owned()))
}
@@ -389,6 +407,30 @@ impl DB {
}
}
/// Recherche un pk par son URL d'origine.
///
/// Cette méthode permet de vérifier si un fichier avec une URL donnée
/// est déjà en cache avant de lancer un téléchargement.
///
/// # Arguments
///
/// * `origin_url` - L'URL d'origine à rechercher
///
/// # Returns
///
/// * `Ok(Some(pk))` - Le pk du fichier en cache avec cette URL
/// * `Ok(None)` - Aucun fichier avec cette URL n'est en cache
pub fn get_pk_by_origin_url(&self, origin_url: &str) -> rusqlite::Result<Option<String>> {
let conn = self.lock_conn("get_pk_by_origin_url");
conn.query_row(
"SELECT pk FROM metadata WHERE key = 'origin_url' AND value = ?",
[origin_url],
|row| row.get(0),
)
.optional()
}
/// Récupère uniquement les métadonnées JSON d'une entrée
///
/// # Arguments

View File

@@ -227,6 +227,52 @@ fn test_origin_url() {
assert_eq!(retrieved_url, Some(url.to_string()));
}
#[test]
fn test_pk_collision_detection() {
let (_temp_dir, db) = create_test_db();
let pk = "collision_pk_123";
let url1 = "https://example.com/file1.jpg";
let url2 = "https://example.com/file2.jpg";
// Ajouter le premier fichier avec le pk
db.add(pk, None, None).unwrap();
db.set_origin_url(pk, url1).unwrap();
// Vérifier que l'URL est bien enregistrée
let retrieved_url = db.get_origin_url(pk).unwrap();
assert_eq!(retrieved_url, Some(url1.to_string()));
// Tenter d'enregistrer une URL différente pour le même pk
// Ceci devrait logger une erreur mais ne devrait pas échouer
let result = db.set_origin_url(pk, url2);
assert!(result.is_ok());
// L'URL devrait être écrasée par la nouvelle (comportement actuel)
let retrieved_url = db.get_origin_url(pk).unwrap();
assert_eq!(retrieved_url, Some(url2.to_string()));
}
#[test]
fn test_get_pk_by_origin_url() {
let (_temp_dir, db) = create_test_db();
let pk = "test_pk_456";
let url = "https://example.com/cover.webp";
// Ajouter une entrée avec URL
db.add(pk, None, None).unwrap();
db.set_origin_url(pk, url).unwrap();
// Rechercher le pk par URL
let found_pk = db.get_pk_by_origin_url(url).unwrap();
assert_eq!(found_pk, Some(pk.to_string()));
// Rechercher une URL qui n'existe pas
let not_found = db.get_pk_by_origin_url("https://example.com/notfound.jpg").unwrap();
assert_eq!(not_found, None);
}
#[test]
fn test_get_from_id() {
let (_temp_dir, db) = create_test_db();