From ee413c5dee67ee1b7ff9e05435913ec6ecc45531 Mon Sep 17 00:00:00 2001 From: Lumither Tao Date: Mon, 22 Jul 2024 21:33:20 +0800 Subject: [PATCH] feat(blog) add pagination for get_post_list --- backend/src/api/get/get_post_list.rs | 72 +++++++++++++++------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/backend/src/api/get/get_post_list.rs b/backend/src/api/get/get_post_list.rs index af1dcc4..f4b87a5 100644 --- a/backend/src/api/get/get_post_list.rs +++ b/backend/src/api/get/get_post_list.rs @@ -1,17 +1,29 @@ use axum::{extract::State, http::StatusCode, Json}; +use axum::extract::Query; use chrono::{DateTime, Utc}; use futures::future::join_all; +use serde::Deserialize; use serde_json::{json, Map, Value}; -use sqlx::{postgres::PgRow, query, PgPool, Row}; +use sqlx::{PgPool, postgres::PgRow, query, Row}; use tracing::error; use uuid::Uuid; +#[derive(Deserialize)] +pub struct Params { + page: Option, +} + +const PAGE_SIZE: u32 = 6; + pub async fn get_post_list( State(db_connection): State, + Query(params): Query, ) -> Result, (StatusCode, Json)> { - let post_list = sqlx::query( - "select post_id, title, sub_title, summary, last_update, first_update, header_img, category from post", - ) + let offset = PAGE_SIZE * (params.page.unwrap_or(1) - 1); + + let post_list = sqlx::query("SELECT * FROM post ORDER BY first_update DESC LIMIT $1 OFFSET $2") + .bind(PAGE_SIZE as i32) + .bind(offset as i32) .fetch_all(&db_connection) .await; let post_list = match post_list { @@ -41,35 +53,29 @@ pub async fn get_post_list( } async fn analyze_post(db_connection: &PgPool, post: PgRow) -> Value { - let mut tmp = Map::new(); let post_id: Uuid = post.get("post_id"); - let title: String = post.get("title"); - let category: String = post.get("category"); - let header_img: String = post.get("header_img"); - let sub_title: String = post.get("sub_title"); - let summary: String = post.get("summary"); - let last_update: DateTime = post.get("last_update"); - let first_update: DateTime = post.get("first_update"); + let tags = fetch_post_tags(db_connection, post_id).await; - let tags_future = query("SELECT tag FROM Tag WHERE post_id = $1") - .bind(post_id) - .fetch_all(db_connection); - let tags: Vec = match tags_future.await { - Ok(res) => res.iter().map(|tag| tag.get::("tag")).collect(), - Err(_) => { - vec![] - } - }; - - tmp.insert("post_id".to_string(), json!(post_id.to_string())); - tmp.insert("title".to_string(), json!(title)); - tmp.insert("category".to_string(), json!(category)); - tmp.insert("header_img".to_string(), json!(header_img)); - tmp.insert("sub_title".to_string(), json!(sub_title)); - tmp.insert("summary".to_string(), json!(summary)); - tmp.insert("last_update".to_string(), json!(last_update)); - tmp.insert("first_update".to_string(), json!(first_update)); - tmp.insert("tags".to_string(), json!(tags)); - - Value::from(tmp) + json!({ + "post_id": post_id.to_string(), + "title": post.get::("title"), + "category": post.get::("category"), + "header_img": post.get::("header_img"), + "sub_title": post.get::("sub_title"), + "summary": post.get::("summary"), + "last_update": post.get::, _>("last_update"), + "first_update": post.get::, _>("first_update"), + "tags": tags, + }) +} + +async fn fetch_post_tags(db_connection: &PgPool, post_id: Uuid) -> Vec { + match query("SELECT tag FROM Tag WHERE post_id = $1") + .bind(post_id) + .fetch_all(db_connection) + .await + { + Ok(res) => res.iter().map(|tag| tag.get::("tag")).collect(), + Err(_) => vec![], + } }