add sqlite database stuff

This commit is contained in:
Milim 2024-12-07 12:27:48 +01:00
parent 28f571e02b
commit be6b86ee28
No known key found for this signature in database
6 changed files with 314 additions and 7 deletions

View file

@ -15,6 +15,24 @@ pub enum DataBase {
Postgres(sqlx::Pool<Postgres>),
}
/// Error type for handling DB related errors
pub enum DbError {
/// No such entry found
NotFound,
/// Database related error
SqlxError(sqlx::Error),
}
impl From<sqlx::Error> for DbError {
fn from(value: sqlx::Error) -> Self {
match value {
sqlx::Error::RowNotFound => DbError::NotFound,
_ => DbError::SqlxError(value),
}
}
}
type DbResult<T> = Result<T, DbError>;
impl DataBase {
/// Database backed by SQLite
pub async fn sqlite() -> Self {
@ -67,9 +85,65 @@ impl DataBase {
Self::Postgres(pool)
}
pub fn get_chapter(&self, id: u32) -> models::Chapter {
/// Tries to fetch a book from the database
pub async fn get_book(&self, id: u32) -> DbResult<models::Book> {
match self {
DataBase::Sqlite(pool) => sqlite::sqlite_chapter(pool, id),
DataBase::Sqlite(pool) => sqlite::sqlite_book(pool, id).await,
DataBase::Postgres(pool) => todo!(),
}
}
/// Tries to create a book and returns the book's id if successful
pub async fn create_book(
&self,
title: String,
description: String,
author_id: u32,
) -> DbResult<u32> {
match self {
DataBase::Sqlite(pool) => {
sqlite::sqlite_book_create(pool, title, description, author_id).await
}
DataBase::Postgres(pool) => todo!(),
}
}
/// Tries to fetch a chapter from the database
pub async fn get_chapter(&self, id: u32) -> DbResult<models::Chapter> {
match self {
DataBase::Sqlite(pool) => sqlite::sqlite_chapter(pool, id).await,
DataBase::Postgres(pool) => todo!(),
}
}
/// Tries to create a chapter and returns the chapter's id if successfu
pub async fn create_chapter(
&self,
title: String,
text: String,
book_id: u32,
author_id: u32,
) -> DbResult<u32> {
match self {
DataBase::Sqlite(pool) => {
sqlite::sqlite_chapter_create(pool, title, text, book_id, author_id).await
}
DataBase::Postgres(pool) => todo!(),
}
}
/// Tries to fetch a user from the database
pub async fn get_user(&self, id: u32) -> DbResult<models::User> {
match self {
DataBase::Sqlite(pool) => sqlite::sqlite_user(pool, id).await,
DataBase::Postgres(pool) => todo!(),
}
}
/// Tries to create a user and returns the user's id if successful
pub async fn create_user(&self, name: String) -> DbResult<u32> {
match self {
DataBase::Sqlite(pool) => sqlite::sqlite_user_create(pool, name).await,
DataBase::Postgres(pool) => todo!(),
}
}

View file

@ -2,7 +2,7 @@ pub struct Chapter {
pub id: u32,
pub title: String,
pub text: String,
pub creation_data: String,
pub creation_date: String,
pub book_id: u32,
pub author_id: u32,
}

View file

@ -1,5 +1,99 @@
//! Module containing database code for SQLite
use super::models::{Book, Chapter, User};
use super::{DbError, DbResult};
use serde::de;
use sqlx::{Pool, Row, Sqlite};
pub fn sqlite_chapter(pool: &sqlx::Pool<sqlx::Sqlite>, id: u32) -> super::models::Chapter {
todo!()
pub async fn sqlite_book(pool: &Pool<Sqlite>, id: u32) -> DbResult<Book> {
let row = sqlx::query("SELECT * FROM users WHERE user_id = ?")
.bind(id)
.fetch_one(pool)
.await?;
let book = Book {
id,
title: row.get("book_title"),
description: row.get("book_description"),
creation_date: row.get("book_creation_date"),
author_id: row.get("author_id"),
};
Ok(book)
}
pub async fn sqlite_book_create(
pool: &Pool<Sqlite>,
title: String,
description: String,
author_id: u32,
) -> DbResult<u32> {
let id = sqlx::query("INSERT INTO books (title, description, author_id, book_creation_date) VALUES ( ?1, ?2, ?3, ?4 )")
.bind(title)
.bind(description)
.bind(author_id)
.bind(chrono::Local::now().timestamp())
.execute(pool)
.await?
.last_insert_rowid() as u32;
Ok(id)
}
pub async fn sqlite_chapter(pool: &Pool<Sqlite>, id: u32) -> DbResult<Chapter> {
let row = sqlx::query("SELECT * FROM chapters WHERE chapter_id = ?")
.bind(id)
.fetch_one(pool)
.await?;
let chapter = Chapter {
id,
title: row.get("chapter_title"),
text: row.get("chapter_text"),
creation_date: row.get("chapter_creation_date"),
book_id: row.get("book_id"),
author_id: row.get("author_id"),
};
Ok(chapter)
}
pub async fn sqlite_chapter_create(
pool: &Pool<Sqlite>,
title: String,
text: String,
book_id: u32,
author_id: u32,
) -> DbResult<u32> {
let id = sqlx::query("INSERT INTO chapters (chapter_title, chapter_text, book_id, author_id, chapter_creation_date) VALUES ( ?1, ?2, ?3, ?4, ?5 )")
.bind(title)
.bind(text)
.bind(book_id)
.bind(author_id)
.bind(chrono::Local::now().timestamp())
.execute(pool)
.await?
.last_insert_rowid() as u32;
Ok(id)
}
pub async fn sqlite_user(pool: &Pool<Sqlite>, id: u32) -> DbResult<User> {
let row = sqlx::query("SELECT * FROM users WHERE user_id = ?")
.bind(id)
.fetch_one(pool)
.await?;
let user = User {
id,
name: row.get("name"),
};
Ok(user)
}
pub async fn sqlite_user_create(pool: &Pool<Sqlite>, name: String) -> DbResult<u32> {
let id = sqlx::query("INSERT INTO users (name) VALUES ( ? )")
.bind(name)
.execute(pool)
.await?
.last_insert_rowid() as u32;
Ok(id)
}