diff --git a/backend/public/src/datasources/authors.rs b/backend/public/src/datasources/authors.rs index c263f96..fb1f17b 100644 --- a/backend/public/src/datasources/authors.rs +++ b/backend/public/src/datasources/authors.rs @@ -1,2 +1,31 @@ +use sqlx::{Pool, Postgres}; + +use crate::routes::{authors::Author, comments::Pagination}; + pub struct AuthorsDatasource; -impl AuthorsDatasource {} +impl AuthorsDatasource { + pub async fn get_all( + pool: &Pool, + pagination: Pagination, + ) -> Result, sqlx::Error> { + let offset: i64 = (pagination.page_number - 1) * pagination.page_size; + sqlx::query_as!( + Author, + "SELECT author_id, first_name, last_name, bio FROM authors ORDER BY created_at DESC LIMIT $1 OFFSET $2", + pagination.page_size, + offset, + ) + .fetch_all(pool) + .await + } + + pub async fn get_one(pool: &Pool, author_id: i32) -> Result { + sqlx::query_as!( + Author, + "SELECT author_id, first_name, last_name, bio FROM authors WHERE author_id = $1", + author_id + ) + .fetch_one(pool) + .await + } +} diff --git a/backend/public/src/datasources/comments.rs b/backend/public/src/datasources/comments.rs index a2c2194..bd88ea9 100644 --- a/backend/public/src/datasources/comments.rs +++ b/backend/public/src/datasources/comments.rs @@ -1,4 +1,4 @@ -use crate::routes::comments::{Comment, CommentInputPayload}; +use crate::routes::comments::{Comment, CommentInputPayload, Pagination}; use sqlx::{Pool, Postgres}; pub struct CommentsDatasource; @@ -11,12 +11,23 @@ impl CommentsDatasource { .fetch_all(pool) .await } + pub async fn insert_comment( pool: &Pool, comment_input: CommentInputPayload, ) -> Result { - sqlx::query!("INSERT INTO comments (post_id, name, body) VALUES ($1, $2, $3) RETURNING comment_id, name, body, created_at", comment_input.post_id, comment_input.name, comment_input.body) + sqlx::query_as!(Comment, "INSERT INTO comments (post_id, name, body) VALUES ($1, $2, $3) RETURNING comment_id, name, body, created_at", comment_input.post_id, comment_input.name, comment_input.body) .fetch_one(pool) .await } + + pub async fn get_index_comments( + pool: &Pool, + pagination: Pagination, + ) -> Result, sqlx::Error> { + let offset: i64 = (pagination.page_number - 1) * pagination.page_size; + sqlx::query_as!(Comment, "SELECT comment_id, name, body, created_at FROM comments ORDER BY created_at DESC LIMIT $1 OFFSET $2", pagination.page_size, offset) + .fetch_all(pool) + .await + } } diff --git a/backend/public/src/routes/authors.rs b/backend/public/src/routes/authors.rs index 389b26a..903dabe 100644 --- a/backend/public/src/routes/authors.rs +++ b/backend/public/src/routes/authors.rs @@ -1,2 +1,56 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + routing::get, + Json, +}; +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres}; + +use crate::{datasources::authors::AuthorsDatasource, AppState}; + +use super::comments::Pagination; + +#[derive(Serialize)] +pub struct Author { + pub author_id: i32, + pub first_name: String, + pub last_name: String, + pub bio: Option, +} + +#[derive(Deserialize)] +pub struct AuthorGetOneParams { + pub id: i32, +} + pub struct AuthorsRoute; -impl AuthorsRoute {} +impl AuthorsRoute { + pub fn routes(app_state: &AppState) -> axum::Router { + axum::Router::new() + .route("/", get(AuthorsRoute::get_all)) + .route("/:id", get(AuthorsRoute::get_one)) + .with_state(app_state.db.clone()) + } + + async fn get_all( + State(pool): State>, + Json(pagination): Json, + ) -> impl IntoResponse { + match AuthorsDatasource::get_all(&pool, pagination).await { + Ok(a) => Ok(Json(a)), + Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), + } + } + + async fn get_one( + State(pool): State>, + Path(params): Path, + ) -> impl IntoResponse { + match AuthorsDatasource::get_one(&pool, params.id).await { + Ok(a) => Ok(Json(a)), + Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), + } + } +} diff --git a/backend/public/src/routes/comments.rs b/backend/public/src/routes/comments.rs index 845c25b..53b26df 100644 --- a/backend/public/src/routes/comments.rs +++ b/backend/public/src/routes/comments.rs @@ -1,7 +1,7 @@ use super::posts::serialize_datetime; use crate::{datasources::comments::CommentsDatasource, AppState}; use axum::{ - extract::{Form, Path, State}, + extract::{Path, State}, http::StatusCode, response::IntoResponse, routing::{get, post}, @@ -23,6 +23,12 @@ pub struct CommentPathParams { id: i32, } +#[derive(Deserialize)] +pub struct Pagination { + pub page_number: i64, + pub page_size: i64, +} + #[derive(sqlx::FromRow, Serialize, Debug)] pub struct Comment { pub comment_id: i32, @@ -39,6 +45,7 @@ impl CommentsRoute { axum::Router::new() .route("/post/:id", get(CommentsRoute::get_post_comments)) .route("/add", post(CommentsRoute::insert_comment)) + .route("/index", get(CommentsRoute::get_comments_index)) .with_state(app_state.db.clone()) } @@ -54,11 +61,21 @@ impl CommentsRoute { // async fn insert_comment( State(pool): State>, - Json(comment_input): Json, + Json(input): Json, ) -> impl IntoResponse { - match CommentsDatasource::insert_comment(&pool, comment_input).await { + match CommentsDatasource::insert_comment(&pool, input).await { Ok(c) => Ok((StatusCode::CREATED, Json(c))), Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), } } + + async fn get_comments_index( + State(pool): State>, + Json(pagination): Json, + ) -> impl IntoResponse { + match CommentsDatasource::get_index_comments(&pool, pagination).await { + Ok(c) => Ok(Json(c)), + Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())), + } + } }