Replace Rusqlite by Sqlx and Actix by Axum (A lot of changes)

This commit is contained in:
Greg Burri 2024-11-03 10:13:31 +01:00
parent 57d7e7a3ce
commit 980c5884a4
28 changed files with 2860 additions and 2262 deletions

View file

@ -1,195 +0,0 @@
//! Functions to be called from actix code. They are asynchonrous and won't block worker thread caller.
use std::fmt;
use actix_web::{error::BlockingError, web};
use chrono::{prelude::*, Duration};
use super::db::*;
use crate::model;
#[derive(Debug)]
pub enum DBAsyncError {
DBError(DBError),
ActixError(BlockingError),
Other(String),
}
impl fmt::Display for DBAsyncError {
fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
write!(f, "{:?}", self)
}
}
impl std::error::Error for DBAsyncError {}
impl From<DBError> for DBAsyncError {
fn from(error: DBError) -> Self {
DBAsyncError::DBError(error)
}
}
impl From<BlockingError> for DBAsyncError {
fn from(error: BlockingError) -> Self {
DBAsyncError::ActixError(error)
}
}
impl DBAsyncError {
fn from_dyn_error(error: Box<dyn std::error::Error>) -> Self {
DBAsyncError::Other(error.to_string())
}
}
fn combine_errors<T>(
error: std::result::Result<std::result::Result<T, DBAsyncError>, BlockingError>,
) -> Result<T> {
error?
}
type Result<T> = std::result::Result<T, DBAsyncError>;
impl Connection {
pub async fn get_all_recipe_titles_async(&self) -> Result<Vec<(i64, String)>> {
let self_copy = self.clone();
web::block(move || self_copy.get_all_recipe_titles().unwrap_or_default())
.await
.map_err(DBAsyncError::from)
}
pub async fn get_recipe_async(&self, id: i64) -> Result<model::Recipe> {
let self_copy = self.clone();
combine_errors(
web::block(move || self_copy.get_recipe(id).map_err(DBAsyncError::from)).await,
)
}
pub async fn load_user_async(&self, user_id: i64) -> Result<model::User> {
let self_copy = self.clone();
combine_errors(
web::block(move || self_copy.load_user(user_id).map_err(DBAsyncError::from)).await,
)
}
pub async fn sign_up_async(&self, email: &str, password: &str) -> Result<SignUpResult> {
let self_copy = self.clone();
let email_copy = email.to_string();
let password_copy = password.to_string();
combine_errors(
web::block(move || {
self_copy
.sign_up(&email_copy, &password_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
pub async fn validation_async(
&self,
token: &str,
validation_time: Duration,
ip: &str,
user_agent: &str,
) -> Result<ValidationResult> {
let self_copy = self.clone();
let token_copy = token.to_string();
let ip_copy = ip.to_string();
let user_agent_copy = user_agent.to_string();
combine_errors(
web::block(move || {
self_copy
.validation(&token_copy, validation_time, &ip_copy, &user_agent_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
pub async fn sign_in_async(
&self,
email: &str,
password: &str,
ip: &str,
user_agent: &str,
) -> Result<SignInResult> {
let self_copy = self.clone();
let email_copy = email.to_string();
let password_copy = password.to_string();
let ip_copy = ip.to_string();
let user_agent_copy = user_agent.to_string();
combine_errors(
web::block(move || {
self_copy
.sign_in(&email_copy, &password_copy, &ip_copy, &user_agent_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
pub async fn authentication_async(
&self,
token: &str,
ip: &str,
user_agent: &str,
) -> Result<AuthenticationResult> {
let self_copy = self.clone();
let token_copy = token.to_string();
let ip_copy = ip.to_string();
let user_agent_copy = user_agent.to_string();
combine_errors(
web::block(move || {
self_copy
.authentication(&token_copy, &ip_copy, &user_agent_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
pub async fn sign_out_async(&self, token: &str) -> Result<()> {
let self_copy = self.clone();
let token_copy = token.to_string();
combine_errors(
web::block(move || self_copy.sign_out(&token_copy).map_err(DBAsyncError::from)).await,
)
}
pub async fn create_recipe_async(&self, user_id: i64) -> Result<i64> {
let self_copy = self.clone();
combine_errors(
web::block(move || self_copy.create_recipe(user_id).map_err(DBAsyncError::from)).await,
)
}
pub async fn set_recipe_title_async(&self, recipe_id: i64, title: &str) -> Result<()> {
let self_copy = self.clone();
let title_copy = title.to_string();
combine_errors(
web::block(move || {
self_copy
.set_recipe_title(recipe_id, &title_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
pub async fn set_recipe_description_async(
&self,
recipe_id: i64,
description: &str,
) -> Result<()> {
let self_copy = self.clone();
let description_copy = description.to_string();
combine_errors(
web::block(move || {
self_copy
.set_recipe_description(recipe_id, &description_copy)
.map_err(DBAsyncError::from)
})
.await,
)
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
pub mod asynchronous;
pub mod db;
mod utils;

33
backend/src/data/utils.rs Normal file
View file

@ -0,0 +1,33 @@
use sqlx::{sqlite::SqliteRow, FromRow, Row};
use crate::model;
impl FromRow<'_, SqliteRow> for model::Recipe {
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
Ok(model::Recipe::new(
row.try_get("id")?,
row.try_get("user_id")?,
row.try_get("title")?,
row.try_get("description")?,
))
}
}
impl FromRow<'_, SqliteRow> for model::UserLoginInfo {
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
Ok(model::UserLoginInfo {
last_login_datetime: row.try_get("last_login_datetime")?,
ip: row.try_get("ip")?,
user_agent: row.try_get("user_agent")?,
})
}
}
impl FromRow<'_, SqliteRow> for model::User {
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
Ok(model::User {
id: row.try_get("id")?,
email: row.try_get("email")?,
})
}
}