You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.3 KiB
Rust
169 lines
5.3 KiB
Rust
use serde::Serialize;
|
|
use sqlx::{Pool, Postgres};
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Clone)]
|
|
pub struct DB {
|
|
connection_pool: Pool::<Postgres>
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct Site {
|
|
uuid: Uuid,
|
|
title: String,
|
|
base_url: String,
|
|
theme: String,
|
|
boards: Vec<Board>
|
|
}
|
|
|
|
#[derive(Serialize, Clone)]
|
|
pub struct Board {
|
|
uuid: Uuid,
|
|
title: String,
|
|
description: String,
|
|
threads: Vec<Thread>
|
|
}
|
|
impl Board {
|
|
fn clone(&self) -> Board {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Clone)]
|
|
pub struct Thread {
|
|
uuid: Uuid,
|
|
title: String,
|
|
posts: Vec<Post>
|
|
}
|
|
|
|
#[derive(Serialize, Clone)]
|
|
pub struct Post {
|
|
uuid: Uuid,
|
|
contents: String,
|
|
author: User
|
|
}
|
|
|
|
#[derive(Serialize, Clone)]
|
|
pub struct User {
|
|
uuid: Uuid,
|
|
email: String,
|
|
username: String,
|
|
password_hash: String,
|
|
is_admin: bool
|
|
}
|
|
|
|
impl DB {
|
|
pub async fn init() -> Self {
|
|
let db_url = std::env::var("DATABASE_URL").expect("Please provide DATABASE_URL in environment");
|
|
let pool = Pool::<Postgres>::connect(db_url.as_str()).await.expect("Could not connect to database");
|
|
|
|
sqlx::migrate!()
|
|
.run(&pool)
|
|
.await
|
|
.expect("Could not run database migrations");
|
|
|
|
DB {
|
|
connection_pool: pool
|
|
}
|
|
}
|
|
|
|
pub async fn get_site_data(&self) -> Result<Site, String> {
|
|
let rows = sqlx::query!(r#"
|
|
select
|
|
site_uuid,
|
|
site_title,
|
|
site_base_url,
|
|
site_theme,
|
|
board_uuid,
|
|
board_title,
|
|
board_description,
|
|
thread_uuid,
|
|
thread_title,
|
|
post_uuid as "post_uuid?",
|
|
post_contents as "post_contents?",
|
|
user_uuid,
|
|
user_email,
|
|
user_username,
|
|
user_password_hash,
|
|
user_is_admin
|
|
from forum.site
|
|
left join forum.board on board_site = site_uuid
|
|
left join forum.thread on thread_board = board_uuid
|
|
left join forum.post on post_thread = thread_uuid
|
|
left join forum.user on post_author = user_uuid
|
|
"#).fetch_all(&self.connection_pool).await.expect("Could not connect to database");
|
|
|
|
let mut site : Option<Site> = None;
|
|
let mut last_board : Option<Board> = None;
|
|
let mut last_thread : Option<Thread> = None;
|
|
let mut last_post : Option<Post> = None;
|
|
|
|
for row in rows {
|
|
if site.is_none() || row.site_uuid.is_some() && row.site_uuid.unwrap() != site.as_ref().unwrap().uuid {
|
|
site = Some(Site {
|
|
uuid: row.site_uuid.unwrap(),
|
|
title: row.site_title.unwrap_or(String::new()),
|
|
base_url: row.site_base_url.unwrap_or(String::new()),
|
|
theme: row.site_theme.unwrap_or(String::new()),
|
|
boards: Vec::new()
|
|
})
|
|
}
|
|
|
|
if last_board.is_none() || row.board_uuid.is_some() && row.board_uuid.unwrap() != last_board.as_ref().unwrap().uuid {
|
|
if let Some(ref board) = last_board {
|
|
site.as_mut().unwrap().boards.push(board.clone())
|
|
}
|
|
|
|
if row.board_uuid.is_some() {
|
|
last_board = Some(Board {
|
|
uuid: row.board_uuid.unwrap(),
|
|
title: row.board_title.unwrap_or(String::new()),
|
|
description: row.board_description.unwrap_or(String::new()),
|
|
threads: Vec::new()
|
|
})
|
|
}
|
|
}
|
|
|
|
if last_thread.is_none() || row.thread_uuid.is_some() && row.thread_uuid.unwrap() != last_thread.as_mut().unwrap().uuid {
|
|
if let Some(ref thread) = last_thread {
|
|
last_board.as_mut().unwrap().threads.push(thread.clone())
|
|
}
|
|
|
|
if row.thread_uuid.is_some() {
|
|
last_thread = Some(Thread {
|
|
uuid: row.thread_uuid.unwrap(),
|
|
title: row.thread_title.unwrap_or(String::new()),
|
|
posts: Vec::new()
|
|
})
|
|
}
|
|
}
|
|
|
|
// if last_post.is_none() || row.post_uuid != last_post.as_ref().unwrap().uuid {
|
|
// if let Some(post) = last_post {
|
|
// last_thread.as_mut().unwrap().posts.push(post)
|
|
// }
|
|
//
|
|
// if row.post_uuid.is_some() {
|
|
// last_post = Some(Post {
|
|
// uuid: row.post_uuid,
|
|
// contents: row.post_contents,
|
|
// author: User {
|
|
// uuid: row.user_uuid.unwrap(),
|
|
// email: row.user_email.unwrap_or(String::new()),
|
|
// username: row.user_username.unwrap_or(String::new()),
|
|
// password_hash: row.user_password_hash.unwrap_or(String::new()),
|
|
// is_admin: row.user_is_admin.unwrap_or(false)
|
|
// }
|
|
// })
|
|
// }
|
|
// }
|
|
}
|
|
|
|
if let Some(site) = site {
|
|
Ok(site)
|
|
} else {
|
|
Err("Could not find site in DB".to_string())
|
|
}
|
|
}
|
|
}
|