Reorg-ed
This commit is contained in:
21
Cargo.lock
generated
21
Cargo.lock
generated
@@ -273,7 +273,6 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"listenfd",
|
|
||||||
"log",
|
"log",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -962,17 +961,6 @@ version = "0.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "listenfd"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "492158e732f2e2de81c592f0a2427e57e12cd3d59877378fe7af624b6bbe0ca1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"uuid",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@@ -1861,15 +1849,6 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "uuid"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "3.3.0"
|
actix-web = "3.3.0"
|
||||||
actix-rt = "1.1.1"
|
actix-rt = "1.1.1"
|
||||||
listenfd = "0.3.3"
|
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
env_logger = "0.8.2"
|
env_logger = "0.8.2"
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
create sequence products_productid_seq;
|
||||||
|
|
||||||
create table if not exists products
|
create table if not exists products
|
||||||
(
|
(
|
||||||
productid integer not null
|
productid integer not null
|
||||||
constraint pk_products
|
constraint pk_products
|
||||||
primary key,
|
primary key DEFAULT nextval('products_productid_seq'),
|
||||||
productname text not null,
|
productname text not null,
|
||||||
created_at timestamp not null default current_timestamp
|
created_at timestamp not null default current_timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
alter sequence products_productid_seq
|
||||||
|
owned by products.productid;
|
||||||
@@ -1,8 +1,14 @@
|
|||||||
|
create sequence orders_ordersid_seq;
|
||||||
|
|
||||||
|
|
||||||
create table if not exists orders
|
create table if not exists orders
|
||||||
(
|
(
|
||||||
orderid integer not null
|
orderid integer not null
|
||||||
constraint pk_orders
|
constraint pk_orders
|
||||||
primary key,
|
primary key default nextval('orders_ordersid_seq'),
|
||||||
customer_email text not null,
|
customer_email text not null,
|
||||||
created_at timestamp not null default current_timestamp
|
created_at timestamp not null default current_timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
alter sequence orders_ordersid_seq
|
||||||
|
owned by orders.orderid;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod product_controller;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
use crate::models::product::Product;
|
||||||
|
use actix_web::{get, web, HttpResponse, Responder};
|
||||||
|
|
||||||
|
#[get("/products")]
|
||||||
|
async fn find_all() -> impl Responder {
|
||||||
|
let products = Product::find_all().expect("Error fetching all Products");
|
||||||
|
HttpResponse::Ok().json(products)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/product/{id}")]
|
||||||
|
async fn find(id: web::Path<i32>) -> impl Responder {
|
||||||
|
let product = Product::find(id.into_inner()).expect("Error fetching Product");
|
||||||
|
HttpResponse::Ok().json(product)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn routes(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg.service(find_all);
|
||||||
|
cfg.service(find);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::api_error::ApiError;
|
use crate::utils::api_error::ApiError;
|
||||||
use diesel::pg::PgConnection;
|
use diesel::pg::PgConnection;
|
||||||
use diesel::r2d2::ConnectionManager;
|
use diesel::r2d2::ConnectionManager;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
@@ -14,18 +14,18 @@ lazy_static! {
|
|||||||
static ref POOL: Pool = {
|
static ref POOL: Pool = {
|
||||||
let db_url = env::var("DATABASE_URL").expect("Database url not set");
|
let db_url = env::var("DATABASE_URL").expect("Database url not set");
|
||||||
let manager = ConnectionManager::<PgConnection>::new(db_url);
|
let manager = ConnectionManager::<PgConnection>::new(db_url);
|
||||||
Pool::new(manager).expect("Failed to create db pool")
|
Pool::new(manager).expect("Failed to create config pool")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
info!("Initializing DB");
|
info!("Initializing DB");
|
||||||
lazy_static::initialize(&POOL);
|
lazy_static::initialize(&POOL);
|
||||||
let conn = connection().expect("Failed to get db connection");
|
let conn = get_connection().expect("Failed to get config connection");
|
||||||
embedded_migrations::run(&conn).unwrap();
|
embedded_migrations::run(&conn).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection() -> Result<DbConnection, ApiError> {
|
pub fn get_connection() -> Result<DbConnection, ApiError> {
|
||||||
POOL.get()
|
POOL.get()
|
||||||
.map_err(|e| ApiError::new(500, format!("Failed getting db connection: {}", e)))
|
.map_err(|e| ApiError::new(500, format!("Failed getting config connection: {}", e)))
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod db_pool;
|
||||||
|
|||||||
36
src/main.rs
36
src/main.rs
@@ -7,36 +7,30 @@ extern crate diesel_migrations;
|
|||||||
|
|
||||||
use actix_web::{App, HttpServer};
|
use actix_web::{App, HttpServer};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use listenfd::ListenFd;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use crate::api::product_controller;
|
||||||
|
use config::db_pool;
|
||||||
|
|
||||||
mod db;
|
|
||||||
mod product;
|
|
||||||
mod schema;
|
mod schema;
|
||||||
mod api_error;
|
mod utils;
|
||||||
|
mod models;
|
||||||
|
mod api;
|
||||||
|
mod config;
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
db::init();
|
db_pool::init();
|
||||||
|
|
||||||
let mut listenfd = ListenFd::from_env();
|
|
||||||
let mut server = HttpServer::new(||
|
|
||||||
App::new()
|
|
||||||
.configure(product::init_routes)
|
|
||||||
);
|
|
||||||
|
|
||||||
server = match listenfd.take_tcp_listener(0)? {
|
|
||||||
Some(listener) => server.listen(listener)?,
|
|
||||||
None => {
|
|
||||||
let host = env::var("HOST").expect("Host not set in .env file");
|
|
||||||
let port = env::var("PORT").expect("Port not set in .env file");
|
|
||||||
server.bind(format!("{}:{}", host, port))?
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let bind_address = format!("{}:{}",
|
||||||
|
env::var("HOST").expect("Host not set in .env file"),
|
||||||
|
env::var("PORT").expect("Port not set in .env file"));
|
||||||
info!("Starting Server");
|
info!("Starting Server");
|
||||||
server.run().await
|
HttpServer::new(||
|
||||||
|
App::new()
|
||||||
|
.configure(product_controller::routes)
|
||||||
|
).bind(bind_address)?
|
||||||
|
.run().await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod product;
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
use crate::config::db_pool;
|
||||||
|
use crate::schema::products;
|
||||||
|
use chrono::{NaiveDateTime, Utc};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::utils::api_error::ApiError;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, AsChangeset)]
|
||||||
|
#[table_name = "products"]
|
||||||
|
pub struct ProductMessage {
|
||||||
|
pub productid: i32,
|
||||||
|
pub productname: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Queryable, Insertable)]
|
||||||
|
#[table_name = "products"]
|
||||||
|
pub struct Product {
|
||||||
|
pub productid: i32,
|
||||||
|
pub productname: String,
|
||||||
|
pub created_at: NaiveDateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Product {
|
||||||
|
pub fn find_all() -> Result<Vec<Self>, ApiError> {
|
||||||
|
let conn = db_pool::get_connection()?;
|
||||||
|
|
||||||
|
let products = products::table
|
||||||
|
.load::<Product>(&conn)?;
|
||||||
|
|
||||||
|
Ok(products)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find(id: i32) -> Result<Self, ApiError> {
|
||||||
|
let conn = db_pool::get_connection()?;
|
||||||
|
|
||||||
|
let product = products::table
|
||||||
|
.filter(products::productid.eq(id))
|
||||||
|
.first(&conn)?;
|
||||||
|
|
||||||
|
Ok(product)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ProductMessage> for Product {
|
||||||
|
fn from(product: ProductMessage) -> Self {
|
||||||
|
Product {
|
||||||
|
productid: product.productid,
|
||||||
|
productname: product.productname,
|
||||||
|
created_at: Utc::now().naive_utc(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/schema.rs
Normal file
32
src/schema.rs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
table! {
|
||||||
|
order_details (orderid, productid) {
|
||||||
|
orderid -> Int4,
|
||||||
|
productid -> Int4,
|
||||||
|
quantity -> Int4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
orders (orderid) {
|
||||||
|
orderid -> Int4,
|
||||||
|
customer_email -> Text,
|
||||||
|
created_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
products (productid) {
|
||||||
|
productid -> Int4,
|
||||||
|
productname -> Text,
|
||||||
|
created_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinable!(order_details -> orders (orderid));
|
||||||
|
joinable!(order_details -> products (productid));
|
||||||
|
|
||||||
|
allow_tables_to_appear_in_same_query!(
|
||||||
|
order_details,
|
||||||
|
orders,
|
||||||
|
products,
|
||||||
|
);
|
||||||
13
src/utils/constants.rs
Normal file
13
src/utils/constants.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Messages
|
||||||
|
// pub const MESSAGE_OK: &str = "ok";
|
||||||
|
// pub const MESSAGE_CAN_NOT_FETCH_DATA: &str = "Can not fetch data";
|
||||||
|
// pub const MESSAGE_CAN_NOT_INSERT_DATA: &str = "Can not insert data";
|
||||||
|
// pub const MESSAGE_CAN_NOT_UPDATE_DATA: &str = "Can not update data";
|
||||||
|
// pub const MESSAGE_CAN_NOT_DELETE_DATA: &str = "Can not delete data";
|
||||||
|
// pub const MESSAGE_INTERNAL_SERVER_ERROR: &str = "Internal Server Error";
|
||||||
|
//
|
||||||
|
// // Misc
|
||||||
|
// pub const EMPTY: &str = "";
|
||||||
|
//
|
||||||
|
// // ignore routes
|
||||||
|
// pub const IGNORE_ROUTES: [&str; 3] = ["/api/ping", "/api/auth/signup", "/api/auth/login"];
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod api_error;
|
||||||
|
pub mod constants;
|
||||||
|
|||||||
Reference in New Issue
Block a user