summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db/mod.rs1
-rw-r--r--src/db/product.rs24
-rw-r--r--src/db/producttag.rs2
-rw-r--r--src/db/story.rs3
-rw-r--r--src/handlers/admin.rs11
5 files changed, 36 insertions, 5 deletions
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 7050527..e44c9ad 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -21,6 +21,7 @@ pub trait ProductDatabaseHandler {
pool: &SqlitePool,
name: String,
description: String,
+ tags: Vec<String>,
) -> Result<Self, AppError>
where
Self: Sized;
diff --git a/src/db/product.rs b/src/db/product.rs
index 5b58560..06217c0 100644
--- a/src/db/product.rs
+++ b/src/db/product.rs
@@ -1,10 +1,12 @@
use std::collections::HashMap;
use std::time::SystemTime;
-use sqlx::{Sqlite, SqlitePool, Transaction};
+use sqlx::{QueryBuilder, Sqlite, SqlitePool, Transaction};
use crate::error::AppError;
+use super::producttag::ProductTag;
+use super::tag::Tag;
use super::ProductDatabaseHandler;
#[derive(Debug, serde::Serialize, sqlx::FromRow)]
@@ -17,7 +19,7 @@ pub struct Product {
}
impl Product {
- pub async fn post(tx: &mut Transaction<'static, Sqlite>, name: String, description: String) -> Result<Product, AppError> {
+ pub async fn post(tx: &mut Transaction<'static, Sqlite>, name: String, description: String, tags: Vec<String>) -> Result<Product, AppError> {
let now = SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64;
let product = sqlx::query_as!(
Product,
@@ -28,6 +30,24 @@ impl Product {
now)
.fetch_one(&mut **tx)
.await?;
+
+ if !tags.is_empty() {
+ let mut tags_query_builder: QueryBuilder<Sqlite> = QueryBuilder::new("INSERT INTO tag (name) ");
+ tags_query_builder.push_values(tags.iter(), | mut b, tag | { b.push_bind(tag); });
+ tags_query_builder.push(" RETURNING id, name;");
+ let added_tags: Vec<Tag> = tags_query_builder
+ .build_query_as::<Tag>()
+ .fetch_all(&mut **tx)
+ .await?;
+
+ let mut producttags_query_builder: QueryBuilder<Sqlite> = QueryBuilder::new("INSERT INTO producttag (pid, tid) ");
+ producttags_query_builder.push_values(added_tags.iter(), | mut b, added_tag | {
+ b.push_bind(product.id).push_bind(added_tag.id);
+ });
+ producttags_query_builder
+ .build().execute(&mut **tx).await?;
+
+ }
Ok(product)
}
}
diff --git a/src/db/producttag.rs b/src/db/producttag.rs
index b3091c3..160e720 100644
--- a/src/db/producttag.rs
+++ b/src/db/producttag.rs
@@ -1,5 +1,5 @@
#[derive(Debug, serde::Serialize, sqlx::FromRow)]
-pub struct Storytag {
+pub struct ProductTag {
pub pid: i64,
pub tid: i64,
}
diff --git a/src/db/story.rs b/src/db/story.rs
index b77d7a3..137c964 100644
--- a/src/db/story.rs
+++ b/src/db/story.rs
@@ -78,12 +78,13 @@ impl ProductDatabaseHandler for Story {
pool: &SqlitePool,
name: String,
description: String,
+ tags: Vec<String>,
) -> Result<Self, AppError>
where
Self: Sized,
{
let mut tx = pool.begin().await?;
- let product = Product::post(&mut tx, name, description).await?;
+ let product = Product::post(&mut tx, name, description, tags).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",
diff --git a/src/handlers/admin.rs b/src/handlers/admin.rs
index a48be21..7c016dd 100644
--- a/src/handlers/admin.rs
+++ b/src/handlers/admin.rs
@@ -112,6 +112,13 @@ pub async fn upload_story(
return Ok(StatusCode::BAD_REQUEST.into_response());
};
+ let mut tags: Vec<String> = Vec::new();
+ if let Some(tags_value) = form.get("tag") {
+ for tag in String::from_utf8(tags_value.to_vec())?.split(",") {
+ tags.push(tag.trim().to_string());
+ }
+ }
+
let story_template = Story {
id: 0,
pid: 0,
@@ -120,6 +127,8 @@ pub async fn upload_story(
epub,
};
- let story = story_template.post(&ctx.pool, name, description).await?;
+ let story = story_template
+ .post(&ctx.pool, name, description, tags)
+ .await?;
Ok((StatusCode::CREATED, Json(story)).into_response())
}