Бэкенд: Добавлены владельцы автомобилей

This commit is contained in:
Сергей Полевой 2023-04-02 17:39:56 +04:00
parent 2c90088b45
commit f7eb534027
7 changed files with 199 additions and 2 deletions

View File

@ -1,4 +1,5 @@
pub mod client;
pub mod car_station;
pub mod car;
pub mod rent;
pub mod rent;
pub mod owner;

View File

@ -0,0 +1,59 @@
use std::sync::Mutex;
use crate::models::client::*;
use actix_web::{web, get, post, patch, delete, Responder, HttpResponse};
use crate::State;
#[get("/")]
pub async fn get_owners(state: web::Data<Mutex<State>>) -> impl Responder {
match state.lock() {
Ok(guard) => match guard.owner_repository.read_all().await {
Ok(result) => HttpResponse::Ok().json(result),
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
},
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
}
}
#[get("/{id}")]
pub async fn get_owner(state: web::Data<Mutex<State>>, path: web::Path<(u32, )>) -> impl Responder {
match state.lock() {
Ok(guard) => match guard.owner_repository.read(path.into_inner().0).await {
Ok(result) => HttpResponse::Ok().json(result),
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
},
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
}
}
#[post("/")]
pub async fn create_owner(state: web::Data<Mutex<State>>, json: web::Json<BindingClient>) -> impl Responder {
match state.lock() {
Ok(guard) => match guard.owner_repository.create(json.0).await {
Ok(result) => HttpResponse::Ok().json(result),
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
},
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
}
}
#[patch("/{id}")]
pub async fn update_owner(state: web::Data<Mutex<State>>, json: web::Json<BindingClient>, path: web::Path<(u32, )>) -> impl Responder {
match state.lock() {
Ok(guard) => match guard.owner_repository.update(path.into_inner().0, json.0).await {
Ok(result) => HttpResponse::Ok().json(result),
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
},
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
}
}
#[delete("/{id}")]
pub async fn delete_owner(state: web::Data<Mutex<State>>, path: web::Path<(u32, )>) -> impl Responder {
match state.lock() {
Ok(guard) => match guard.owner_repository.delete(path.into_inner().0).await {
Ok(result) => HttpResponse::Ok().json(result),
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
},
Err(error) => HttpResponse::InternalServerError().json(error.to_string())
}
}

View File

@ -1,3 +1,5 @@
use storages::traits::OwnerRepository;
use crate::storages::traits::{CarRepository, CarStationRepository, ClientRepository, RentRepository};
pub mod endpoints;
@ -8,5 +10,6 @@ pub struct State {
pub car_repository: Box<dyn CarRepository + Send>,
pub car_station_repository: Box<dyn CarStationRepository + Send>,
pub client_repository: Box<dyn ClientRepository + Send>,
pub owner_repository: Box<dyn OwnerRepository + Send>,
pub rent_repository: Box<dyn RentRepository + Send>
}

View File

