From 696af52b9b3a732b369a771e1f6409d8e2049ea9 Mon Sep 17 00:00:00 2001 From: WriterV2 Date: Wed, 6 Nov 2024 18:19:31 +0100 Subject: Refactoring: Add product post method --- src/db/product.rs | 19 +++++++++++++++- src/db/story.rs | 66 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 31 deletions(-) (limited to 'src/db') diff --git a/src/db/product.rs b/src/db/product.rs index 0fc8f05..5b58560 100644 --- a/src/db/product.rs +++ b/src/db/product.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; +use std::time::SystemTime; -use sqlx::SqlitePool; +use sqlx::{Sqlite, SqlitePool, Transaction}; use crate::error::AppError; @@ -15,6 +16,22 @@ pub struct Product { pub updatedate: i64, } +impl Product { + pub async fn post(tx: &mut Transaction<'static, Sqlite>, name: String, description: String) -> Result { + let now = SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64; + let product = sqlx::query_as!( + Product, + "INSERT INTO product (name, description, uploaddate, updatedate) VALUES ($1, $2, $3, $4) RETURNING id, name, description, uploaddate, updatedate", + name, + description, + now, + now) + .fetch_one(&mut **tx) + .await?; + Ok(product) + } +} + pub trait ProductMarker { fn product_id(&self) -> i64; } diff --git a/src/db/story.rs b/src/db/story.rs index 4228e80..b77d7a3 100644 --- a/src/db/story.rs +++ b/src/db/story.rs @@ -7,14 +7,13 @@ use axum::async_trait; use maud::html; use sqlx::SqlitePool; -use crate::error::AppError; use crate::db::product::Product; +use crate::error::AppError; use crate::handlers::frontend_builder::PageBuilder; use super::product::ProductMarker; use super::ProductDatabaseHandler; - #[derive(Debug, serde::Serialize, sqlx::FromRow)] pub struct Story { pub id: i64, @@ -33,19 +32,32 @@ impl ProductMarker for Story { pub async fn synchronize_story_files(pool: &SqlitePool) -> Result<(), anyhow::Error> { for entry in read_dir("static").with_context(|| "Failed to read directory")? { let path = entry.with_context(|| "Failed to get entry")?.path(); - if path.extension().is_some_and(|ext| ext == OsStr::new("pdf") || ext == OsStr::new("epub")) { + if path + .extension() + .is_some_and(|ext| ext == OsStr::new("pdf") || ext == OsStr::new("epub")) + { remove_file(path).with_context(|| "Failed to remove file")?; } } - let results = sqlx::query!("SELECT p.name, s.pdf, s.epub FROM story s INNER JOIN product p ON s.pid = p.id").fetch_all(pool).await?; + let results = sqlx::query!( + "SELECT p.name, s.pdf, s.epub FROM story s INNER JOIN product p ON s.pid = p.id" + ) + .fetch_all(pool) + .await?; for result in results.iter() { let pdf_filename = format_filepath(&result.name, "pdf"); - let file = std::fs::File::create_new(&pdf_filename).with_context(|| format!("Failed to create {}", &pdf_filename))?; - BufWriter::new(file).write_all(&result.pdf.to_vec()).with_context(|| format!("Failed to write {}", &pdf_filename))?; + let file = std::fs::File::create_new(&pdf_filename) + .with_context(|| format!("Failed to create {}", &pdf_filename))?; + BufWriter::new(file) + .write_all(&result.pdf.to_vec()) + .with_context(|| format!("Failed to write {}", &pdf_filename))?; let epub_filename = format_filepath(&result.name, "epub"); - let file = std::fs::File::create_new(&epub_filename).with_context(|| format!("Failed to create {}", &epub_filename))?; - BufWriter::new(file).write_all(&result.epub.to_vec()).with_context(|| format!("Failed to write {}", &epub_filename))?; + let file = std::fs::File::create_new(&epub_filename) + .with_context(|| format!("Failed to create {}", &epub_filename))?; + BufWriter::new(file) + .write_all(&result.epub.to_vec()) + .with_context(|| format!("Failed to write {}", &epub_filename))?; } Ok(()) } @@ -61,24 +73,17 @@ impl ProductDatabaseHandler for Story { .await?) } - async fn post(&self, pool: &SqlitePool, name: String, description: String) -> Result + async fn post( + &self, + pool: &SqlitePool, + name: String, + description: String, + ) -> Result where Self: Sized, { - let time = std::time::SystemTime::now(); - let uploaddate = time.duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64; - let mut tx = pool.begin().await?; - let product = sqlx::query_as!( - Product, - "INSERT INTO product (name, description, uploaddate, updatedate) VALUES ($1, $2, $3, $4) RETURNING id, name, description, uploaddate, updatedate", - name, - description, - uploaddate, - uploaddate) - .fetch_one(&mut *tx) - .await?; - + let product = Product::post(&mut tx, name, description).await?; let story = sqlx::query_as!( Story, "INSERT INTO story (language, pdf, epub, pid) VALUES ($1, $2, $3, $4) RETURNING id, language, pdf, epub, pid", @@ -96,14 +101,16 @@ impl ProductDatabaseHandler for Story { } impl PageBuilder for Story { - fn page_title() -> String { + fn page_title() -> String { "Stories".to_string() - } + } - // TODO: Add pdf and epub icons - fn product_specific_card_content - (&self, specific_product: &super::product::SpecificProduct) -> maud::Markup { - html!( + // TODO: Add pdf and epub icons + fn product_specific_card_content( + &self, + specific_product: &super::product::SpecificProduct, + ) -> maud::Markup { + html!( div class="flex justify-start mt-5 text-sm" { span class="mr-10" { (&self.language) } div class="flex justify-between" { @@ -112,7 +119,7 @@ impl PageBuilder for Story { } } ) - } + } } pub fn format_filepath(name: &str, extension: &str) -> String { @@ -120,4 +127,3 @@ pub fn format_filepath(name: &str, extension: &str) -> String { filename.retain(|c| !c.is_whitespace()); filename } - -- cgit v1.2.3