des debug
This commit is contained in:
@@ -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))?;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user