diff --git a/src/bin/upgrade.rs b/src/bin/upgrade.rs index 563bebdb..15350d1d 100644 --- a/src/bin/upgrade.rs +++ b/src/bin/upgrade.rs @@ -1,82 +1,10 @@ -//! Migration command to migrate data from v1.0.0 to v2.0.0 -//! Run it with `cargo run --bin upgrade` +//! Upgrade command. +//! It updates the application from version v1.0.0 to v2.0.0. +//! You can execute it with: `cargo run --bin upgrade` -use std::sync::Arc; -use torrust_index_backend::config::Configuration; -use torrust_index_backend::databases::sqlite_v1_0_0::SqliteDatabaseV1_0_0; -use torrust_index_backend::databases::sqlite_v2_0_0::SqliteDatabaseV2_0_0; - -async fn current_db() -> Arc { - // Connect to the old v1.0.0 DB - let cfg = match Configuration::load_from_file().await { - Ok(config) => Arc::new(config), - Err(error) => { - panic!("{}", error) - } - }; - - let settings = cfg.settings.read().await; - - Arc::new(SqliteDatabaseV1_0_0::new(&settings.database.connect_url).await) -} - -async fn new_db(db_filename: String) -> Arc { - let dest_database_connect_url = format!("sqlite://{}?mode=rwc", db_filename); - Arc::new(SqliteDatabaseV2_0_0::new(&dest_database_connect_url).await) -} - -async fn reset_destiny_database(dest_database: Arc) { - println!("Truncating all tables in destiny database ..."); - dest_database - .delete_all_database_rows() - .await - .expect("Can't reset destiny database."); -} - -async fn transfer_categories( - source_database: Arc, - dest_database: Arc, -) { - let source_categories = source_database.get_categories_order_by_id().await.unwrap(); - println!("[v1] categories: {:?}", &source_categories); - - let result = dest_database.reset_categories_sequence().await.unwrap(); - println!("result {:?}", result); - - for cat in &source_categories { - println!( - "[v2] adding category: {:?} {:?} ...", - &cat.category_id, &cat.name - ); - let id = dest_database - .insert_category_and_get_id(&cat.name) - .await - .unwrap(); - - if id != cat.category_id { - panic!( - "Error copying category {:?} from source DB to destiny DB", - &cat.category_id - ); - } - - println!("[v2] category: {:?} {:?} added.", id, &cat.name); - } - - let dest_categories = dest_database.get_categories().await.unwrap(); - println!("[v2] categories: {:?}", &dest_categories); -} +use torrust_index_backend::upgrades::from_v1_0_0_to_v2_0_0::upgrader::upgrade; #[actix_web::main] async fn main() { - // Get connections to source adn destiny databases - let source_database = current_db().await; - let dest_database = new_db("data_v2.db".to_string()).await; - - println!("Upgrading data from version v1.0.0 to v2.0.0 ..."); - - reset_destiny_database(dest_database.clone()).await; - transfer_categories(source_database.clone(), dest_database.clone()).await; - - // TODO: WIP. We have to transfer data from the 5 tables in V1 and the torrent files in folder `uploads`. + upgrade().await; } diff --git a/src/databases/mod.rs b/src/databases/mod.rs index c15a2b72..169d99f4 100644 --- a/src/databases/mod.rs +++ b/src/databases/mod.rs @@ -1,5 +1,3 @@ pub mod database; pub mod mysql; pub mod sqlite; -pub mod sqlite_v1_0_0; -pub mod sqlite_v2_0_0; diff --git a/src/lib.rs b/src/lib.rs index 5a0100c3..d7ef0d09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ pub mod mailer; pub mod models; pub mod routes; pub mod tracker; +pub mod upgrades; pub mod utils; trait AsCSV { diff --git a/src/upgrades/from_v1_0_0_to_v2_0_0/databases/mod.rs b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/mod.rs new file mode 100644 index 00000000..fa37d81b --- /dev/null +++ b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/mod.rs @@ -0,0 +1,2 @@ +pub mod sqlite_v1_0_0; +pub mod sqlite_v2_0_0; diff --git a/src/databases/sqlite_v1_0_0.rs b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v1_0_0.rs similarity index 71% rename from src/databases/sqlite_v1_0_0.rs rename to src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v1_0_0.rs index 10420128..a7351479 100644 --- a/src/databases/sqlite_v1_0_0.rs +++ b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v1_0_0.rs @@ -1,8 +1,9 @@ -use super::database::DatabaseError; use serde::{Deserialize, Serialize}; use sqlx::sqlite::SqlitePoolOptions; use sqlx::{query_as, SqlitePool}; +use crate::databases::database::DatabaseError; + #[derive(Debug, Serialize, Deserialize, sqlx::FromRow)] pub struct Category { pub category_id: i64, @@ -22,9 +23,11 @@ impl SqliteDatabaseV1_0_0 { } pub async fn get_categories_order_by_id(&self) -> Result, DatabaseError> { - query_as::<_, Category>("SELECT category_id, name FROM torrust_categories ORDER BY category_id ASC") - .fetch_all(&self.pool) - .await - .map_err(|_| DatabaseError::Error) + query_as::<_, Category>( + "SELECT category_id, name FROM torrust_categories ORDER BY category_id ASC", + ) + .fetch_all(&self.pool) + .await + .map_err(|_| DatabaseError::Error) } } diff --git a/src/databases/sqlite_v2_0_0.rs b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v2_0_0.rs similarity index 94% rename from src/databases/sqlite_v2_0_0.rs rename to src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v2_0_0.rs index 0a1efe33..8dce7584 100644 --- a/src/databases/sqlite_v2_0_0.rs +++ b/src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v2_0_0.rs @@ -1,8 +1,9 @@ -use super::database::DatabaseError; use serde::{Deserialize, Serialize}; use sqlx::sqlite::{SqlitePoolOptions, SqliteQueryResult}; use sqlx::{query, query_as, SqlitePool}; +use crate::databases::database::DatabaseError; + #[derive(Debug, Serialize, Deserialize, sqlx::FromRow)] pub struct Category { pub category_id: i64, @@ -35,7 +36,10 @@ impl SqliteDatabaseV2_0_0 { .map_err(|_| DatabaseError::Error) } - pub async fn insert_category_and_get_id(&self, category_name: &str) -> Result { + pub async fn insert_category_and_get_id( + &self, + category_name: &str, + ) -> Result { query("INSERT INTO torrust_categories (name) VALUES (?)") .bind(category_name) .execute(&self.pool) @@ -51,7 +55,7 @@ impl SqliteDatabaseV2_0_0 { } _ => DatabaseError::Error, }) - } + } pub async fn delete_all_database_rows(&self) -> Result<(), DatabaseError> { query("DELETE FROM torrust_categories;") diff --git a/src/upgrades/from_v1_0_0_to_v2_0_0/mod.rs b/src/upgrades/from_v1_0_0_to_v2_0_0/mod.rs new file mode 100644 index 00000000..ef4843d0 --- /dev/null +++ b/src/upgrades/from_v1_0_0_to_v2_0_0/mod.rs @@ -0,0 +1,2 @@ +pub mod upgrader; +pub mod databases; \ No newline at end of file diff --git a/src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs b/src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs index e69de29b..1be682cd 100644 --- a/src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs +++ b/src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs @@ -0,0 +1,79 @@ +use crate::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v1_0_0::SqliteDatabaseV1_0_0; +use crate::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v2_0_0::SqliteDatabaseV2_0_0; +use std::sync::Arc; + +use crate::config::Configuration; + +async fn current_db() -> Arc { + // Connect to the old v1.0.0 DB + let cfg = match Configuration::load_from_file().await { + Ok(config) => Arc::new(config), + Err(error) => { + panic!("{}", error) + } + }; + + let settings = cfg.settings.read().await; + + Arc::new(SqliteDatabaseV1_0_0::new(&settings.database.connect_url).await) +} + +async fn new_db(db_filename: String) -> Arc { + let dest_database_connect_url = format!("sqlite://{}?mode=rwc", db_filename); + Arc::new(SqliteDatabaseV2_0_0::new(&dest_database_connect_url).await) +} + +async fn reset_destiny_database(dest_database: Arc) { + println!("Truncating all tables in destiny database ..."); + dest_database + .delete_all_database_rows() + .await + .expect("Can't reset destiny database."); +} + +async fn transfer_categories( + source_database: Arc, + dest_database: Arc, +) { + let source_categories = source_database.get_categories_order_by_id().await.unwrap(); + println!("[v1] categories: {:?}", &source_categories); + + let result = dest_database.reset_categories_sequence().await.unwrap(); + println!("result {:?}", result); + + for cat in &source_categories { + println!( + "[v2] adding category: {:?} {:?} ...", + &cat.category_id, &cat.name + ); + let id = dest_database + .insert_category_and_get_id(&cat.name) + .await + .unwrap(); + + if id != cat.category_id { + panic!( + "Error copying category {:?} from source DB to destiny DB", + &cat.category_id + ); + } + + println!("[v2] category: {:?} {:?} added.", id, &cat.name); + } + + let dest_categories = dest_database.get_categories().await.unwrap(); + println!("[v2] categories: {:?}", &dest_categories); +} + +pub async fn upgrade() { + // Get connections to source adn destiny databases + let source_database = current_db().await; + let dest_database = new_db("data_v2.db".to_string()).await; + + println!("Upgrading data from version v1.0.0 to v2.0.0 ..."); + + reset_destiny_database(dest_database.clone()).await; + transfer_categories(source_database.clone(), dest_database.clone()).await; + + // TODO: WIP. We have to transfer data from the 5 tables in V1 and the torrent files in folder `uploads`. +} diff --git a/src/upgrades/mod.rs b/src/upgrades/mod.rs new file mode 100644 index 00000000..736d54f6 --- /dev/null +++ b/src/upgrades/mod.rs @@ -0,0 +1 @@ +pub mod from_v1_0_0_to_v2_0_0; \ No newline at end of file