Skip to content

Commit

Permalink
refactor: extract struct TorrentRecordV2
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Nov 30, 2022
1 parent b9bf405 commit 6bb4c53
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 76 deletions.
34 changes: 18 additions & 16 deletions src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v1_0_0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct CategoryRecord {
}

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct UserRecord {
pub struct UserRecordV1 {
pub user_id: i64,
pub username: String,
pub email: String,
Expand All @@ -21,15 +21,15 @@ pub struct UserRecord {
}

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct TrackerKeyRecord {
pub struct TrackerKeyRecordV1 {
pub key_id: i64,
pub user_id: i64,
pub key: String,
pub valid_until: i64,
}

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct TorrentRecord {
pub struct TorrentRecordV1 {
pub torrent_id: i64,
pub uploader: String,
pub info_hash: String,
Expand All @@ -43,7 +43,7 @@ pub struct TorrentRecord {
}

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct TorrentFileRecord {
pub struct TorrentFileRecordV1 {
pub file_id: i64,
pub torrent_uid: i64,
pub number: i64,
Expand Down Expand Up @@ -73,34 +73,36 @@ impl SqliteDatabaseV1_0_0 {
.map_err(|_| DatabaseError::Error)
}

pub async fn get_users(&self) -> Result<Vec<UserRecord>, sqlx::Error> {
query_as::<_, UserRecord>("SELECT * FROM torrust_users ORDER BY user_id ASC")
pub async fn get_users(&self) -> Result<Vec<UserRecordV1>, sqlx::Error> {
query_as::<_, UserRecordV1>("SELECT * FROM torrust_users ORDER BY user_id ASC")
.fetch_all(&self.pool)
.await
}

pub async fn get_user_by_username(&self, username: &str) -> Result<UserRecord, sqlx::Error> {
query_as::<_, UserRecord>("SELECT * FROM torrust_users WHERE username = ?")
pub async fn get_user_by_username(&self, username: &str) -> Result<UserRecordV1, sqlx::Error> {
query_as::<_, UserRecordV1>("SELECT * FROM torrust_users WHERE username = ?")
.bind(username)
.fetch_one(&self.pool)
.await
}

pub async fn get_tracker_keys(&self) -> Result<Vec<TrackerKeyRecord>, sqlx::Error> {
query_as::<_, TrackerKeyRecord>("SELECT * FROM torrust_tracker_keys ORDER BY key_id ASC")
pub async fn get_tracker_keys(&self) -> Result<Vec<TrackerKeyRecordV1>, sqlx::Error> {
query_as::<_, TrackerKeyRecordV1>("SELECT * FROM torrust_tracker_keys ORDER BY key_id ASC")
.fetch_all(&self.pool)
.await
}

pub async fn get_torrents(&self) -> Result<Vec<TorrentRecord>, sqlx::Error> {
query_as::<_, TorrentRecord>("SELECT * FROM torrust_torrents ORDER BY torrent_id ASC")
pub async fn get_torrents(&self) -> Result<Vec<TorrentRecordV1>, sqlx::Error> {
query_as::<_, TorrentRecordV1>("SELECT * FROM torrust_torrents ORDER BY torrent_id ASC")
.fetch_all(&self.pool)
.await
}

pub async fn get_torrent_files(&self) -> Result<Vec<TorrentFileRecord>, sqlx::Error> {
query_as::<_, TorrentFileRecord>("SELECT * FROM torrust_torrent_files ORDER BY file_id ASC")
.fetch_all(&self.pool)
.await
pub async fn get_torrent_files(&self) -> Result<Vec<TorrentFileRecordV1>, sqlx::Error> {
query_as::<_, TorrentFileRecordV1>(
"SELECT * FROM torrust_torrent_files ORDER BY file_id ASC",
)
.fetch_all(&self.pool)
.await
}
}
101 changes: 69 additions & 32 deletions src/upgrades/from_v1_0_0_to_v2_0_0/databases/sqlite_v2_0_0.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,67 @@
use chrono::{DateTime, NaiveDateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::sqlite::{SqlitePoolOptions, SqliteQueryResult};
use sqlx::{query, query_as, SqlitePool};

use crate::databases::database::DatabaseError;
use crate::models::torrent_file::TorrentFile;
use crate::models::torrent_file::{TorrentFile, TorrentInfo};

use super::sqlite_v1_0_0::TorrentRecord;
use super::sqlite_v1_0_0::{TorrentRecordV1, UserRecordV1};

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct CategoryRecord {
pub struct CategoryRecordV2 {
pub category_id: i64,
pub name: String,
}

pub struct TorrentRecordV2 {
pub torrent_id: i64,
pub uploader_id: i64,
pub category_id: i64,
pub info_hash: String,
pub size: i64,
pub name: String,
pub pieces: String,
pub piece_length: i64,
pub private: bool,
pub root_hash: i64,
pub date_uploaded: String,
}

impl TorrentRecordV2 {
pub fn from_v1_data(
torrent: &TorrentRecordV1,
torrent_info: &TorrentInfo,
uploader: &UserRecordV1,
private: bool,
) -> Self {
Self {
torrent_id: torrent.torrent_id,
uploader_id: uploader.user_id,
category_id: torrent.category_id,
info_hash: torrent.info_hash.clone(),
size: torrent.file_size,
name: torrent_info.name.clone(),
pieces: torrent_info.get_pieces_as_string(),
piece_length: torrent_info.piece_length,
private,
root_hash: torrent_info.get_root_hash_as_i64(),
date_uploaded: convert_timestamp_to_datetime(torrent.upload_date),
}
}
}

fn convert_timestamp_to_datetime(timestamp: i64) -> String {
// The expected format in database is: 2022-11-04 09:53:57
// MySQL uses a DATETIME column and SQLite uses a TEXT column.

let naive_datetime = NaiveDateTime::from_timestamp(timestamp, 0);
let datetime_again: DateTime<Utc> = DateTime::from_utc(naive_datetime, Utc);

// Format without timezone
datetime_again.format("%Y-%m-%d %H:%M:%S").to_string()
}

pub struct SqliteDatabaseV2_0_0 {
pub pool: SqlitePool,
}
Expand Down Expand Up @@ -39,8 +89,8 @@ impl SqliteDatabaseV2_0_0 {
.map_err(|_| DatabaseError::Error)
}

pub async fn get_categories(&self) -> Result<Vec<CategoryRecord>, DatabaseError> {
query_as::<_, CategoryRecord>("SELECT tc.category_id, tc.name, COUNT(tt.category_id) as num_torrents FROM torrust_categories tc LEFT JOIN torrust_torrents tt on tc.category_id = tt.category_id GROUP BY tc.name")
pub async fn get_categories(&self) -> Result<Vec<CategoryRecordV2>, DatabaseError> {
query_as::<_, CategoryRecordV2>("SELECT tc.category_id, tc.name, COUNT(tt.category_id) as num_torrents FROM torrust_categories tc LEFT JOIN torrust_torrents tt on tc.category_id = tt.category_id GROUP BY tc.name")
.fetch_all(&self.pool)
.await
.map_err(|_| DatabaseError::Error)
Expand Down Expand Up @@ -133,20 +183,7 @@ impl SqliteDatabaseV2_0_0 {
.map(|v| v.last_insert_rowid())
}

pub async fn insert_torrent(
&self,
torrent_id: i64,
uploader_id: i64,
category_id: i64,
info_hash: &str,
size: i64,
name: &str,
pieces: &str,
piece_length: i64,
private: bool,
root_hash: i64,
date_uploaded: &str,
) -> Result<i64, sqlx::Error> {
pub async fn insert_torrent(&self, torrent: &TorrentRecordV2) -> Result<i64, sqlx::Error> {
query(
"
INSERT INTO torrust_torrents (
Expand All @@ -163,17 +200,17 @@ impl SqliteDatabaseV2_0_0 {
date_uploaded
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
)
.bind(torrent_id)
.bind(uploader_id)
.bind(category_id)
.bind(info_hash)
.bind(size)
.bind(name)
.bind(pieces)
.bind(piece_length)
.bind(private)
.bind(root_hash)
.bind(date_uploaded)
.bind(torrent.torrent_id)
.bind(torrent.uploader_id)
.bind(torrent.category_id)
.bind(torrent.info_hash.clone())
.bind(torrent.size)
.bind(torrent.name.clone())
.bind(torrent.pieces.clone())
.bind(torrent.piece_length)
.bind(torrent.private)
.bind(torrent.root_hash)
.bind(torrent.date_uploaded.clone())
.execute(&self.pool)
.await
.map(|v| v.last_insert_rowid())
Expand All @@ -200,7 +237,7 @@ impl SqliteDatabaseV2_0_0 {

pub async fn insert_torrent_file_for_torrent_with_multiple_files(
&self,
torrent: &TorrentRecord,
torrent: &TorrentRecordV1,
file: &TorrentFile,
) -> Result<i64, sqlx::Error> {
query(
Expand All @@ -216,7 +253,7 @@ impl SqliteDatabaseV2_0_0 {
.map(|v| v.last_insert_rowid())
}

pub async fn insert_torrent_info(&self, torrent: &TorrentRecord) -> Result<i64, sqlx::Error> {
pub async fn insert_torrent_info(&self, torrent: &TorrentRecordV1) -> Result<i64, sqlx::Error> {
query(
"INSERT INTO torrust_torrent_info (torrent_id, title, description)
VALUES (?, ?, ?)",
Expand Down
36 changes: 8 additions & 28 deletions src/upgrades/from_v1_0_0_to_v2_0_0/upgrader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
//! - In v2, the table `torrust_user_profiles` contains two new fields: `bio` and `avatar`.
//! Empty string is used as default value.

use crate::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v2_0_0::SqliteDatabaseV2_0_0;
use crate::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v2_0_0::{
SqliteDatabaseV2_0_0, TorrentRecordV2,
};
use crate::utils::parse_torrent::decode_torrent;
use crate::{
models::torrent_file::Torrent,
upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v1_0_0::SqliteDatabaseV1_0_0,
};
use chrono::prelude::{DateTime, Utc};
use chrono::NaiveDateTime;

use std::{error, fs};
use std::{sync::Arc, time::SystemTime};
Expand Down Expand Up @@ -287,23 +288,13 @@ async fn transfer_torrents(

let torrent_from_file = read_torrent_from_file(&filepath).unwrap();

let pieces = torrent_from_file.info.get_pieces_as_string();
let root_hash = torrent_from_file.info.get_root_hash_as_i64();

let id = dest_database
.insert_torrent(
torrent.torrent_id,
uploader.user_id,
torrent.category_id,
&torrent_from_file.info_hash(),
torrent.file_size,
&torrent_from_file.info.name,
&pieces,
torrent_from_file.info.piece_length,
.insert_torrent(&TorrentRecordV2::from_v1_data(
torrent,
&torrent_from_file.info,
&uploader,
private,
root_hash,
&convert_timestamp_to_datetime(torrent.upload_date),
)
))
.await
.unwrap();

Expand Down Expand Up @@ -444,14 +435,3 @@ fn read_torrent_from_file(path: &str) -> Result<Torrent, Box<dyn error::Error>>
Err(e) => Err(e),
}
}

fn convert_timestamp_to_datetime(timestamp: i64) -> String {
// The expected format in database is: 2022-11-04 09:53:57
// MySQL uses a DATETIME column and SQLite uses a TEXT column.

let naive_datetime = NaiveDateTime::from_timestamp(timestamp, 0);
let datetime_again: DateTime<Utc> = DateTime::from_utc(naive_datetime, Utc);

// Format without timezone
datetime_again.format("%Y-%m-%d %H:%M:%S").to_string()
}

0 comments on commit 6bb4c53

Please sign in to comment.