@ -8,10 +8,12 @@ use backend::storages::postgres::car::PostgresCarRepository;
use backend::storages::postgres::car_station::PostgresCarStationRepository;
use backend::storages::postgres::client::PostgresClientRepository;
use backend::storages::postgres::rent::PostgresRentRepository;
use backend::storages::postgres::owner::PostgresOwnerRepository;
use backend::endpoints::car_station::*;
use backend::endpoints::car::*;
use backend::endpoints::client::*;
use backend::endpoints::rent::*;
use backend::endpoints::owner::*;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
@ -34,12 +36,15 @@ async fn main() -> std::io::Result<()> {
let client_repository = PostgresClientRepository { connection: Arc::clone(&client) };
let owner_repository = PostgresOwnerRepository { connection: Arc::clone(&client) };
let rent_repository = PostgresRentRepository { connection: Arc::clone(&client) };
let state = Data::new(Mutex::new(State {
car_repository: Box::new(car_repository),
car_station_repository: Box::new(car_station_repository),
client_repository: Box::new(client_repository),
owner_repository: Box::new(owner_repository),
rent_repository: Box::new(rent_repository)
}));
@ -62,6 +67,14 @@ async fn main() -> std::io::Result<()> {
.service(update_client)
.service(delete_client)
)
.service(
web::scope("/owners")
.service(get_owners)
.service(get_owner)
.service(create_owner)
.service(update_owner)
.service(delete_owner)
)
.service(
web::scope("/car_stations")
.service(get_car_stations)

View File

@ -1,4 +1,5 @@
pub mod client;
pub mod car_station;
pub mod car;
pub mod rent;
pub mod rent;
pub mod owner;

View File

@ -0,0 +1,111 @@
use tokio_postgres::Client as PgClient;
use std::sync::Arc;
use crate::models::client::{BindingClient, Client};
use crate::storages::traits::OwnerRepository;
use async_trait::async_trait;
pub struct PostgresOwnerRepository {
pub connection: Arc<PgClient>
}
#[async_trait]
impl OwnerRepository for PostgresOwnerRepository {
async fn create(&self, client: BindingClient) -> Result<Client, String> {
let result = self.connection.query(
"INSERT INTO Owner(name, surname, middlename, phone) \
VALUES ($1, $2, $3, $4) RETURNING *",
&[&client.name, &client.surname, &client.middlename, &client.phone]
).await;
if let Ok(rows) = &result {
let row = rows.get(0).unwrap();
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err("Something gone wrong during creation of Owner".to_owned())
}
}
async fn read(&self, id: u32) -> Result<Client, String> {
let result= self.connection.query(
"SELECT * FROM Owner WHERE id = $1", &[&id]
).await;
if let Ok(rows) = result {
let row = rows.get(0).ok_or("Owner not found".to_owned())?;
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err("Something gone wrong during reading of Owner".to_owned())
}
}
async fn read_all(&self) -> Result<Vec<Client>, String> {
let result = self.connection.query(
"SELECT * FROM Owner", &[]
).await;
if let Ok(rows) = result {
Ok(
rows.into_iter().map(|r| Client {
id: r.get("id"),
name: r.get("name"),
surname: r.get("surname"),
middlename: r.get("middlename"),
phone: r.get("phone")
}).collect()
)
} else {
Err("Something gone wrong during reading Owner".to_owned())
}
}
async fn update(&self, id: u32, client: BindingClient) -> Result<Client, String> {
let result = self.connection.query(
"UPDATE Owner SET name = $1, surname = $2, middlename = $3, phone = $4 \
WHERE id = $5 RETURNING *",
&[&client.name, &client.surname, &client.middlename, &client.phone, &id]
).await;
if let Ok(rows) = result {
let row = rows.get(0).unwrap();
Ok(Client {
id: row.get("id"),
name: row.get("name"),
surname: row.get("surname"),
middlename: row.get("middlename"),
phone: row.get("phone")
})
} else {
Err("Something gone wrong during updating of Owner".to_owned())
}
}
async fn delete(&self, id: u32) -> Result<(), String> {
let result = self.connection.execute(
"DELETE FROM Owner WHERE id = $1",
&[&id]
).await;
if let Ok(rows) = result {
if rows == 0 {
Err("Owner not found".to_owned())
} else {
Ok(())
}
} else {
Err("Something gone wrong during deleting of Owner".to_owned())
}
}
}

View File

@ -38,4 +38,13 @@ pub trait RentRepository {
async fn read_all(&self) -> Result<Vec<Rent>, String>;
async fn update(&self, id: u32, rent: BindingRent) -> Result<Rent, String>;
async fn delete(&self, id: u32) -> Result<(), String>;
}
#[async_trait]
pub trait OwnerRepository {
async fn create(&self, client: BindingClient) -> Result<Client, String>;
async fn read(&self, id: u32) -> Result<Client, String>;
async fn read_all(&self) -> Result<Vec<Client>, String>;
async fn update(&self, id: u32, client: BindingClient) -> Result<Client, String>;
async fn delete(&self, id: u32) -> Result<(), String>;
}