Skip to content

Commit

Permalink
refactor: [torrust#56] move upgrader from main upgrade mod to specifi…
Browse files Browse the repository at this point in the history
…c version upgrader mod
  • Loading branch information
josecelano committed Nov 30, 2022
1 parent 996c7d1 commit d590972
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 87 deletions.
82 changes: 5 additions & 77 deletions src/bin/upgrade.rs
Original file line number Diff line number Diff line change
@@ -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<SqliteDatabaseV1_0_0> {
// 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<SqliteDatabaseV2_0_0> {
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<SqliteDatabaseV2_0_0>) {
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<SqliteDatabaseV1_0_0>,
dest_database: Arc<SqliteDatabaseV2_0_0>,
) {
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;
}
2 changes: 0 additions & 2 deletions src/databases/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod mailer;
pub mod models;
pub mod routes;
pub mod tracker;
pub mod upgrades;
pub mod utils;

trait AsCSV {
Expand Down
2 changes: 2 additions & 0 deletions src/upgrades/from_v1_0_0_to_v2_0_0/databases/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod sqlite_v1_0_0;
pub mod sqlite_v2_0_0;
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -22,9 +23,11 @@ impl SqliteDatabaseV1_0_0 {
}

pub async fn get_categories_order_by_id(&self) -> Result<Vec<Category>, 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)
}
}
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<i64, DatabaseError> {
pub async fn insert_category_and_get_id(
&self,
category_name: &str,
) -> Result<i64, DatabaseError> {
query("INSERT INTO torrust_categories (name) VALUES (?)")
.bind(category_name)
.execute(&self.pool)
Expand All @@ -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;")
Expand Down
2 changes: 2 additions & 0 deletions src/upgrades/from_v1_0_0_to_v2_0_0/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod upgrader;
pub mod databases;
79 changes: 79 additions & 0 deletions src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs
Original file line number Diff line number Diff line change
@@ -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<SqliteDatabaseV1_0_0> {
// 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<SqliteDatabaseV2_0_0> {
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<SqliteDatabaseV2_0_0>) {
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<SqliteDatabaseV1_0_0>,
dest_database: Arc<SqliteDatabaseV2_0_0>,
) {
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`.
}
1 change: 1 addition & 0 deletions src/upgrades/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod from_v1_0_0_to_v2_0_0;

0 comments on commit d590972

Please sign in to comment.