feat(blog) add meta to get_post

This commit is contained in:
lumither committed 2024-07-23 02:49:16 +08:00
1 parent ee413c5dee
commit 91ad20215a
4 files changed
+61 -70

No files matched your search

+51 -63
View File
@@ -5,8 +5,7 @@ use axum::{
http::StatusCode, http::StatusCode,
Json, Json,
}; };
use chrono::{DateTime, Utc}; use serde_json::{json, Value};
use serde_json::{json, Map, Value};
use sqlx::{Error, PgPool, query, Row}; use sqlx::{Error, PgPool, query, Row};
use tracing::error; use tracing::error;
use uuid::Uuid; use uuid::Uuid;
@@ -24,16 +23,16 @@ pub async fn get_post(
e.to_string() e.to_string()
); );
return Err(( return Err((
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::BAD_REQUEST,
Json::from(json!(("error", e.to_string()))), Json::from(json!(("error", e.to_string()))),
)); ));
} }
}; };
let meta = match query( let post = match query(
r#" r#"
SELECT * SELECT jsonb_strip_nulls(to_jsonb(t.*)) - 'post_id' AS post
FROM Post FROM post t
WHERE post_id = $1; WHERE post_id = $1;
"#, "#,
) )
@@ -41,84 +40,73 @@ WHERE post_id = $1;
.fetch_one(&db_connection) .fetch_one(&db_connection)
.await .await
{ {
Ok(value) => value, Ok(value) => value.get::<Value, _>("post"),
Err(e) => { Err(e) => {
error!("Database query error on fetching meta: {}", e.to_string()); error!(
"Database error on Reading `base post information` from table `post`: <{}>: {}",
post_id.to_string(),
e.to_string()
);
return match e { return match e {
Error::RowNotFound => Err(( Error::RowNotFound => Err((
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
Json::from(json!(format!("{{error: {}}}", e.to_string()))), Json::from(json!({"error": e.to_string()})),
)), )),
_ => Err(( _ => Err((
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
Json::from(json!(format!("{{error: {}}}", e.to_string()))), Json::from(json!({"error": e.to_string()})),
)), )),
}; };
} }
}; };
let tags = query( let tags: Vec<_> = match query("SELECT tag FROM Tag WHERE post_id = $1;")
r#"
SELECT tag FROM Tag WHERE post_id = $1;
"#,
)
.bind(post_id) .bind(post_id)
.fetch_all(&db_connection) .fetch_all(&db_connection)
.await; .await
let tags = match tags { {
Ok(tags) => tags, Ok(tags) => tags.iter().map(|tag| tag.get::<String, _>("tag")).collect(),
Err(e) => { Err(e) => {
error!("Database query error :{}", e.to_string()); error!("Database query error :{}", e.to_string());
return Err(( return Err((
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
Json::from(json!(("error", e.to_string()))), Json::from(json!({"error": e.to_string()})),
)); ));
} }
}; };
let mut res = Map::new(); let meta = match query(
r#"
res.insert( SELECT jsonb_strip_nulls(to_jsonb(t.*)) - 'post_id' AS meta
"title".to_string(), FROM meta t
json!(meta.get::<String, &str>("title")), WHERE post_id = $1;
"#,
)
.bind(post_id)
.fetch_one(&db_connection)
.await
{
Ok(value) => value.get::<Value, _>("meta"),
Err(e) => {
error!(
"Database error on Reading `{}` from table `{}`: <{}>: {}",
"post meta data",
"meta",
post_id.to_string(),
e.to_string()
); );
res.insert( return Err((
"sub_title".to_string(), StatusCode::INTERNAL_SERVER_ERROR,
json!(meta.get::<String, &str>("sub_title")), Json::from(json!({"error": e.to_string()})),
); ));
res.insert( }
"category".to_string(), };
json!(meta.get::<String, &str>("category")),
); // todo: next, prev post
res.insert(
"header_img".to_string(), let mut res = post.as_object().unwrap().to_owned();
json!(meta.get::<String, &str>("header_img")), res.insert("tags".to_string(), tags.into());
); res.insert("meta".to_string(), meta.into());
res.insert(
"summary".to_string(), Ok(Json::from(json!(res)))
json!(meta.get::<String, &str>("summary")),
);
res.insert(
"content".to_string(),
json!(meta.get::<String, &str>("content")),
);
res.insert(
"last_update".to_string(),
json!(meta.get::<DateTime<Utc>, &str>("last_update")),
);
res.insert(
"first_update".to_string(),
json!(meta.get::<DateTime<Utc>, &str>("first_update")),
);
let tags: Vec<String> = tags
.iter()
.map(|tag| {
let tag: String = tag.get("tag");
tag
})
.collect();
res.insert("tags".to_string(), Value::from(tags));
Ok(Json::from(Value::from(res)))
} }
+1 -2
View File
@@ -1,5 +1,4 @@
use axum::{extract::State, http::StatusCode, Json}; use axum::{extract::Query, extract::State, http::StatusCode, Json};
use axum::extract::Query;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use futures::future::join_all; use futures::future::join_all;
use serde::Deserialize; use serde::Deserialize;
+1 -1
View File
@@ -46,7 +46,7 @@ pub enum PostIdxError {
}, },
#[error( #[error(
"Database error on Reading `{}` to table `{}`: <{}>: {}", "Database error on Reading `{}` from table `{}`: <{}>: {}",
data_desc, data_desc,
db_table, db_table,
id, id,
+8 -4
View File
@@ -1,5 +1,4 @@
use base64::Engine; use base64::{Engine, engine::general_purpose};
use base64::engine::general_purpose;
use chrono::DateTime; use chrono::DateTime;
use serde_json::{Map, Value}; use serde_json::{Map, Value};
use sqlx::{PgPool, query, Row}; use sqlx::{PgPool, query, Row};
@@ -218,7 +217,7 @@ pub async fn meta(db_connection: &PgPool, post_id: Uuid, meta: &Value) -> Result
loop { loop {
if let Err(e) = query( if let Err(e) = query(
format!( format!(
r" r#"
DO DO
$$ $$
DECLARE DECLARE
@@ -231,11 +230,16 @@ $$
_insert_columns TEXT := 'post_id'; _insert_columns TEXT := 'post_id';
_insert_values TEXT := quote_literal(_post_id); _insert_values TEXT := quote_literal(_post_id);
_update_set TEXT := ''; _update_set TEXT := '';
_blacklist TEXT[] := ARRAY['id', 'tags'];
BEGIN BEGIN
SELECT EXISTS(SELECT 1 FROM meta WHERE post_id = _post_id) INTO _exists; SELECT EXISTS(SELECT 1 FROM meta WHERE post_id = _post_id) INTO _exists;
FOR _col_name, _col_value IN SELECT key, value FROM jsonb_each_text(_meta_cols) FOR _col_name, _col_value IN SELECT key, value FROM jsonb_each_text(_meta_cols)
LOOP LOOP
IF _col_name = ANY(_blacklist) THEN
CONTINUE;
END IF;
IF NOT EXISTS (SELECT 1 IF NOT EXISTS (SELECT 1
FROM information_schema.columns FROM information_schema.columns
WHERE table_name = 'meta' WHERE table_name = 'meta'
@@ -261,7 +265,7 @@ $$
END IF; END IF;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
", post_id.to_string().as_str(), meta.to_string() "#, post_id.to_string().as_str(), meta.to_string()
).as_str() ).as_str()
) )
.execute(db_connection) .execute(db_connection)