Create database link and implement get_member

This commit is contained in:
Sebastian H. Gabrielli 2023-12-23 23:39:23 +01:00
parent ab81d241df
commit 72f73a89e1
9 changed files with 1833 additions and 30 deletions

1653
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,4 +7,6 @@ edition = "2021"
[dependencies]
rocket = {version = "0.5.0", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
sea-orm = { version = "^0.12.0", features = [ "sqlx-sqlite", "runtime-tokio-native-tls", "macros", "mock" ] }
futures = "0.3.28"

34
src/entities/members.rs Normal file
View File

@ -0,0 +1,34 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "members")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32,
#[sea_orm(column_name = "ntnuUsername")]
pub ntnu_username: String,
#[sea_orm(column_name = "firstName")]
pub first_name: String,
#[sea_orm(column_name = "lastName")]
pub last_name: String,
pub email: String,
pub balance: i32,
#[sea_orm(column_name = "imagePreference")]
pub image_preference: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::rfid_cards::Entity")]
RfidCards,
}
impl Related<super::rfid_cards::Entity> for Entity {
fn to() -> RelationDef {
Relation::RfidCards.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

6
src/entities/mod.rs Normal file
View File

@ -0,0 +1,6 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
pub mod prelude;
pub mod members;
pub mod rfid_cards;

4
src/entities/prelude.rs Normal file
View File

@ -0,0 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
pub use super::members::Entity as Members;
pub use super::rfid_cards::Entity as RfidCards;

View File

@ -0,0 +1,33 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "rfid_cards")]
pub struct Model {
#[sea_orm(column_name = "cardId", primary_key, auto_increment = false)]
pub card_id: String,
#[sea_orm(column_name = "cardComment")]
pub card_comment: String,
pub member_id: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::members::Entity",
from = "Column::MemberId",
to = "super::members::Column::Id",
on_update = "NoAction",
on_delete = "NoAction"
)]
Members,
}
impl Related<super::members::Entity> for Entity {
fn to() -> RelationDef {
Relation::Members.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,9 +1,17 @@
// Webserver
#[macro_use] extern crate rocket;
use rocket::{State, Error};
use rocket::response::status;
use rocket::serde::{Serialize, Deserialize, json::Json};
// Database
use sea_orm::*;
mod setup;
use setup::set_up_db;
mod entities;
use entities::{prelude::*, *};
#[derive(Serialize, Deserialize)]
struct RfidCard {
@ -13,40 +21,90 @@ struct RfidCard {
#[derive(Serialize, Deserialize)]
struct Member {
id: u64,
id: i32,
ntnuUsername: String,
firstName: String,
lastName: String,
email: String,
balance: i64,
balance: i32,
imagePreference: String,
rfidCards: Vec<RfidCard>
}
#[derive(Responder)]
#[response(status = 500, content_type = "json")]
struct ErrorResponder {
message: String
}
impl From<DbErr> for ErrorResponder {
fn from(err: DbErr) -> ErrorResponder {
ErrorResponder { message: err.to_string() }
}
}
impl From<String> for ErrorResponder {
fn from(string: String) -> ErrorResponder {
ErrorResponder { message: string }
}
}
impl From<&str> for ErrorResponder {
fn from(str: &str) -> ErrorResponder {
ErrorResponder { message: str.to_owned().into() }
}
}
#[get("/")]
fn index() -> &'static str {
"Hello, world!\nNothing useful is served here."
}
#[get("/member/<memberId>")]
fn get_member(memberId: u64) -> Json<Member> {
let sebasthg = Member {
id: 1,
ntnuUsername: "sebasthg".to_string(),
firstName: "Sebastian".to_string(),
lastName: "Gabrielli".to_string(),
email: "sebastian@fastmail.mx".to_string(),
balance: 50,
imagePreference: "Money".to_string(),
rfidCards: vec![ RfidCard { cardId: "0364249683".to_string(), cardComment: "Studentkort".to_string() } ]
async fn get_member(db: &State<DatabaseConnection>, memberId: i32) -> Result<Json<Member>, ErrorResponder> {
let db = db as &DatabaseConnection;
let database_member;
match Members::find_by_id(memberId).one(db).await? {
Some(model) => database_member = model,
None => {
return Err(
ErrorResponder {
message: format!("Failed to fetch member by ID. memberId: {}", memberId)
}
);
},
};
Json(sebasthg)
let member_rfid_cards: Vec<rfid_cards::Model> = database_member.find_related(RfidCards).all(db).await?;
let rfids: Vec<RfidCard> = member_rfid_cards.iter().map(|model| RfidCard {
cardId: model.card_id.clone(),
cardComment: model.card_comment.clone()
}).collect();
let member = Member {
id: database_member.id,
ntnuUsername: database_member.ntnu_username,
firstName: database_member.first_name,
lastName: database_member.last_name,
email: database_member.email,
balance: database_member.balance,
imagePreference: database_member.image_preference,
rfidCards: rfids
};
Ok(Json(member))
}
#[launch]
fn rocket() -> _ {
async fn rocket() -> _ {
let db = match set_up_db().await {
Ok(db) => db,
Err(err) => panic!("{}", err)
};
rocket::build()
.mount("/", routes![index])
.mount("/", routes![get_member])
.manage(db)
.mount("/", routes![
index,
get_member
])
}

39
src/setup.rs Normal file
View File

@ -0,0 +1,39 @@
use sea_orm::*;
const DATABASE_URL: &str = "sqlite:./test.db";
const DB_NAME: &str = "omegav";
pub(super) async fn set_up_db() -> Result<DatabaseConnection, DbErr> {
let db = Database::connect(DATABASE_URL).await?;
let db = match db.get_database_backend() {
DbBackend::MySql => {
db.execute(Statement::from_string(
db.get_database_backend(),
format!("CREATE DATABASE IF NOT EXISTS `{}`;", DB_NAME),
))
.await?;
let url = format!("{}/{}", DATABASE_URL, DB_NAME);
Database::connect(&url).await?
}
DbBackend::Postgres => {
db.execute(Statement::from_string(
db.get_database_backend(),
format!("DROP DATABASE IF EXISTS \"{}\";", DB_NAME),
))
.await?;
db.execute(Statement::from_string(
db.get_database_backend(),
format!("CREATE DATABASE \"{}\";", DB_NAME),
))
.await?;
let url = format!("{}/{}", DATABASE_URL, DB_NAME);
Database::connect(&url).await?
}
DbBackend::Sqlite => db,
};
Ok(db)
}

BIN
test.db

Binary file not shown.