From f25d37318e7873bf4f5ca58bcb850bed70ae77a6 Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 16 Dec 2020 20:00:42 +0530 Subject: add product/ endpoints --- src/bin/server.rs | 17 +++++++++++++++-- src/handlers/mod.rs | 1 + src/handlers/product.rs | 25 ++++++++++++++++--------- src/handlers/users.rs | 28 ++++++++++++++-------------- src/models.rs | 36 ++++++++++++++++++++++++++++++++---- src/schema.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 6 files changed, 117 insertions(+), 31 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 180c5bc..601d514 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -5,7 +5,7 @@ use actix_web::{web, App, HttpServer}; use diesel::r2d2::{ConnectionManager, Pool}; use diesel::MysqlConnection; use furby::handlers::smoke::manual_hello; -use furby::handlers::{product, users}; +use furby::handlers::{cart_items, product, users}; use rand::Rng; #[actix_web::main] @@ -42,13 +42,26 @@ async fn main() -> std::io::Result<()> { ) .service( web::scope("/product") - .route("/{id}", web::get().to(product::product_details)) + .route("/catalog", web::get().to(product::get_all_products)) .route("/new", web::post().to(product::new_product)) + .route("/{id}", web::get().to(product::product_details)) .route( "/update_product/{id}", web::post().to(product::update_product), ), ) + .service( + web::scope("/cart") + .route( + "/items", + web::get().to(cart_items::get_user_cart_items), + ) + .route("/add", web::post().to(cart_items::add_to_cart)) + .route( + "/remove", + web::post().to(cart_items::remove_from_cart), + ), + ) .route("/hey", web::get().to(manual_hello)) }) .bind("127.0.0.1:7878")? diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 41bba8d..28591bc 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,3 +1,4 @@ +pub mod cart_items; pub mod product; pub mod smoke; pub mod users; diff --git a/src/handlers/product.rs b/src/handlers/product.rs index 60a4684..788efb3 100644 --- a/src/handlers/product.rs +++ b/src/handlers/product.rs @@ -1,4 +1,4 @@ -use crate::models::{NewProduct, Product}; +use crate::models::{NewProduct, Product, UpdateProduct}; use crate::schema::product::dsl::*; use crate::TPool; @@ -43,14 +43,6 @@ pub async fn product_details( } } -#[derive(Deserialize)] -pub struct UpdateProduct { - name: String, - kind: Option, - price: f32, - description: Option, -} - pub async fn update_product( pool: web::Data, product_id: web::Path, @@ -78,3 +70,18 @@ pub async fn update_product( } } } + +pub async fn get_all_products(pool: web::Data) -> impl Responder { + let conn = pool.get().unwrap(); + info!("Generating and returning catalog ..."); + match product.load::(&conn) { + Ok(products) => { + return HttpResponse::Ok() + .body(serde_json::to_string(&products).unwrap()) + } + Err(_) => { + return HttpResponse::InternalServerError() + .body("Unable to fetch product catalog") + } + } +} diff --git a/src/handlers/users.rs b/src/handlers/users.rs index c7bc870..bff532c 100644 --- a/src/handlers/users.rs +++ b/src/handlers/users.rs @@ -1,5 +1,5 @@ -use crate::models::{Member, NewMember}; -use crate::schema::members::dsl::*; +use crate::models::{Customer, NewCustomer}; +use crate::schema::customer::dsl::*; use crate::TPool; use actix_identity::Identity; @@ -11,14 +11,14 @@ use serde::Deserialize; pub async fn new_user( pool: web::Data, - item: web::Json, + item: web::Json, ) -> impl Responder { let conn = pool.get().unwrap(); - let hashed_item = NewMember { + let hashed_item = NewCustomer { password: hash(&item.password, DEFAULT_COST).unwrap(), ..(item.into_inner()) }; - diesel::insert_into(members) + diesel::insert_into(customer) .values(hashed_item) .execute(&conn) .expect("Coundn't connect to DB"); @@ -31,10 +31,10 @@ pub async fn name_exists( ) -> impl Responder { let conn = pool.get().unwrap(); info!("target: {:?}", item); - if (members + if (customer .filter(username.eq(&item)) .limit(1) - .load::(&conn) + .load::(&conn) .expect("Coundn't connect to DB")) .len() > 0 @@ -59,10 +59,10 @@ pub async fn login( info!("Login hit"); let conn = pool.get().unwrap(); let entered_pass = &login_details.password; - let selected_user = members + let selected_user = customer .filter(username.eq(&login_details.username)) .limit(1) - .first::(&conn) + .first::(&conn) .expect("Couldn't connect to DB"); let hashed_pass = selected_user.password; if verify(entered_pass, &hashed_pass).unwrap() { @@ -89,10 +89,10 @@ pub async fn user_details( let conn = pool.get().unwrap(); let uname = uname.into_inner(); info!("Fetching info for: \"{}\"", uname); - let selected_user = members + let selected_user = customer .filter(username.eq(&uname)) .limit(1) - .first::(&conn); + .first::(&conn); match selected_user { Ok(m) => { info!("Found user: {}", uname); @@ -121,16 +121,16 @@ pub async fn change_password( if let Some(uname) = cookie.identity() { let entered_pass = &password_details.old_password; let new_password = &password_details.new_password; - let selected_user = members + let selected_user = customer .filter(username.eq(&uname)) .limit(1) - .first::(&conn) + .first::(&conn) .expect("Couldn't connect to DB"); let hashed_pass = selected_user.password; if verify(entered_pass, &hashed_pass).unwrap() { let hashed_new_password = hash(&new_password, DEFAULT_COST).unwrap(); - diesel::update(members.filter(id.eq(selected_user.id))) + diesel::update(customer.filter(id.eq(selected_user.id))) .set(password.eq(hashed_new_password)) .execute(&conn) .unwrap(); diff --git a/src/models.rs b/src/models.rs index 6af1af6..acd67a6 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,26 +1,32 @@ -use super::schema::{members, product}; +use super::schema::{cart_items, customer, product, rating, transaction}; use diesel::{Insertable, Queryable}; use serde::{Deserialize, Serialize}; +/* Member */ #[derive(Queryable, Serialize)] -pub struct Member { +pub struct Customer { pub id: i32, pub username: String, pub password: String, pub phone_number: String, pub email_id: String, + pub address: Option, } #[derive(Insertable, Deserialize)] -#[table_name = "members"] -pub struct NewMember { +#[table_name = "customer"] +pub struct NewCustomer { pub username: String, pub password: String, pub phone_number: String, pub email_id: String, + + #[serde(skip_serializing_if = "Option::is_none")] + pub address: Option, } +/* Product */ #[derive(Queryable, Serialize)] pub struct Product { pub id: i32, @@ -42,3 +48,25 @@ pub struct NewProduct { #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, } + +#[derive(Deserialize)] +pub struct UpdateProduct { + pub name: String, + pub kind: Option, + pub price: f32, + pub description: Option, +} + +/* Cart Items */ +#[derive(Queryable, Serialize)] +pub struct CartItem { + pub cart_id: i32, + pub product_id: i32, +} + +#[derive(Insertable, Deserialize)] +#[table_name = "cart_items"] +pub struct AddCartItem { + pub cart_id: i32, + pub product_id: i32, +} diff --git a/src/schema.rs b/src/schema.rs index b6074f2..f08221a 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,10 +1,18 @@ table! { - members (id) { + cart_items (cart_id, product_id) { + cart_id -> Integer, + product_id -> Integer, + } +} + +table! { + customer (id) { id -> Integer, username -> Varchar, password -> Varchar, phone_number -> Varchar, email_id -> Varchar, + address -> Nullable, } } @@ -18,7 +26,36 @@ table! { } } +table! { + rating (id) { + id -> Integer, + comment_text -> Nullable, + comment_date -> Nullable, + product_id -> Nullable, + customer_id -> Nullable, + stars -> Nullable, + } +} + +table! { + transaction (id) { + id -> Integer, + payment_type -> Varchar, + amount -> Float, + customer_id -> Nullable, + } +} + +joinable!(cart_items -> customer (cart_id)); +joinable!(cart_items -> product (product_id)); +joinable!(rating -> customer (customer_id)); +joinable!(rating -> product (product_id)); +joinable!(transaction -> customer (customer_id)); + allow_tables_to_appear_in_same_query!( - members, + cart_items, + customer, product, + rating, + transaction, ); -- cgit v1.2.3