diff --git a/migrations/mysql/20230627103405_torrust_allow_null_categories.sql b/migrations/mysql/20230627103405_torrust_allow_null_categories.sql new file mode 100644 index 00000000..9a540278 --- /dev/null +++ b/migrations/mysql/20230627103405_torrust_allow_null_categories.sql @@ -0,0 +1,6 @@ +-- Step 1: Allow null categories for torrents +ALTER TABLE torrust_torrents MODIFY category_id INTEGER NULL; + +-- Step 2: Set torrent category to NULL when category is deleted +ALTER TABLE `torrust_torrents` DROP FOREIGN KEY `torrust_torrents_ibfk_2`; +ALTER TABLE `torrust_torrents` ADD CONSTRAINT `torrust_torrents_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `torrust_categories` (`category_id`) ON DELETE SET NULL; diff --git a/migrations/sqlite3/20230627103405_torrust_allow_null_categories.sql b/migrations/sqlite3/20230627103405_torrust_allow_null_categories.sql new file mode 100644 index 00000000..f2c2b13e --- /dev/null +++ b/migrations/sqlite3/20230627103405_torrust_allow_null_categories.sql @@ -0,0 +1,28 @@ +-- Step 1: Create a new table with the new structure +CREATE TABLE IF NOT EXISTS "torrust_torrents_new" ( + "torrent_id" INTEGER NOT NULL, + "uploader_id" INTEGER NOT NULL, + "category_id" INTEGER NULL, + "info_hash" TEXT NOT NULL UNIQUE, + "size" INTEGER NOT NULL, + "name" TEXT NOT NULL, + "pieces" TEXT NOT NULL, + "piece_length" INTEGER NOT NULL, + "private" BOOLEAN DEFAULT NULL, + "root_hash" INT NOT NULL DEFAULT 0, + "date_uploaded" TEXT NOT NULL, + FOREIGN KEY("uploader_id") REFERENCES "torrust_users"("user_id") ON DELETE CASCADE, + FOREIGN KEY("category_id") REFERENCES "torrust_categories"("category_id") ON DELETE SET NULL, + PRIMARY KEY("torrent_id" AUTOINCREMENT) +); + +-- Step 2: Copy rows from the current table to the new table +INSERT INTO torrust_torrents_new (torrent_id, uploader_id, category_id, info_hash, size, name, pieces, piece_length, private, root_hash, date_uploaded) +SELECT torrent_id, uploader_id, category_id, info_hash, size, name, pieces, piece_length, private, root_hash, date_uploaded +FROM torrust_torrents; + +-- Step 3: Delete the current table +DROP TABLE torrust_torrents; + +-- Step 1: Rename the new table +ALTER TABLE torrust_torrents_new RENAME TO torrust_torrents; diff --git a/src/models/response.rs b/src/models/response.rs index 09476be3..cd8b4f59 100644 --- a/src/models/response.rs +++ b/src/models/response.rs @@ -52,7 +52,7 @@ pub struct TorrentResponse { pub info_hash: String, pub title: String, pub description: Option, - pub category: Category, + pub category: Option, pub upload_date: String, pub file_size: i64, pub seeders: i64, @@ -65,7 +65,7 @@ pub struct TorrentResponse { impl TorrentResponse { #[must_use] - pub fn from_listing(torrent_listing: TorrentListing, category: Category) -> TorrentResponse { + pub fn from_listing(torrent_listing: TorrentListing, category: Option) -> TorrentResponse { TorrentResponse { torrent_id: torrent_listing.torrent_id, uploader: torrent_listing.uploader, diff --git a/src/models/torrent.rs b/src/models/torrent.rs index c06800ca..194b0c10 100644 --- a/src/models/torrent.rs +++ b/src/models/torrent.rs @@ -16,7 +16,7 @@ pub struct TorrentListing { pub info_hash: String, pub title: String, pub description: Option, - pub category_id: i64, + pub category_id: Option, pub date_uploaded: String, pub file_size: i64, pub seeders: i64, diff --git a/src/services/torrent.rs b/src/services/torrent.rs index 7a7262ba..c56dc9a3 100644 --- a/src/services/torrent.rs +++ b/src/services/torrent.rs @@ -221,7 +221,10 @@ impl Index { let torrent_id = torrent_listing.torrent_id; - let category = self.category_repository.get_by_id(&torrent_listing.category_id).await?; + let category = match torrent_listing.category_id { + Some(category_id) => Some(self.category_repository.get_by_id(&category_id).await?), + None => None, + }; let mut torrent_response = TorrentResponse::from_listing(torrent_listing, category); @@ -382,7 +385,10 @@ impl Index { .one_torrent_by_torrent_id(&torrent_listing.torrent_id) .await?; - let category = self.category_repository.get_by_id(&torrent_listing.category_id).await?; + let category = match torrent_listing.category_id { + Some(category_id) => Some(self.category_repository.get_by_id(&category_id).await?), + None => None, + }; let torrent_response = TorrentResponse::from_listing(torrent_listing, category);