Skip to content

Commit

Permalink
feat!: [torrust#276] do not persist uploaded torrent if it cannot per…
Browse files Browse the repository at this point in the history
…sit tags

When you upload a torrent the transaction wraps all the persisted data.

Before this change, if tags can't be stored in the database the rest of
the indexed data is stored anyway.
  • Loading branch information
josecelano committed Sep 20, 2023
1 parent 6a75c54 commit fbb42ad
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 37 deletions.
6 changes: 2 additions & 4 deletions src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::databases::sqlite::Sqlite;
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
use crate::models::torrent::{Metadata, TorrentListing};
use crate::models::torrent_file::{DbTorrent, Torrent, TorrentFile};
use crate::models::torrent_tag::{TagId, TorrentTag};
use crate::models::tracker_key::TrackerKey;
Expand Down Expand Up @@ -196,9 +196,7 @@ pub trait Database: Sync + Send {
original_info_hash: &InfoHash,
torrent: &Torrent,
uploader_id: UserId,
category_id: CategoryId,
title: &str,
description: &str,
metadata: &Metadata,
) -> Result<i64, Error>;

/// Get `Torrent` from `InfoHash`.
Expand Down
29 changes: 22 additions & 7 deletions src/databases/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCom
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
use crate::models::torrent::{Metadata, TorrentListing};
use crate::models::torrent_file::{DbTorrent, DbTorrentAnnounceUrl, DbTorrentFile, Torrent, TorrentFile};
use crate::models::torrent_tag::{TagId, TorrentTag};
use crate::models::tracker_key::TrackerKey;
Expand Down Expand Up @@ -432,9 +432,7 @@ impl Database for Mysql {
original_info_hash: &InfoHash,
torrent: &Torrent,
uploader_id: UserId,
category_id: CategoryId,
title: &str,
description: &str,
metadata: &Metadata,
) -> Result<i64, database::Error> {
let info_hash = torrent.canonical_info_hash_hex();
let canonical_info_hash = torrent.canonical_info_hash();
Expand Down Expand Up @@ -471,7 +469,7 @@ impl Database for Mysql {
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, UTC_TIMESTAMP())",
)
.bind(uploader_id)
.bind(category_id)
.bind(metadata.category_id)
.bind(info_hash.to_lowercase())
.bind(torrent.file_size())
.bind(torrent.info.name.to_string())
Expand Down Expand Up @@ -585,11 +583,28 @@ impl Database for Mysql {
return Err(e);
}

// Insert tags

for tag_id in &metadata.tags {
let insert_torrent_tag_result = query("INSERT INTO torrust_torrent_tag_links (torrent_id, tag_id) VALUES (?, ?)")
.bind(torrent_id)
.bind(tag_id)
.execute(&mut tx)
.await
.map_err(|err| database::Error::ErrorWithText(err.to_string()));

// rollback transaction on error
if let Err(e) = insert_torrent_tag_result {
drop(tx.rollback().await);
return Err(e);
}
}

let insert_torrent_info_result =
query(r#"INSERT INTO torrust_torrent_info (torrent_id, title, description) VALUES (?, ?, NULLIF(?, ""))"#)
.bind(torrent_id)
.bind(title)
.bind(description)
.bind(metadata.title.clone())
.bind(metadata.description.clone())
.execute(&mut tx)
.await
.map_err(|e| match e {
Expand Down
29 changes: 22 additions & 7 deletions src/databases/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCom
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
use crate::models::torrent::{Metadata, TorrentListing};
use crate::models::torrent_file::{DbTorrent, DbTorrentAnnounceUrl, DbTorrentFile, Torrent, TorrentFile};
use crate::models::torrent_tag::{TagId, TorrentTag};
use crate::models::tracker_key::TrackerKey;
Expand Down Expand Up @@ -422,9 +422,7 @@ impl Database for Sqlite {
original_info_hash: &InfoHash,
torrent: &Torrent,
uploader_id: UserId,
category_id: CategoryId,
title: &str,
description: &str,
metadata: &Metadata,
) -> Result<i64, database::Error> {
let info_hash = torrent.canonical_info_hash_hex();
let canonical_info_hash = torrent.canonical_info_hash();
Expand Down Expand Up @@ -461,7 +459,7 @@ impl Database for Sqlite {
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%S',DATETIME('now', 'utc')))",
)
.bind(uploader_id)
.bind(category_id)
.bind(metadata.category_id)
.bind(info_hash.to_lowercase())
.bind(torrent.file_size())
.bind(torrent.info.name.to_string())
Expand Down Expand Up @@ -575,11 +573,28 @@ impl Database for Sqlite {
return Err(e);
}

// Insert tags

for tag_id in &metadata.tags {
let insert_torrent_tag_result = query("INSERT INTO torrust_torrent_tag_links (torrent_id, tag_id) VALUES (?, ?)")
.bind(torrent_id)
.bind(tag_id)
.execute(&mut tx)
.await
.map_err(|err| database::Error::ErrorWithText(err.to_string()));

// rollback transaction on error
if let Err(e) = insert_torrent_tag_result {
drop(tx.rollback().await);
return Err(e);
}
}

let insert_torrent_info_result =
query(r#"INSERT INTO torrust_torrent_info (torrent_id, title, description) VALUES (?, ?, NULLIF(?, ""))"#)
.bind(torrent_id)
.bind(title)
.bind(description)
.bind(metadata.title.clone())
.bind(metadata.description.clone())
.execute(&mut tx)
.await
.map_err(|e| match e {
Expand Down
22 changes: 3 additions & 19 deletions src/services/torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,12 @@ impl Index {

self.customize_announcement_info_for(&mut torrent).await;

let canonical_info_hash = torrent.canonical_info_hash();

self.canonical_info_hash_group_checks(&original_info_hash, &canonical_info_hash)
self.canonical_info_hash_group_checks(&original_info_hash, &torrent.canonical_info_hash())
.await?;

// Store the torrent into the database

let torrent_id = self
.torrent_repository
.add(&original_info_hash, &torrent, &metadata, user_id, metadata.category_id)
.await?;

self.torrent_tag_repository
.link_torrent_to_tags(&torrent_id, &metadata.tags)
.add(&original_info_hash, &torrent, &metadata, user_id)
.await?;

// Secondary task: import torrent statistics from the tracker
Expand Down Expand Up @@ -544,17 +536,9 @@ impl DbTorrentRepository {
torrent: &Torrent,
metadata: &Metadata,
user_id: UserId,
category_id: CategoryId,
) -> Result<TorrentId, Error> {
self.database
.insert_torrent_and_get_id(
original_info_hash,
torrent,
user_id,
category_id,
&metadata.title,
&metadata.description,
)
.insert_torrent_and_get_id(original_info_hash, torrent, user_id, metadata)
.await
}

Expand Down

0 comments on commit fbb42ad

Please sign in to comment.