mirror of
https://github.com/Lumither/nocturne.git
synced 2026-10-17 10:26:21 +00:00
feat(blog) add meta to get_post
This commit is contained in:
4 files changed
+75
-84
No files matched your search
@@ -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,101 +23,90 @@ 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 post = match query(
|
||||||
|
r#"
|
||||||
|
SELECT jsonb_strip_nulls(to_jsonb(t.*)) - 'post_id' AS post
|
||||||
|
FROM post t
|
||||||
|
WHERE post_id = $1;
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(post_id)
|
||||||
|
.fetch_one(&db_connection)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(value) => value.get::<Value, _>("post"),
|
||||||
|
Err(e) => {
|
||||||
|
error!(
|
||||||
|
"Database error on Reading `base post information` from table `post`: <{}>: {}",
|
||||||
|
post_id.to_string(),
|
||||||
|
e.to_string()
|
||||||
|
);
|
||||||
|
return match e {
|
||||||
|
Error::RowNotFound => Err((
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
Json::from(json!({"error": e.to_string()})),
|
||||||
|
)),
|
||||||
|
_ => Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Json::from(json!({"error": e.to_string()})),
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let tags: Vec<_> = match query("SELECT tag FROM Tag WHERE post_id = $1;")
|
||||||
|
.bind(post_id)
|
||||||
|
.fetch_all(&db_connection)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(tags) => tags.iter().map(|tag| tag.get::<String, _>("tag")).collect(),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Database query error :{}", e.to_string());
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Json::from(json!({"error": e.to_string()})),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let meta = match query(
|
let meta = match query(
|
||||||
r#"
|
r#"
|
||||||
SELECT *
|
SELECT jsonb_strip_nulls(to_jsonb(t.*)) - 'post_id' AS meta
|
||||||
FROM Post
|
FROM meta t
|
||||||
WHERE post_id = $1;
|
WHERE post_id = $1;
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(post_id)
|
.bind(post_id)
|
||||||
.fetch_one(&db_connection)
|
.fetch_one(&db_connection)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value.get::<Value, _>("meta"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Database query error on fetching meta: {}", e.to_string());
|
error!(
|
||||||
return match e {
|
"Database error on Reading `{}` from table `{}`: <{}>: {}",
|
||||||
Error::RowNotFound => Err((
|
"post meta data",
|
||||||
StatusCode::BAD_REQUEST,
|
"meta",
|
||||||
Json::from(json!(format!("{{error: {}}}", e.to_string()))),
|
post_id.to_string(),
|
||||||
)),
|
e.to_string()
|
||||||
_ => Err((
|
);
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
|
||||||
Json::from(json!(format!("{{error: {}}}", e.to_string()))),
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let tags = query(
|
|
||||||
r#"
|
|
||||||
SELECT tag FROM Tag WHERE post_id = $1;
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.bind(post_id)
|
|
||||||
.fetch_all(&db_connection)
|
|
||||||
.await;
|
|
||||||
let tags = match tags {
|
|
||||||
Ok(tags) => tags,
|
|
||||||
Err(e) => {
|
|
||||||
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();
|
// todo: next, prev post
|
||||||
|
|
||||||
res.insert(
|
let mut res = post.as_object().unwrap().to_owned();
|
||||||
"title".to_string(),
|
res.insert("tags".to_string(), tags.into());
|
||||||
json!(meta.get::<String, &str>("title")),
|
res.insert("meta".to_string(), meta.into());
|
||||||
);
|
|
||||||
res.insert(
|
|
||||||
"sub_title".to_string(),
|
|
||||||
json!(meta.get::<String, &str>("sub_title")),
|
|
||||||
);
|
|
||||||
res.insert(
|
|
||||||
"category".to_string(),
|
|
||||||
json!(meta.get::<String, &str>("category")),
|
|
||||||
);
|
|
||||||
res.insert(
|
|
||||||
"header_img".to_string(),
|
|
||||||
json!(meta.get::<String, &str>("header_img")),
|
|
||||||
);
|
|
||||||
res.insert(
|
|
||||||
"summary".to_string(),
|
|
||||||
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
|
Ok(Json::from(json!(res)))
|
||||||
.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,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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in new issue
Block a user