diff --git a/.env b/.env index 7eca3fb..4fa7ffb 100644 --- a/.env +++ b/.env @@ -1 +1,3 @@ +# This is for sqlx to do compile time sql checking +# Actual server and database configs are in config folder DATABASE_URL=postgres://root:root@localhost:5432/rust_forum \ No newline at end of file diff --git a/migrations/20241204225143_create_post_table.up.sql b/migrations/20241204225143_create_post_table.up.sql index c7be5f0..944ba14 100644 --- a/migrations/20241204225143_create_post_table.up.sql +++ b/migrations/20241204225143_create_post_table.up.sql @@ -1,6 +1,6 @@ -- Add up migration script here CREATE TABLE IF NOT EXISTS "post"( creation_time TIMESTAMPTZ PRIMARY KEY UNIQUE NOT NULL DEFAULT NOW(), - poster_id BIGSERIAL NOT NULL REFERENCES "user"(id), + user_id BIGSERIAL NOT NULL REFERENCES "user"(id), post VARCHAR NOT NULL UNIQUE ); \ No newline at end of file diff --git a/migrations/20241204225151_create_comment_table.up.sql b/migrations/20241204225151_create_comment_table.up.sql index 0339b36..a92af64 100644 --- a/migrations/20241204225151_create_comment_table.up.sql +++ b/migrations/20241204225151_create_comment_table.up.sql @@ -2,6 +2,6 @@ CREATE TABLE IF NOT EXISTS "comment"( post_creation_time TIMESTAMPTZ NOT NULL REFERENCES "post"(creation_time), creation_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW(), - commenter_id BIGSERIAL NOT NULL REFERENCES "user"(id), + user_id BIGSERIAL NOT NULL REFERENCES "user"(id), comment VARCHAR NOT NULL ); \ No newline at end of file diff --git a/migrations/20241204230240_create_post_interaction_table.up.sql b/migrations/20241204230240_create_post_interaction_table.up.sql index fc12e83..d22e247 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"( 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), - interactor_id BIGSERIAL NOT NULL REFERENCES "user"(id), interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW() ); \ 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 1742b20..41f4aca 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"( 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), - interactor_id BIGSERIAL NOT NULL REFERENCES "user"(id), interaction_time TIMESTAMPTZ PRIMARY KEY NOT NULL UNIQUE DEFAULT NOW() ); \ No newline at end of file diff --git a/src/database/comment.rs b/src/database/comment.rs index 3202320..cd01e1c 100644 --- a/src/database/comment.rs +++ b/src/database/comment.rs @@ -5,19 +5,19 @@ use crate::feature::comment::Comment; pub async fn create( post_creation_time: &DateTime, - commenter_id: &i64, + user_id: &i64, comment: &String, database_connection: &Pool, ) -> Result { sqlx::query_as!( Comment, r#" - INSERT INTO "comment"(post_creation_time, commenter_id, comment) + INSERT INTO "comment"(post_creation_time, user_id, comment) VALUES ($1, $2, $3) RETURNING * "#, post_creation_time, - commenter_id, + user_id, comment, ) .fetch_one(database_connection) diff --git a/src/database/comment_interaction.rs b/src/database/comment_interaction.rs index ac5960b..c5c1baa 100644 --- a/src/database/comment_interaction.rs +++ b/src/database/comment_interaction.rs @@ -5,20 +5,20 @@ use crate::feature::comment_interaction::CommentInteraction; pub async fn create( comment_creation_time: &DateTime, + user_id: &i64, interaction_id: &i64, - interactor_id: &i64, database_connection: &Pool, ) -> Result { sqlx::query_as!( CommentInteraction, r#" - INSERT INTO "comment_interaction"(comment_creation_time, interaction_id, interactor_id) + INSERT INTO "comment_interaction"(comment_creation_time, user_id, interaction_id) VALUES ($1, $2, $3) RETURNING * "#, comment_creation_time, + user_id, interaction_id, - interactor_id, ) .fetch_one(database_connection) .await diff --git a/src/database/post.rs b/src/database/post.rs index 3ac770f..498d434 100644 --- a/src/database/post.rs +++ b/src/database/post.rs @@ -4,18 +4,18 @@ use sqlx::{Pool, Postgres}; use crate::feature::post::Post; pub async fn create( - poster_id: &i64, + user_id: &i64, post: &String, database_connection: &Pool, ) -> Result { sqlx::query_as!( Post, r#" - INSERT INTO "post"(poster_id, post) + INSERT INTO "post"(user_id, post) VALUES ($1, $2) RETURNING * "#, - poster_id, + user_id, post ) .fetch_one(database_connection) @@ -39,18 +39,18 @@ pub async fn read( pub async fn update( creation_time: &DateTime, - poster_id: &i64, + user_id: &i64, post: &String, database_connection: &Pool, ) -> Result { sqlx::query_as!( Post, r#" - UPDATE "post" SET poster_id = $2, post = $3 WHERE "creation_time" = $1 + UPDATE "post" SET user_id = $2, post = $3 WHERE "creation_time" = $1 RETURNING * "#, creation_time, - poster_id, + user_id, post ) .fetch_one(database_connection) @@ -85,15 +85,15 @@ pub async fn read_all(database_connection: &Pool) -> Result, } pub async fn read_all_for_user( - poster_id: &i64, + user_id: &i64, database_connection: &Pool, ) -> Result, sqlx::Error> { sqlx::query_as!( Post, r#" - SELECT * FROM "post" WHERE "poster_id" = $1 + SELECT * FROM "post" WHERE "user_id" = $1 "#, - poster_id + user_id ) .fetch_all(database_connection) .await diff --git a/src/database/post_interaction.rs b/src/database/post_interaction.rs index dab6b49..2c7b90d 100644 --- a/src/database/post_interaction.rs +++ b/src/database/post_interaction.rs @@ -5,20 +5,20 @@ use crate::feature::post_interaction::PostInteraction; pub async fn create( post_creation_time: &DateTime, + user_id: &i64, interaction_id: &i64, - interactor_id: &i64, database_connection: &Pool, ) -> Result { sqlx::query_as!( PostInteraction, r#" - INSERT INTO "post_interaction"(post_creation_time, interaction_id, interactor_id) + INSERT INTO "post_interaction"(post_creation_time, user_id, interaction_id) VALUES ($1, $2, $3) RETURNING * "#, post_creation_time, + user_id, interaction_id, - interactor_id, ) .fetch_one(database_connection) .await diff --git a/src/feature/comment.rs b/src/feature/comment.rs index 2fff712..22acc3f 100644 --- a/src/feature/comment.rs +++ b/src/feature/comment.rs @@ -5,6 +5,6 @@ use serde::{Deserialize, Serialize}; pub struct Comment { pub post_creation_time: DateTime, pub creation_time: DateTime, - pub commenter_id: i64, + pub user_id: i64, pub comment: String, } diff --git a/src/feature/comment_interaction.rs b/src/feature/comment_interaction.rs index fffc545..9e23627 100644 --- a/src/feature/comment_interaction.rs +++ b/src/feature/comment_interaction.rs @@ -5,6 +5,6 @@ use serde::{Deserialize, Serialize}; pub struct CommentInteraction { pub comment_creation_time: DateTime, pub interaction_id: i64, - pub interactor_id: i64, + pub user_id: i64, pub interaction_time: DateTime, } diff --git a/src/feature/post.rs b/src/feature/post.rs index c85a799..f41255d 100644 --- a/src/feature/post.rs +++ b/src/feature/post.rs @@ -1,9 +1,56 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres}; + +use crate::database::post; #[derive(Debug, Serialize, Deserialize)] pub struct Post { pub creation_time: DateTime, - pub poster_id: i64, + pub user_id: i64, pub post: String, } + +impl Post { + pub async fn create( + user_id: &i64, + post: &String, + database_connection: &Pool, + ) -> Result { + post::create(user_id, post, database_connection).await + } + + pub async fn read( + creation_time: &DateTime, + database_connection: &Pool, + ) -> Result { + post::read(creation_time, database_connection).await + } + + pub async fn update( + creation_time: &DateTime, + user_id: &i64, + post: &String, + database_connection: &Pool, + ) -> Result { + post::update(creation_time, user_id, post, database_connection).await + } + + pub async fn delete( + creation_time: &DateTime, + database_connection: &Pool, + ) -> Result { + post::delete(creation_time, database_connection).await + } + + pub async fn read_all(database_connection: &Pool) -> Result, sqlx::Error> { + post::read_all(database_connection).await + } + + pub async fn read_all_for_user( + user_id: &i64, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + post::read_all_for_user(user_id, database_connection).await + } +} diff --git a/src/feature/post_interaction.rs b/src/feature/post_interaction.rs index 8639fec..4c51fd4 100644 --- a/src/feature/post_interaction.rs +++ b/src/feature/post_interaction.rs @@ -5,6 +5,6 @@ use serde::{Deserialize, Serialize}; pub struct PostInteraction { pub post_creation_time: DateTime, pub interaction_id: i64, - pub interactor_id: i64, + pub user_id: i64, pub interaction_time: DateTime, } diff --git a/src/routing.rs b/src/routing.rs index 5b7c0a6..ce68fa6 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -1,3 +1,4 @@ +pub mod post; pub mod role; pub mod user; diff --git a/src/routing/post.rs b/src/routing/post.rs new file mode 100644 index 0000000..210496f --- /dev/null +++ b/src/routing/post.rs @@ -0,0 +1,109 @@ +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::Post, AppState}; + +#[derive(Debug, Serialize, Deserialize)] +struct CreatePost { + user_id: i64, + post: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct UpdatePost { + creation_time: DateTime, + user_id: i64, + post: String, +} + +pub fn route(State(app_state): State) -> Router { + Router::new() + .route("/", post(create)) + .route("/:creation_time", get(read)) + .route("/", patch(update)) + .route("/:creation_time", delete(delete_)) + .route("/", get(read_all)) + .with_state(app_state) +} + +async fn create( + State(app_state): State, + Json(create_post): Json, +) -> impl IntoResponse { + match Post::create( + &create_post.user_id, + &create_post.post, + &app_state.database_connection, + ) + .await + { + Ok(post) => (StatusCode::CREATED, Json(serde_json::json!(post))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read( + State(app_state): State, + Path(creation_time): Path>, +) -> impl IntoResponse { + match Post::read(&creation_time, &app_state.database_connection).await { + Ok(post) => (StatusCode::OK, Json(serde_json::json!(post))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn update( + State(app_state): State, + Json(update_role): Json, +) -> impl IntoResponse { + match Post::update( + &update_role.creation_time, + &update_role.user_id, + &update_role.post, + &app_state.database_connection, + ) + .await + { + Ok(post) => (StatusCode::ACCEPTED, Json(serde_json::json!(post))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_( + State(app_state): State, + Path(creation_time): Path>, +) -> impl IntoResponse { + match Post::delete(&creation_time, &app_state.database_connection).await { + Ok(post) => (StatusCode::NO_CONTENT, Json(serde_json::json!(post))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read_all(State(app_state): State) -> impl IntoResponse { + match Post::read_all(&app_state.database_connection).await { + Ok(posts) => (StatusCode::OK, Json(serde_json::json!(posts))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +}