Compare commits
	
		
			6 commits
		
	
	
		
			9e302fc54a
			...
			8875ae4a4c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8875ae4a4c | ||
|   | 5a75e6f9a0 | ||
|   | d0e5b57006 | ||
|   | 32ff43e87c | ||
|   | 3d40ec513e | ||
|   | d12bd9aa99 | 
					 8 changed files with 101 additions and 23 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -25,3 +25,5 @@ dist-ssr | ||||||
| 
 | 
 | ||||||
| *.env | *.env | ||||||
| *.db* | *.db* | ||||||
|  | 
 | ||||||
|  | *backup* | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| CREATE TABLE IF NOT EXISTS comments ( | CREATE TABLE IF NOT EXISTS comments ( | ||||||
|     id BIGSERIAL PRIMARY KEY, |     id SERIAL PRIMARY KEY NOT NULL, | ||||||
|     parent_post_id BIGINT NOT NULL, |     parent_post_id BIGINT NOT NULL, | ||||||
|     parent_comment_id BIGINT, |     -- parent_comment_id BIGINT, | ||||||
|     author_user_id BIGINT NOT NULL, |     author_user_id BIGINT NOT NULL, | ||||||
|     content TEXT NOT NULL, |     content TEXT NOT NULL, | ||||||
|     upvotes INTEGER NOT NULL DEFAULT 0, |     upvotes INTEGER NOT NULL DEFAULT 0, | ||||||
|  | @ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS comments ( | ||||||
|     created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |     created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|     updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |     updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|     FOREIGN KEY (parent_post_id) REFERENCES posts (id), |     FOREIGN KEY (parent_post_id) REFERENCES posts (id), | ||||||
|     FOREIGN KEY (parent_comment_id) REFERENCES comments (id), |     -- FOREIGN KEY (parent_comment_id) REFERENCES comments (id), | ||||||
|     FOREIGN KEY (author_user_id) REFERENCES users (id) |     FOREIGN KEY (author_user_id) REFERENCES users (id) | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|  | @ -43,5 +43,5 @@ FOR EACH ROW | ||||||
| EXECUTE FUNCTION comments_set_updated_at(); | EXECUTE FUNCTION comments_set_updated_at(); | ||||||
| 
 | 
 | ||||||
| CREATE INDEX comments_parent_post_id_index ON comments (parent_post_id); | CREATE INDEX comments_parent_post_id_index ON comments (parent_post_id); | ||||||
| CREATE INDEX comments_parent_comment_id_index ON comments (parent_comment_id); | -- CREATE INDEX comments_parent_comment_id_index ON comments (parent_comment_id); | ||||||
| CREATE INDEX comments_user_id_index ON comments (author_user_id); | CREATE INDEX comments_user_id_index ON comments (author_user_id); | ||||||
							
								
								
									
										62
									
								
								server/migrations/0004_procedures.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								server/migrations/0004_procedures.sql
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | ||||||
|  | -- Description: This file creates the procedures and functions for adding users, posts, and comments. | ||||||
|  | -- Functions are commonly used for SELECT queries, while procedures are used for INSERT, UPDATE, and DELETE queries. | ||||||
|  | -- None of these seem to play very nice with sqlx for now, but they will surely be useful in the future. | ||||||
|  | 
 | ||||||
|  | -- Procedure for adding a user | ||||||
|  | CREATE OR REPLACE PROCEDURE add_user( | ||||||
|  |     IN username_param TEXT, | ||||||
|  |     IN password_param TEXT | ||||||
|  | ) | ||||||
|  | LANGUAGE plpgsql | ||||||
|  | AS $$ | ||||||
|  | BEGIN | ||||||
|  |     INSERT INTO users (username, password) | ||||||
|  |     VALUES (username_param, password_param); | ||||||
|  | END; | ||||||
|  | $$; | ||||||
|  | 
 | ||||||
|  | -- Procedure for adding a post | ||||||
|  | CREATE OR REPLACE PROCEDURE add_post( | ||||||
|  |     IN user_id_param BIGINT, | ||||||
|  |     IN content_param TEXT | ||||||
|  | ) | ||||||
|  | LANGUAGE plpgsql | ||||||
|  | AS $$ | ||||||
|  | BEGIN | ||||||
|  |     INSERT INTO posts (user_id, content) | ||||||
|  |     VALUES (user_id_param, content_param); | ||||||
|  | END; | ||||||
|  | $$; | ||||||
|  | 
 | ||||||
|  | -- Procedure for adding a comment | ||||||
|  | CREATE OR REPLACE PROCEDURE add_comment( | ||||||
|  |     IN parent_post_id_param BIGINT, | ||||||
|  |     -- IN parent_comment_id_param BIGINT, | ||||||
|  |     IN author_user_id_param BIGINT, | ||||||
|  |     IN content_param TEXT | ||||||
|  | ) | ||||||
|  | LANGUAGE plpgsql | ||||||
|  | AS $$ | ||||||
|  | BEGIN | ||||||
|  |     INSERT INTO comments (parent_post_id, author_user_id, content) | ||||||
|  |     VALUES (parent_post_id_param, author_user_id_param, content_param); | ||||||
|  | END; | ||||||
|  | $$; | ||||||
|  | 
 | ||||||
|  | -- Function for getting comments | ||||||
|  | CREATE OR REPLACE FUNCTION get_comments( | ||||||
|  |     IN parent_post_id_param BIGINT, | ||||||
|  |     IN limit_param BIGINT, | ||||||
|  |     IN offset_param BIGINT | ||||||
|  | ) | ||||||
|  | RETURNS SETOF comments AS $$ | ||||||
|  | BEGIN | ||||||
|  |     RETURN QUERY | ||||||
|  |     SELECT * | ||||||
|  |     FROM comments | ||||||
|  |     WHERE parent_post_id = parent_post_id_param | ||||||
|  |     ORDER BY created_at DESC | ||||||
|  |     LIMIT limit_param | ||||||
|  |     OFFSET offset_param; | ||||||
|  | END; | ||||||
|  | $$ LANGUAGE plpgsql; | ||||||
|  | @ -9,14 +9,13 @@ use sqlx::PgPool; | ||||||
| pub async fn db_new_comment( | pub async fn db_new_comment( | ||||||
|     pool: &PgPool, |     pool: &PgPool, | ||||||
|     parent_post_id: i64, |     parent_post_id: i64, | ||||||
|     parent_comment_id: Option<i64>, |     // parent_comment_id: Option<i64>,
 | ||||||
|     user_id: i64, |     user_id: i64, | ||||||
|     content: &str, |     content: &str, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     let insert_query = sqlx::query!( |     let insert_query = sqlx::query!( | ||||||
|         "INSERT INTO comments (parent_post_id, parent_comment_id, author_user_id, content) VALUES ($1, $2, $3, $4)", |         "INSERT INTO comments (parent_post_id, author_user_id, content) VALUES ($1, $2, $3)", | ||||||
|         parent_post_id, |         parent_post_id, | ||||||
|         parent_comment_id, |  | ||||||
|         user_id, |         user_id, | ||||||
|         content |         content | ||||||
|     ) |     ) | ||||||
|  | @ -40,7 +39,8 @@ pub async fn db_get_comments( | ||||||
| ) -> Vec<PublicComment> { | ) -> Vec<PublicComment> { | ||||||
|     sqlx::query_as!( |     sqlx::query_as!( | ||||||
|         PublicComment, |         PublicComment, | ||||||
|         "SELECT id, parent_post_id, parent_comment_id, upvotes, downvotes, content, created_at, updated_at FROM comments WHERE parent_post_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3", |         "SELECT id, parent_post_id, upvotes, downvotes, content, created_at, updated_at
 | ||||||
|  |          FROM comments WHERE parent_post_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3",
 | ||||||
|         parent_post_id, |         parent_post_id, | ||||||
|         limit, |         limit, | ||||||
|         offset |         offset | ||||||
|  |  | ||||||
|  | @ -20,7 +20,11 @@ use util::hex_string; | ||||||
| 
 | 
 | ||||||
| #[actix_web::main] | #[actix_web::main] | ||||||
| async fn main() -> std::io::Result<()> { | async fn main() -> std::io::Result<()> { | ||||||
|     env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init(); |     let mut builder = env_logger::Builder::new(); | ||||||
|  |     builder | ||||||
|  |         .filter(None, log::LevelFilter::Debug) | ||||||
|  |         .filter_module("sqlx", log::LevelFilter::Warn) | ||||||
|  |         .init(); | ||||||
| 
 | 
 | ||||||
|     let data = ServerState::new().await; |     let data = ServerState::new().await; | ||||||
|     let capt_db = CaptchaState::new(); |     let capt_db = CaptchaState::new(); | ||||||
|  | @ -49,7 +53,7 @@ async fn main() -> std::io::Result<()> { | ||||||
|         App::new() |         App::new() | ||||||
|             .wrap(cors) |             .wrap(cors) | ||||||
|             .wrap(middleware::Compress::default()) |             .wrap(middleware::Compress::default()) | ||||||
|             .wrap(middleware::Logger::default()) |             .wrap(middleware::Logger::new("%s %r")) | ||||||
|             .wrap(middleware::NormalizePath::trim()) |             .wrap(middleware::NormalizePath::trim()) | ||||||
|             .service( |             .service( | ||||||
|                 scope("/api") |                 scope("/api") | ||||||
|  |  | ||||||
|  | @ -24,6 +24,11 @@ pub async fn get_comments( | ||||||
| 
 | 
 | ||||||
|     let comments = db_get_comments(&state.pool, post_id, limit, offset).await; |     let comments = db_get_comments(&state.pool, post_id, limit, offset).await; | ||||||
| 
 | 
 | ||||||
|  |     if comments.is_empty() { | ||||||
|  |         info!("No comments found for post {}", post_id); | ||||||
|  |         return Ok(HttpResponse::NotFound().json("No comments found")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     Ok(HttpResponse::Ok().json(comments)) |     Ok(HttpResponse::Ok().json(comments)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -60,14 +65,7 @@ pub async fn new_comment( | ||||||
| 
 | 
 | ||||||
|     info!("Creating a new comment {:?}", &data); |     info!("Creating a new comment {:?}", &data); | ||||||
| 
 | 
 | ||||||
|     let success = db_new_comment( |     let success = db_new_comment(&state.pool, data.parent_post_id, userid, &content).await; | ||||||
|         &state.pool, |  | ||||||
|         data.parent_post_id, |  | ||||||
|         data.parent_comment_id, |  | ||||||
|         userid, |  | ||||||
|         &content, |  | ||||||
|     ) |  | ||||||
|     .await; |  | ||||||
| 
 | 
 | ||||||
|     match success { |     match success { | ||||||
|         true => { |         true => { | ||||||
|  |  | ||||||
|  | @ -105,6 +105,19 @@ async fn lipsum_setup(pool: &PgPool) -> Result<(), sqlx::Error> { | ||||||
|             .execute(pool) |             .execute(pool) | ||||||
|             .await?; |             .await?; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         // Insert a bunch of comments
 | ||||||
|  |         for i in 1..101 { | ||||||
|  |             for _ in 0..rng.gen_range(3..30) { | ||||||
|  |                 query!( | ||||||
|  |                     "INSERT INTO comments (author_user_id, parent_post_id, content) VALUES (1, $1, $2)", | ||||||
|  |                     i, | ||||||
|  |                     lipsum(rng.gen_range(10..100)) | ||||||
|  |                 ) | ||||||
|  |                 .execute(pool) | ||||||
|  |                 .await?; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
|  |  | ||||||
|  | @ -16,8 +16,8 @@ pub struct Comment { | ||||||
|     pub parent_post_id: i64, |     pub parent_post_id: i64, | ||||||
|     pub parent_comment_id: Option<i64>, |     pub parent_comment_id: Option<i64>, | ||||||
|     pub author_user_id: i64, |     pub author_user_id: i64, | ||||||
|     pub upvotes: i64, |     pub upvotes: i32, | ||||||
|     pub downvotes: i64, |     pub downvotes: i32, | ||||||
|     pub content: String, |     pub content: String, | ||||||
|     pub created_at: chrono::NaiveDateTime, |     pub created_at: chrono::NaiveDateTime, | ||||||
|     pub updated_at: chrono::NaiveDateTime, |     pub updated_at: chrono::NaiveDateTime, | ||||||
|  | @ -28,9 +28,8 @@ pub struct Comment { | ||||||
| pub struct PublicComment { | pub struct PublicComment { | ||||||
|     pub id: i64, |     pub id: i64, | ||||||
|     pub parent_post_id: i64, |     pub parent_post_id: i64, | ||||||
|     pub parent_comment_id: Option<i64>, |     pub upvotes: i32, | ||||||
|     pub upvotes: i64, |     pub downvotes: i32, | ||||||
|     pub downvotes: i64, |  | ||||||
|     pub content: String, |     pub content: String, | ||||||
|     pub created_at: chrono::NaiveDateTime, |     pub created_at: chrono::NaiveDateTime, | ||||||
|     pub updated_at: chrono::NaiveDateTime, |     pub updated_at: chrono::NaiveDateTime, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue