Skip to content

Commit fbb42ad

Browse files
committed
feat!: [#276] do not persist uploaded torrent if it cannot persit 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.
1 parent 6a75c54 commit fbb42ad

File tree

4 files changed

+49
-37
lines changed

4 files changed

+49
-37
lines changed

src/databases/database.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::databases::sqlite::Sqlite;
77
use crate::models::category::CategoryId;
88
use crate::models::info_hash::InfoHash;
99
use crate::models::response::TorrentsResponse;
10-
use crate::models::torrent::TorrentListing;
10+
use crate::models::torrent::{Metadata, TorrentListing};
1111
use crate::models::torrent_file::{DbTorrent, Torrent, TorrentFile};
1212
use crate::models::torrent_tag::{TagId, TorrentTag};
1313
use crate::models::tracker_key::TrackerKey;
@@ -196,9 +196,7 @@ pub trait Database: Sync + Send {
196196
original_info_hash: &InfoHash,
197197
torrent: &Torrent,
198198
uploader_id: UserId,
199-
category_id: CategoryId,
200-
title: &str,
201-
description: &str,
199+
metadata: &Metadata,
202200
) -> Result<i64, Error>;
203201

204202
/// Get `Torrent` from `InfoHash`.

src/databases/mysql.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCom
1212
use crate::models::category::CategoryId;
1313
use crate::models::info_hash::InfoHash;
1414
use crate::models::response::TorrentsResponse;
15-
use crate::models::torrent::TorrentListing;
15+
use crate::models::torrent::{Metadata, TorrentListing};
1616
use crate::models::torrent_file::{DbTorrent, DbTorrentAnnounceUrl, DbTorrentFile, Torrent, TorrentFile};
1717
use crate::models::torrent_tag::{TagId, TorrentTag};
1818
use crate::models::tracker_key::TrackerKey;
@@ -432,9 +432,7 @@ impl Database for Mysql {
432432
original_info_hash: &InfoHash,
433433
torrent: &Torrent,
434434
uploader_id: UserId,
435-
category_id: CategoryId,
436-
title: &str,
437-
description: &str,
435+
metadata: &Metadata,
438436
) -> Result<i64, database::Error> {
439437
let info_hash = torrent.canonical_info_hash_hex();
440438
let canonical_info_hash = torrent.canonical_info_hash();
@@ -471,7 +469,7 @@ impl Database for Mysql {
471469
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, UTC_TIMESTAMP())",
472470
)
473471
.bind(uploader_id)
474-
.bind(category_id)
472+
.bind(metadata.category_id)
475473
.bind(info_hash.to_lowercase())
476474
.bind(torrent.file_size())
477475
.bind(torrent.info.name.to_string())
@@ -585,11 +583,28 @@ impl Database for Mysql {
585583
return Err(e);
586584
}
587585

586+
// Insert tags
587+
588+
for tag_id in &metadata.tags {
589+
let insert_torrent_tag_result = query("INSERT INTO torrust_torrent_tag_links (torrent_id, tag_id) VALUES (?, ?)")
590+
.bind(torrent_id)
591+
.bind(tag_id)
592+
.execute(&mut tx)
593+
.await
594+
.map_err(|err| database::Error::ErrorWithText(err.to_string()));
595+
596+
// rollback transaction on error
597+
if let Err(e) = insert_torrent_tag_result {
598+
drop(tx.rollback().await);
599+
return Err(e);
600+
}
601+
}
602+
588603
let insert_torrent_info_result =
589604
query(r#"INSERT INTO torrust_torrent_info (torrent_id, title, description) VALUES (?, ?, NULLIF(?, ""))"#)
590605
.bind(torrent_id)
591-
.bind(title)
592-
.bind(description)
606+
.bind(metadata.title.clone())
607+
.bind(metadata.description.clone())
593608
.execute(&mut tx)
594609
.await
595610
.map_err(|e| match e {

src/databases/sqlite.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCom
1212
use crate::models::category::CategoryId;
1313
use crate::models::info_hash::InfoHash;
1414
use crate::models::response::TorrentsResponse;
15-
use crate::models::torrent::TorrentListing;
15+
use crate::models::torrent::{Metadata, TorrentListing};
1616
use crate::models::torrent_file::{DbTorrent, DbTorrentAnnounceUrl, DbTorrentFile, Torrent, TorrentFile};
1717
use crate::models::torrent_tag::{TagId, TorrentTag};
1818
use crate::models::tracker_key::TrackerKey;
@@ -422,9 +422,7 @@ impl Database for Sqlite {
422422
original_info_hash: &InfoHash,
423423
torrent: &Torrent,
424424
uploader_id: UserId,
425-
category_id: CategoryId,
426-
title: &str,
427-
description: &str,
425+
metadata: &Metadata,
428426
) -> Result<i64, database::Error> {
429427
let info_hash = torrent.canonical_info_hash_hex();
430428
let canonical_info_hash = torrent.canonical_info_hash();
@@ -461,7 +459,7 @@ impl Database for Sqlite {
461459
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%S',DATETIME('now', 'utc')))",
462460
)
463461
.bind(uploader_id)
464-
.bind(category_id)
462+
.bind(metadata.category_id)
465463
.bind(info_hash.to_lowercase())
466464
.bind(torrent.file_size())
467465
.bind(torrent.info.name.to_string())
@@ -575,11 +573,28 @@ impl Database for Sqlite {
575573
return Err(e);
576574
}
577575

576+
// Insert tags
577+
578+
for tag_id in &metadata.tags {
579+
let insert_torrent_tag_result = query("INSERT INTO torrust_torrent_tag_links (torrent_id, tag_id) VALUES (?, ?)")
580+
.bind(torrent_id)
581+
.bind(tag_id)
582+
.execute(&mut tx)
583+
.await
584+
.map_err(|err| database::Error::ErrorWithText(err.to_string()));
585+
586+
// rollback transaction on error
587+
if let Err(e) = insert_torrent_tag_result {
588+
drop(tx.rollback().await);
589+
return Err(e);
590+
}
591+
}
592+
578593
let insert_torrent_info_result =
579594
query(r#"INSERT INTO torrust_torrent_info (torrent_id, title, description) VALUES (?, ?, NULLIF(?, ""))"#)
580595
.bind(torrent_id)
581-
.bind(title)
582-
.bind(description)
596+
.bind(metadata.title.clone())
597+
.bind(metadata.description.clone())
583598
.execute(&mut tx)
584599
.await
585600
.map_err(|e| match e {

src/services/torrent.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,12 @@ impl Index {
138138

139139
self.customize_announcement_info_for(&mut torrent).await;
140140

141-
let canonical_info_hash = torrent.canonical_info_hash();
142-
143-
self.canonical_info_hash_group_checks(&original_info_hash, &canonical_info_hash)
141+
self.canonical_info_hash_group_checks(&original_info_hash, &torrent.canonical_info_hash())
144142
.await?;
145143

146-
// Store the torrent into the database
147-
148144
let torrent_id = self
149145
.torrent_repository
150-
.add(&original_info_hash, &torrent, &metadata, user_id, metadata.category_id)
151-
.await?;
152-
153-
self.torrent_tag_repository
154-
.link_torrent_to_tags(&torrent_id, &metadata.tags)
146+
.add(&original_info_hash, &torrent, &metadata, user_id)
155147
.await?;
156148

157149
// Secondary task: import torrent statistics from the tracker
@@ -544,17 +536,9 @@ impl DbTorrentRepository {
544536
torrent: &Torrent,
545537
metadata: &Metadata,
546538
user_id: UserId,
547-
category_id: CategoryId,
548539
) -> Result<TorrentId, Error> {
549540
self.database
550-
.insert_torrent_and_get_id(
551-
original_info_hash,
552-
torrent,
553-
user_id,
554-
category_id,
555-
&metadata.title,
556-
&metadata.description,
557-
)
541+
.insert_torrent_and_get_id(original_info_hash, torrent, user_id, metadata)
558542
.await
559543
}
560544

0 commit comments

Comments
 (0)