Migrate product photo db
This commit is contained in:
parent
500dac9b2e
commit
e426fd5f31
@ -1 +1,192 @@
|
||||
use db_utils::PgT;
|
||||
use model::v2::*;
|
||||
|
||||
use crate::db::products::AllProducts;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("Failed to attach photo to product")]
|
||||
Create,
|
||||
#[error("Failed to load all product photos")]
|
||||
All,
|
||||
#[error("Failed to delete product photo {0:?}")]
|
||||
Delete(ProductPhotoId),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AllProductPhotos {
|
||||
pub limit: Option<i32>,
|
||||
pub offset: Option<i32>,
|
||||
}
|
||||
|
||||
impl AllProductPhotos {
|
||||
pub async fn run(self, pool: &mut PgT<'_>) -> Result<Vec<ProductPhoto>> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
SELECT id, product_variant_id, photo_id
|
||||
FROM product_photos
|
||||
ORDER BY id ASC
|
||||
LIMIT $1 OFFSET $2
|
||||
"#,
|
||||
)
|
||||
.bind(self.limit)
|
||||
.bind(self.offset)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
Error::All
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CreateProductPhoto {
|
||||
pub product_variant_id: ProductVariantId,
|
||||
pub photo_id: PhotoId,
|
||||
}
|
||||
|
||||
impl CreateProductPhoto {
|
||||
pub async fn run(self, pool: &mut PgT<'_>) -> Result<ProductPhoto> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
INSERT INTO product_photos(product_variant_id, photo_id)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id, product_variant_id, photo_id
|
||||
"#,
|
||||
)
|
||||
.bind(self.product_variant_id)
|
||||
.bind(self.photo_id)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{:?}", e);
|
||||
Error::Create
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeleteProductPhoto {
|
||||
pub id: ProductPhotoId,
|
||||
}
|
||||
|
||||
impl DeleteProductPhoto {
|
||||
pub async fn run(self, pool: &mut PgT<'_>) -> Result<Option<ProductPhoto>> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
DELETE FROM product_photos
|
||||
WHERE id = $1
|
||||
RETURNING id, product_variant_id, photo_id
|
||||
"#,
|
||||
)
|
||||
.bind(self.id)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{:?}", e);
|
||||
Error::Delete(self.id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use config::UpdateConfig;
|
||||
use model::v2::*;
|
||||
use model::Day;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::product_variants::CreateProductVariant;
|
||||
|
||||
pub struct NoOpts;
|
||||
|
||||
impl UpdateConfig for NoOpts {}
|
||||
|
||||
use super::*;
|
||||
use crate::db::products::*;
|
||||
|
||||
async fn test_product(t: &mut PgT<'_>) -> Product {
|
||||
CreateProduct {
|
||||
name: ProductName::new(format!("{}", Uuid::new_v4())),
|
||||
category: None,
|
||||
deliver_days_flag: Days(vec![Day::Friday, Day::Sunday]),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_variant(product_id: ProductId, t: &mut PgT<'_>) -> ProductVariant {
|
||||
CreateProductVariant {
|
||||
product_id,
|
||||
name: ProductName::new(format!("{}", Uuid::new_v4())),
|
||||
short_description: ProductShortDesc::new("ajs9d8ua9sdu9ahsd98has"),
|
||||
long_description: ProductLongDesc::new("hja89sdy9yha9sdy98ayusd9hya9sy8dh"),
|
||||
price: Default::default(),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_photo(t: &mut PgT<'_>) -> Photo {
|
||||
CreatePhoto {
|
||||
local_path: LocalPath::new(format!("{}", Uuid::new_v4())),
|
||||
file_name: FileName::new(format!("{}", Uuid::new_v4())),
|
||||
unique_name: UniqueName::new(format!("{}", Uuid::new_v4())),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_photo(t: &mut PgT<'_>) -> ProductPhoto {
|
||||
let product = test_product(t).await;
|
||||
let product_variant = test_product_variant(product.id, t).await;
|
||||
let photo = test_photo(t).await;
|
||||
CreateProductPhoto {
|
||||
product_variant_id: product_variant.id,
|
||||
photo_id: photo.id,
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[actix::test]
|
||||
async fn create_photo() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
test_product_photo(&mut t).await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
}
|
||||
|
||||
#[actix::test]
|
||||
async fn delete() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let p1 = test_product_photo(&mut t).await;
|
||||
let p2 = test_product_photo(&mut t).await;
|
||||
let p3 = test_product_photo(&mut t).await;
|
||||
|
||||
let deleted = DeleteProductPhoto { id: p2.id }.run(&mut t).await.unwrap();
|
||||
|
||||
testx::db_rollback!(t);
|
||||
assert_ne!(deleted, Some(p1));
|
||||
assert_eq!(deleted, Some(p2));
|
||||
assert_ne!(deleted, Some(p3));
|
||||
}
|
||||
|
||||
#[actix::test]
|
||||
async fn create() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
test_product_photo(&mut t).await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ pub struct AllProducts {
|
||||
}
|
||||
|
||||
impl AllProducts {
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<Vec<model::Product>>
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<Vec<Product>>
|
||||
where
|
||||
E: sqlx::Executor<'e, Database = sqlx::Postgres>,
|
||||
{
|
||||
@ -60,7 +60,7 @@ pub struct FindProduct {
|
||||
}
|
||||
|
||||
impl FindProduct {
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<model::Product>
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<Product>
|
||||
where
|
||||
E: sqlx::Executor<'e, Database = sqlx::Postgres>,
|
||||
{
|
||||
@ -92,7 +92,7 @@ pub struct CreateProduct {
|
||||
}
|
||||
|
||||
impl CreateProduct {
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<model::Product>
|
||||
pub async fn run<'e, E>(self, pool: E) -> Result<Product>
|
||||
where
|
||||
E: sqlx::Executor<'e, Database = sqlx::Postgres>,
|
||||
{
|
||||
@ -264,7 +264,7 @@ WHERE
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use config::UpdateConfig;
|
||||
use model::*;
|
||||
use model::v2::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct NoOpts;
|
||||
|
Loading…
Reference in New Issue
Block a user