From b988be7056fa5874d743fadee2db30a7ab6edcf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 16 Dec 2024 01:20:10 +0300 Subject: [PATCH] feat: :sparkles: post_interaction routing --- ...30240_create_post_interaction_table.up.sql | 4 +- ...48_create_comment_interaction_table.up.sql | 4 +- src/feature/comment_interaction.rs | 2 +- src/feature/post_interaction.rs | 51 ++++++- src/routing.rs | 5 + src/routing/post_interaction.rs | 125 ++++++++++++++++++ 6 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 src/routing/post_interaction.rs diff --git a/migrations/20241204230240_create_post_interaction_table.up.sql b/migrations/20241204230240_create_post_interaction_table.up.sql index d22e247..a028e2a 100644 --- a/migrations/20241204230240_create_post_interaction_table.up.sql +++ b/migrations/20241204230240_create_post_interaction_table.up.sql @@ -1,7 +1,7 @@ -- Add up migration script here CREATE TABLE IF NOT EXISTS "post_interaction"( + interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW(), post_creation_time TIMESTAMPTZ NOT NULL REFERENCES "post"(creation_time), user_id BIGSERIAL NOT NULL REFERENCES "user"(id), - interaction_id BIGSERIAL NOT NULL REFERENCES "interaction"(id), - interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW() + interaction_id BIGSERIAL NOT NULL REFERENCES "interaction"(id) ); \ No newline at end of file diff --git a/migrations/20241204230248_create_comment_interaction_table.up.sql b/migrations/20241204230248_create_comment_interaction_table.up.sql index 41f4aca..7839f08 100644 --- a/migrations/20241204230248_create_comment_interaction_table.up.sql +++ b/migrations/20241204230248_create_comment_interaction_table.up.sql @@ -1,7 +1,7 @@ -- Add up migration script here CREATE TABLE IF NOT EXISTS "comment_interaction"( + interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW(), comment_creation_time TIMESTAMPTZ NOT NULL REFERENCES "comment"(creation_time), user_id BIGSERIAL NOT NULL REFERENCES "user"(id), - interaction_id BIGSERIAL NOT NULL REFERENCES "interaction"(id), - interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW() + interaction_id BIGSERIAL NOT NULL REFERENCES "interaction"(id) ); \ No newline at end of file diff --git a/src/feature/comment_interaction.rs b/src/feature/comment_interaction.rs index 9e23627..d31b1e1 100644 --- a/src/feature/comment_interaction.rs +++ b/src/feature/comment_interaction.rs @@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub struct CommentInteraction { + pub interaction_time: DateTime, pub comment_creation_time: DateTime, pub interaction_id: i64, pub user_id: i64, - pub interaction_time: DateTime, } diff --git a/src/feature/post_interaction.rs b/src/feature/post_interaction.rs index 4c51fd4..82e63b7 100644 --- a/src/feature/post_interaction.rs +++ b/src/feature/post_interaction.rs @@ -1,10 +1,59 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres}; + +use crate::database::post_interaction; #[derive(Debug, Serialize, Deserialize)] pub struct PostInteraction { + pub interaction_time: DateTime, pub post_creation_time: DateTime, pub interaction_id: i64, pub user_id: i64, - pub interaction_time: DateTime, +} + +impl PostInteraction { + pub async fn create( + post_creation_time: &DateTime, + user_id: &i64, + interaction_id: &i64, + database_connection: &Pool, + ) -> Result { + post_interaction::create( + post_creation_time, + user_id, + interaction_id, + database_connection, + ) + .await + } + + pub async fn read( + interaction_time: &DateTime, + database_connection: &Pool, + ) -> Result { + post_interaction::read(interaction_time, database_connection).await + } + + pub async fn update( + interaction_time: &DateTime, + interaction_id: &i64, + database_connection: &Pool, + ) -> Result { + post_interaction::update(interaction_time, interaction_id, database_connection).await + } + + pub async fn delete( + interaction_time: &DateTime, + database_connection: &Pool, + ) -> Result { + post_interaction::delete(interaction_time, database_connection).await + } + + pub async fn read_all_for_post( + post_creation_time: &DateTime, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + post_interaction::read_all_for_post(post_creation_time, database_connection).await + } } diff --git a/src/routing.rs b/src/routing.rs index 6d12e1f..fd40c63 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -1,6 +1,7 @@ pub mod comment; pub mod interaction; pub mod post; +pub mod post_interaction; pub mod role; pub mod user; @@ -32,6 +33,10 @@ pub async fn route(State(app_state): State) -> Router { "/interactions", interaction::route(axum::extract::State(app_state.clone())), ) + .nest( + "/post_interactions", + post_interaction::route(axum::extract::State(app_state.clone())), + ) .layer(CorsLayer::permissive()) .with_state(app_state) } diff --git a/src/routing/post_interaction.rs b/src/routing/post_interaction.rs new file mode 100644 index 0000000..9a932a0 --- /dev/null +++ b/src/routing/post_interaction.rs @@ -0,0 +1,125 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + routing::{delete, get, patch, post}, + Json, Router, +}; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +use crate::{feature::post_interaction::PostInteraction, AppState}; + +#[derive(Debug, Serialize, Deserialize)] +struct CreatePostInteraction { + pub post_creation_time: DateTime, + pub interaction_id: i64, + pub user_id: i64, +} + +#[derive(Debug, Serialize, Deserialize)] +struct UpdatePostInteraction { + pub interaction_time: DateTime, + pub post_creation_time: DateTime, + pub interaction_id: i64, + pub user_id: i64, +} + +pub fn route(State(app_state): State) -> Router { + Router::new() + .route("/", post(create)) + .route("/:interaction_time", get(read)) + .route("/", patch(update)) + .route("/:interaction_time", delete(delete_)) + .route("/posts/:post_creation_time", get(read_all_for_post)) + .with_state(app_state) +} + +async fn create( + State(app_state): State, + Json(create_post_interaction): Json, +) -> impl IntoResponse { + match PostInteraction::create( + &create_post_interaction.post_creation_time, + &create_post_interaction.user_id, + &create_post_interaction.interaction_id, + &app_state.database_connection, + ) + .await + { + Ok(post_interaction) => ( + StatusCode::CREATED, + Json(serde_json::json!(post_interaction)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read( + State(app_state): State, + Path(interaction_time): Path>, +) -> impl IntoResponse { + match PostInteraction::read(&interaction_time, &app_state.database_connection).await { + Ok(post_interaction) => (StatusCode::OK, Json(serde_json::json!(post_interaction))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn update( + State(app_state): State, + Json(update_post_interaction): Json, +) -> impl IntoResponse { + match PostInteraction::update( + &update_post_interaction.interaction_time, + &update_post_interaction.interaction_id, + &app_state.database_connection, + ) + .await + { + Ok(post_interaction) => ( + StatusCode::ACCEPTED, + Json(serde_json::json!(post_interaction)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_( + State(app_state): State, + Path(interaction_time): Path>, +) -> impl IntoResponse { + match PostInteraction::delete(&interaction_time, &app_state.database_connection).await { + Ok(post_interaction) => ( + StatusCode::NO_CONTENT, + Json(serde_json::json!(post_interaction)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read_all_for_post( + State(app_state): State, + Path(post_creation_time): Path>, +) -> impl IntoResponse { + match PostInteraction::read_all_for_post(&post_creation_time, &app_state.database_connection) + .await + { + Ok(post_interactions) => (StatusCode::OK, Json(serde_json::json!(post_interactions))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +}