Skip to content

Commit

Permalink
ajout des trajet
Browse files Browse the repository at this point in the history
  • Loading branch information
thybux committed Apr 29, 2024
1 parent 004725b commit 475fc16
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 26 deletions.
4 changes: 3 additions & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ dotenv_codegen = "0.15.0"
serde = { version = "1.0.197", features = ["derive"] }
dirs = "5.0.1"
bcrypt = "0.15.1"
sqlx = { version = "^0.7.4", features = ["mysql", "runtime-tokio-rustls", "macros"] }
sqlx = { version = "0.5.13", default-features = false, features = ["mysql", "runtime-tokio-rustls"] }
sqlx-macros = "0.7.4"
syn = { version = "2.0", features = ["full"] }
148 changes: 125 additions & 23 deletions common/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use bcrypt::{hash, verify, DEFAULT_COST};
use serde::Serialize;
use sqlx::mysql::MySqlPoolOptions;
use sqlx::MySqlPool;
use sqlx::mysql::MySqlQueryResult;
use sqlx::{Error as SqlxError, Error, MySqlPool, Row, Transaction};
use sqlx::{self, MySql, Pool, query, query_scalar};
use sqlx_macros::FromRow;

#[derive(Debug)]
pub struct Db {
Expand All @@ -11,8 +15,23 @@ pub struct Db {
pool: MySqlPool,
}

#[derive(Debug)]
struct Activity {
name: String,
address: String,
city: String,
}
#[derive(Debug, FromRow, Serialize)]
pub struct ActivityDetails {
name: String,
address: String,
city: String,
depart: String,
arrive: String,
}

impl Db {
pub async fn new() -> Result<Db, sqlx::Error> {
pub async fn new() -> Result<Db, Error> {
let host = "db-mysql-fra1-63257-do-user-16108155-0.c.db.ondigitalocean.com";
let password = "AVNS_Yv2uBhNARgrljcVnjR9";
let port = 25060;
Expand All @@ -36,26 +55,106 @@ impl Db {
pool,
})
}
pub async fn fetch_activity_details(self, user_email: &str, activity_description: &str) -> Result<Vec<ActivityDetails>, sqlx::Error> {
let user_id: i32 = sqlx::query("SELECT id FROM user WHERE email = ?")
.bind(user_email)
.fetch_one(&self.pool)
.await?
.try_get(0)?;

let result = sqlx::query_as::<_, ActivityDetails>(
"SELECT activity.name, activity.address, activity.city, travel.depart, travel.arrive
FROM activity
JOIN travel ON activity.id = travel.activity_id
WHERE travel.id_user = ? AND travel.description = ? ")
.bind(user_id)
.bind(activity_description.to_string())
.fetch_all(&self.pool)
.await?;

Ok(result)
}

pub async fn add_activity_and_travel(
&self,
email: &str,
activity_name: String,
address: String,
city: String,
description: &str,
transport: &str,
depart: &str,
arrive: &str,
) -> Result<(), sqlx::Error> {

let mut tx: Transaction<'_, MySql> = self.pool.begin().await?;
let address_clone= address.clone();
// Check for existing activity
let activity_id: Option<i32> =
sqlx::query_scalar("SELECT id FROM activity WHERE address = ?")
.bind(address)
.fetch_optional(&mut tx)
.await?;

let activity_id = match activity_id {
Some(id) => id,
None => {
// Insert new activity
let result: MySqlQueryResult = sqlx::query(
"INSERT INTO activity (name, address, city) VALUES (?, ?, ?)",
)
.bind(activity_name)
.bind(address_clone)
.bind(city)
.execute(&mut tx)
.await?;
result.last_insert_id() as i32
}
};

// Find user ID by email
let user_id: Option<i32> = sqlx::query_scalar("SELECT id FROM user WHERE email = ?")
.bind(email)
.fetch_optional(&mut tx)
.await?;
if let Some(user_id) = user_id {
// Insert into travel
sqlx::query(
"INSERT INTO travel (id_user, description, activity_id, transport, depart, arrive) VALUES (?, ?, ?, ?, ?, ?)"
)
.bind(user_id)
.bind(description)
.bind(activity_id)
.bind(transport)
.bind(depart)
.bind(arrive)
.execute(&mut tx)
.await?;
}

tx.commit().await?;

Ok(())
}

pub async fn create_account(
&self,
user_email: &str,
user_password: &str,
user_name: &str,
user_last_name: &str,
) -> Result<bool, sqlx::Error> {
) -> Result<bool, Error> {
let hashed_password = match hash(user_password, DEFAULT_COST) {
Ok(h) => h,
Err(_) => panic!("Failed to hash password"),
};

let result = sqlx::query!(
"INSERT INTO user (email, password, first_name, last_name) VALUES (?, ?, ?, ?)",
user_email,
hashed_password,
user_name,
user_last_name
)
let result = sqlx::query(
"INSERT INTO user (email, password, first_name, last_name) VALUES (?, ?, ?, ?)",)
.bind(user_email)
.bind(hashed_password)
.bind(user_name)
.bind(user_last_name)
.execute(&self.pool)
.await?;

Expand All @@ -66,23 +165,26 @@ impl Db {
}
}

pub async fn login(&self, user_email: &str, user_password: &str) -> Result<bool, sqlx::Error> {
let user_record = sqlx::query!("SELECT password FROM user WHERE email = ?", user_email)
pub async fn login(&self, user_email: &str, user_password: &str) -> Result<bool, Error> {
let result = sqlx::query("SELECT password FROM user WHERE email = ?")
.bind(user_email)
.fetch_one(&self.pool)
.await;

match user_record {
Ok(record) => {
if let Some(stored_password) = record.password {
let password_matched = verify(user_password, &stored_password)
.map_err(|_| sqlx::Error::RowNotFound)?;
match result {
Ok(row) => {
let stored_password: Option<String> = row.try_get("password")?;
if let Some(password) = stored_password {
// Verify the password against the hash stored in the database
let password_matched = verify(user_password, &password)
.map_err(|_| Error::RowNotFound)?; // Adjust error handling as necessary

Ok(password_matched)
} else {
Ok(false) // Le mot de passe est null
Ok(false) // Password is null
}
}
Err(_) => Ok(false), // Aucun enregistrement trouvé pour l'e-mail donné
},
Err(e) => Err(e), // Pass along any SQL error
}
}
}
Expand All @@ -91,7 +193,7 @@ impl Db {
mod tests {
use super::*;

#[tokio::test]
/*#[tokio::test]
async fn test_connexion_bd() {
let db = Db::new().await.unwrap();
let connection_result = db.pool.acquire().await;
Expand All @@ -114,7 +216,7 @@ mod tests {
.await
.unwrap();
// Supprimer l'utilisateur après le test
let delete_result = sqlx::query!("DELETE FROM user WHERE email = ?", user_email)
let delete_result = sqlx::query("DELETE FROM user WHERE email = ?", user_email)
.execute(&lets_db.pool)
.await;
assert!(
Expand All @@ -141,5 +243,5 @@ mod tests {
.login(false_user_email, false_user_password)
.await;
assert!(!false_login_result.unwrap());
}
}*/
}
62 changes: 60 additions & 2 deletions services/eat/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use common::db::Db;
use rocket::http::Status;
use rocket::serde::json::Json;
use rocket::serde::Deserialize;
use rocket::State;
use serde_json::Value;
use common::db::{ActivityDetails, Db};


#[macro_use]
extern crate rocket;
Expand All @@ -17,6 +19,24 @@ struct CityCoord {
long: f64,
}

#[derive(Deserialize)]
struct TravelRequest {
email: String,
activity_name: String,
address: String,
city: String,
description: String,
transport: String,
depart: String,
arrive: String,
}

#[derive(Debug, Serialize)]
struct ApiResponse {
status: String,
message: String,
}

#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
struct AccountCreationData {
Expand Down Expand Up @@ -62,6 +82,44 @@ async fn auth(
}
}

#[get("/fetch_activities?<email>&<description>")]
async fn get_activities(email: String, description: String) -> Result<Json<Vec<ActivityDetails>>, Status> {
let db = Db::new().await.expect("coucou");
match db.fetch_activity_details(&email, &description).await {
Ok(activity_details) => Ok(Json(activity_details)),
Err(e) => {
eprintln!("Error fetching activity details: {}", e);
Err(Status::InternalServerError)
},
}
}

#[post("/add_activity_travel", data = "<travel_request>")]
async fn add_activity_travel(
db: &rocket::State<Db>,
travel_request: Json<TravelRequest>,
) -> Json<ApiResponse> {
match db.add_activity_and_travel(
&travel_request.email,
travel_request.activity_name.clone(),
travel_request.address.clone(),
travel_request.city.clone(),
&travel_request.description,
&travel_request.transport,
&travel_request.depart,
&travel_request.arrive,
).await {
Ok(()) => Json(ApiResponse {
status: "success".into(),
message: "Activity and travel added successfully".into(),
}),
Err(e) => Json(ApiResponse {
status: "error".into(),
message: format!("Failed to add activity and travel: {}", e),
}),
}
}

#[post(
"/create_account",
format = "application/json",
Expand Down Expand Up @@ -100,7 +158,7 @@ async fn main() {
let db = Db::new().await.expect("Failed to create database pool");
let rocket_instance = rocket::build()
.manage(db)
.mount("/", routes![index, coord, auth, create_account_route]);
.mount("/", routes![index, coord, auth, create_account_route, add_activity_travel, get_activities]);

match rocket_instance.launch().await {
Ok(_) => println!("Server launched successfully."),
Expand Down

0 comments on commit 475fc16

Please sign in to comment.