Ported the project from sqlite to postgres

This commit is contained in:
Imbus 2023-11-14 08:40:45 +01:00
parent d397b5c1ed
commit 29c1fc8f82
23 changed files with 566 additions and 409 deletions

View file

@ -4,13 +4,13 @@ use argon2::{
Argon2, PasswordHasher, PasswordVerifier,
};
use log::{info, warn};
use sqlx::SqlitePool;
use sqlx::PgPool;
// Gets the latest posts from the database, ordered by created_at
pub async fn db_get_latest_posts(pool: &SqlitePool, limit: i64, offset: i64) -> Vec<Post> {
pub async fn db_get_latest_posts(pool: &PgPool, limit: i64, offset: i64) -> Vec<Post> {
sqlx::query_as!(
Post,
"SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?",
"SELECT * FROM posts ORDER BY created_at DESC LIMIT $1 OFFSET $2",
limit,
offset
)
@ -20,19 +20,19 @@ pub async fn db_get_latest_posts(pool: &SqlitePool, limit: i64, offset: i64) ->
}
// Gets the post with id from the database
pub async fn db_get_post(id: i64, pool: &SqlitePool) -> Option<Post> {
sqlx::query_as!(Post, "SELECT * FROM posts WHERE id = ?", id)
pub async fn db_get_post(id: i64, pool: &PgPool) -> Option<Post> {
sqlx::query_as!(Post, "SELECT * FROM posts WHERE id = $1", id)
.fetch_one(pool)
.await
.ok()
}
// Inserts a new post to the database
pub async fn db_new_post(userid: i64, content: &str, pool: &SqlitePool) -> Option<Post> {
pub async fn db_new_post(userid: i64, content: &str, pool: &PgPool) -> Option<Post> {
info!("User with id {} submitted a post", userid);
let insert_query = sqlx::query!(
"INSERT INTO posts (user_id, content) VALUES (?, ?)",
"INSERT INTO posts (user_id, content) VALUES ($1, $2)",
userid,
content
)
@ -57,8 +57,8 @@ pub async fn db_new_post(userid: i64, content: &str, pool: &SqlitePool) -> Optio
Some(post)
}
pub async fn db_user_exists(username: String, pool: &SqlitePool) -> bool {
let exists = sqlx::query!("SELECT username FROM users WHERE username = ?", username)
pub async fn db_user_exists(username: String, pool: &PgPool) -> bool {
let exists = sqlx::query!("SELECT username FROM users WHERE username = $1", username)
.fetch_one(pool)
.await
.ok()
@ -67,9 +67,9 @@ pub async fn db_user_exists(username: String, pool: &SqlitePool) -> bool {
exists.is_some()
}
pub async fn db_user_login(username: String, password: String, pool: &SqlitePool) -> Option<User> {
pub async fn db_user_login(username: String, password: String, pool: &PgPool) -> Option<User> {
let username = username.clone();
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = ?", username)
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = $1", username)
.fetch_one(pool)
.await
.ok()?;
@ -95,7 +95,7 @@ pub async fn db_user_login(username: String, password: String, pool: &SqlitePool
}
}
pub async fn db_new_user(username: String, password: String, pool: &SqlitePool) -> Option<User> {
pub async fn db_new_user(username: String, password: String, pool: &PgPool) -> Option<User> {
// First check if the user already exists
match db_user_exists(username.clone(), pool).await {
true => {
@ -113,7 +113,7 @@ pub async fn db_new_user(username: String, password: String, pool: &SqlitePool)
// Insert our new user into the database
let insert_query = sqlx::query!(
"INSERT INTO users (username, password) VALUES (?, ?)",
"INSERT INTO users (username, password) VALUES ($1, $2)",
username,
phc_hash
)
@ -123,7 +123,7 @@ pub async fn db_new_user(username: String, password: String, pool: &SqlitePool)
match insert_query {
Ok(_) => {
info!("User: {} registered", username);
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = ?", username)
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE username = $1", username)
.fetch_one(pool)
.await
.ok()?;

View file

@ -79,7 +79,7 @@ pub async fn new_post(new_post: Json<NewPost>, state: Data<ServerState>) -> Resu
let username = claims.sub.clone();
// This one is avoidable if we just store the user id in the token
let userid = sqlx::query!("SELECT id FROM users WHERE username = ?", username)
let userid = sqlx::query!("SELECT id FROM users WHERE username = $1", username)
.fetch_one(&state.pool)
.await
.unwrap()

View file

@ -4,10 +4,8 @@ use std::sync::Mutex;
use log::error;
use log::info;
use sqlx::migrate::MigrateDatabase;
use sqlx::Pool;
use sqlx::Sqlite;
use sqlx::{self, sqlite};
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
#[derive(Clone)]
pub struct CaptchaState {
@ -24,7 +22,7 @@ impl CaptchaState {
#[derive(Clone)]
pub struct ServerState {
pub pool: Pool<Sqlite>,
pub pool: PgPool,
}
impl ServerState {
@ -38,17 +36,13 @@ impl ServerState {
info!("Using db_url: {}", &db_url);
if !sqlx::Sqlite::database_exists(&db_url).await.unwrap() {
sqlx::Sqlite::create_database(&db_url).await.unwrap();
}
let pool = sqlite::SqlitePoolOptions::new()
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(&db_url)
.await
.unwrap();
sqlx::migrate!("./migrations").run(&pool).await.unwrap();
sqlx::migrate!("./migrations_pg").run(&pool).await.unwrap();
match crate::db::db_new_user("imbus".to_string(), "kartellen1234".to_string(), &pool).await
{
@ -63,13 +57,10 @@ impl ServerState {
}
}
#[cfg(debug_assertions)]
use sqlx::SqlitePool;
// Inserts a bunch of dummy data into the database
// Mostly useful for debugging new posts, as we need to satisfy foreign key constraints.
#[cfg(debug_assertions)]
async fn debug_setup(pool: &SqlitePool) -> Result<(), sqlx::Error> {
async fn debug_setup(pool: &PgPool) -> Result<(), sqlx::Error> {
use sqlx::query;
use crate::db::db_new_user;