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

138
Cargo.lock generated
View file

@ -243,6 +243,21 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.18"
@ -382,6 +397,12 @@ dependencies = [
"alloc-stdlib",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.20.0"
@ -426,6 +447,20 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.6",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
@ -464,6 +499,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.16"
@ -822,6 +863,7 @@ name = "gunnhildr"
version = "0.1.0"
dependencies = [
"actix-web",
"chrono",
"env_logger",
"figment",
"log",
@ -942,6 +984,29 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "1.5.0"
@ -1124,6 +1189,16 @@ dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "language-tags"
version = "0.3.2"
@ -2282,6 +2357,60 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
[[package]]
name = "wasm-bindgen"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
[[package]]
name = "whoami"
version = "1.5.2"
@ -2292,6 +2421,15 @@ dependencies = [
"wasite",
]
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.48.0"

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
actix-web = {version="4.9.0"}
chrono = "0.4.38"
env_logger = "0.11.5"
figment = {version="0.10.19", features=["env"]}
log = "0.4.22"

View file

@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS books(
book_id INTEGER PRIMARY KEY,
book_title TEXT NOT NULL,
book_description TEXT,
book_creation_date TEXT NOT NULL,
book_creation_date INT NOT NULL,
author_id INTEGER NOT NULL,
FOREIGN KEY (author_id) REFERENCES users(user_id) ON DELETE CASCADE
@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS chapters(
chapter_id INTEGER PRIMARY KEY,
chapter_title TEXT NOT NULL,
chapter_text TEXT NOT NULL,
chapter_creation_date TEXT NOT NULL,
chapter_creation_date INT NOT NULL,
book_id INTEGER NOT NULL,
author_id INTEGER NOT NULL,
FOREIGN KEY (book_id) REFERENCES books(book_id) ON DELETE CASCADE,

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)
}