Merge branch 'db-no-duplicates' into 'main'

Reject duplicate links

See merge request kernald/reddit-magnet!4
This commit is contained in:
Marc Plano-Lesay 2025-04-30 12:21:32 +00:00
commit 8530f4f3e6
3 changed files with 78 additions and 0 deletions

View file

@ -0,0 +1 @@
DROP INDEX magnets_unique_link;

View file

@ -0,0 +1 @@
CREATE UNIQUE INDEX magnets_unique_link ON magnets(link);

View file

@ -69,6 +69,73 @@ mod tests {
assert_eq!(magnet.published_at, expected_timestamp);
}
}
#[test]
fn test_prevent_duplicate_magnets() {
let temp_dir = tempdir().unwrap();
let db_path = temp_dir.path().join("test.db");
let mut db = Database::new(&db_path).unwrap();
// Create initial post with magnet links
let post_info = PostInfo {
title: "Test Title".to_string(),
submitter: "test_user".to_string(),
subreddit: "test_subreddit".to_string(),
magnet_links: vec![
"magnet:?xt=urn:btih:test1".to_string(),
"magnet:?xt=urn:btih:test2".to_string(),
],
timestamp: Utc::now(),
};
// First insertion should succeed and insert 2 links
let result = db.store_magnets(&post_info);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 2); // 2 links inserted
// Create a second post with some duplicate and some new links
let post_info2 = PostInfo {
title: "Test Title 2".to_string(),
submitter: "test_user2".to_string(),
subreddit: "test_subreddit2".to_string(),
magnet_links: vec![
"magnet:?xt=urn:btih:test1".to_string(), // Duplicate
"magnet:?xt=urn:btih:test3".to_string(), // New
],
timestamp: Utc::now(),
};
// Second insertion should succeed but only insert the new link
let result2 = db.store_magnets(&post_info2);
assert!(result2.is_ok());
assert_eq!(result2.unwrap(), 1); // Only 1 new link inserted
// Verify we have 3 total links in the database
let magnets = db.get_all_magnets().unwrap();
assert_eq!(magnets.len(), 3);
// Try inserting only duplicates
let post_info3 = PostInfo {
title: "Test Title 3".to_string(),
submitter: "test_user3".to_string(),
subreddit: "test_subreddit3".to_string(),
magnet_links: vec![
"magnet:?xt=urn:btih:test1".to_string(), // Duplicate
"magnet:?xt=urn:btih:test2".to_string(), // Duplicate
],
timestamp: Utc::now(),
};
// Third insertion should succeed but insert 0 links
let result3 = db.store_magnets(&post_info3);
assert!(result3.is_ok());
assert_eq!(result3.unwrap(), 0); // No new links inserted
// Verify we still have 3 total links in the database
let magnets = db.get_all_magnets().unwrap();
assert_eq!(magnets.len(), 3);
}
}
impl Database {
@ -103,9 +170,18 @@ impl Database {
pub fn store_magnets(&mut self, post: &PostInfo) -> Result<usize> {
let published_at = post.timestamp.naive_utc();
// Filter out magnet links that already exist in the database
let existing_links: Vec<String> = magnets::table
.select(magnets::link)
.filter(magnets::link.eq_any(&post.magnet_links))
.load(&mut self.conn)
.wrap_err("Failed to query existing magnets")?;
let links = post
.magnet_links
.iter()
.filter(|link| !existing_links.contains(link))
.map(|m| NewMagnet {
title: post.title.as_str(),
submitter: post.submitter.as_str(),