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