Demonstrate UUID support

develop
cahe 3 years ago
parent 8f554b7e5b
commit 51e12788c3

@ -11,4 +11,5 @@ warp = "0.2"
tokio = { version = "0.2", features = ["macros"] } tokio = { version = "0.2", features = ["macros"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" } serde_json = { version = "1.0" }
sqlx = { version = "0.4.0-beta.1", default-features = false, features = [ "postgres", "runtime-tokio-rustls", "macros" ] } sqlx = { version = "0.4.0-beta.1", default-features = false, features = [ "postgres", "runtime-tokio-rustls", "macros", "uuid" ] }
uuid = { version = "1.2.1", features = [ "serde" ] }

@ -5,14 +5,14 @@ use crate::base::robots;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct GetRobot { pub struct GetRobot {
#[serde(skip_deserializing)] #[serde(skip_deserializing)]
pub id: Option<i64>, pub uuid: Option<uuid::Uuid>,
pub name: String, pub name: String,
} }
impl std::convert::From<robots::Robot> for GetRobot { impl std::convert::From<robots::Robot> for GetRobot {
fn from(r: robots::Robot) -> GetRobot { fn from(r: robots::Robot) -> GetRobot {
GetRobot { GetRobot {
id: Some(r.id), uuid: Some(r.uuid),
name: r.name, name: r.name,
} }
} }

@ -14,9 +14,9 @@ pub async fn add_robot(
let pool = shared.find::<PgSharedPool>().unwrap(); let pool = shared.find::<PgSharedPool>().unwrap();
let mut tx = pool.begin().await?; let mut tx = pool.begin().await?;
let model = robots::Robot::new(0, r.name).try_into()?; let model = robots::Robot::new(uuid::Uuid::nil(), r.name).try_into()?;
let id = postgres::add(tx.as_mut(), model).await?; let uuid = postgres::add(tx.as_mut(), model).await?;
let robot = postgres::get_by_id(tx.as_mut(), id).await?; let robot = postgres::get_by_id(tx.as_mut(), uuid).await?;
tx.commit().await.map_err(|e| HandlingError::DBError(e))?; tx.commit().await.map_err(|e| HandlingError::DBError(e))?;
@ -25,11 +25,11 @@ pub async fn add_robot(
pub async fn get_robot( pub async fn get_robot(
shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: uuid::Uuid,
) -> Result<GetRobot, HandlingError> { ) -> Result<GetRobot, HandlingError> {
let pool = shared.find::<PgSharedPool>().unwrap(); let pool = shared.find::<PgSharedPool>().unwrap();
let mut tx = pool.begin().await?; let mut tx = pool.begin().await?;
Ok(postgres::get_by_id(tx.as_mut(), id).await?.into()) Ok(postgres::get_by_id(tx.as_mut(), uuid).await?.into())
} }
pub async fn get_all( pub async fn get_all(
@ -50,15 +50,15 @@ pub async fn get_all(
pub async fn update_robot( pub async fn update_robot(
shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: uuid::Uuid,
r: GetRobot, r: GetRobot,
) -> Result<GetRobot, HandlingError> { ) -> Result<GetRobot, HandlingError> {
let pool = shared.find::<PgSharedPool>().unwrap(); let pool = shared.find::<PgSharedPool>().unwrap();
let mut tx = pool.begin().await?; let mut tx = pool.begin().await?;
let model = robots::Robot::new(id, r.name).try_into()?; let model = robots::Robot::new(uuid, r.name).try_into()?;
postgres::update(tx.as_mut(), model).await?; postgres::update(tx.as_mut(), model).await?;
let robot = postgres::get_by_id(tx.as_mut(), id).await?; let robot = postgres::get_by_id(tx.as_mut(), uuid).await?;
tx.commit().await.map_err(HandlingError::DBError)?; tx.commit().await.map_err(HandlingError::DBError)?;
@ -67,12 +67,12 @@ pub async fn update_robot(
pub async fn delete_robot( pub async fn delete_robot(
shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: uuid::Uuid,
) -> Result<(), HandlingError> { ) -> Result<(), HandlingError> {
let pool = shared.find::<PgSharedPool>().unwrap(); let pool = shared.find::<PgSharedPool>().unwrap();
let mut tx = pool.begin().await?; let mut tx = pool.begin().await?;
postgres::delete(tx.as_mut(), id).await?; postgres::delete(tx.as_mut(), uuid).await?;
tx.commit().await.map_err(HandlingError::DBError)?; tx.commit().await.map_err(HandlingError::DBError)?;
Ok(()) Ok(())

@ -2,13 +2,13 @@ use crate::simple::HandlingError;
use std::convert::TryFrom; use std::convert::TryFrom;
pub struct Robot { pub struct Robot {
pub id: i64, pub uuid: uuid::Uuid,
pub name: String, pub name: String,
} }
impl Robot { impl Robot {
pub fn new(id: i64, name: String) -> Self { pub fn new(uuid : uuid::Uuid, name: String) -> Self {
Self { id: id, name: name } Self { uuid: uuid, name: name }
} }
} }

@ -19,7 +19,7 @@ where
{ {
pub fn new(tx: &'c mut Box<E>) -> Collection<'c, E> { pub fn new(tx: &'c mut Box<E>) -> Collection<'c, E> {
let all = sqlx::query::<sqlx::Postgres>( let all = sqlx::query::<sqlx::Postgres>(
"SELECT id, name "SELECT id, name, uuid
FROM robots FROM robots
WHERE WHERE
(CASE WHEN $1::BOOLEAN THEN (id = $2::INTEGER) ELSE TRUE END) (CASE WHEN $1::BOOLEAN THEN (id = $2::INTEGER) ELSE TRUE END)
@ -54,8 +54,8 @@ where
Ok(v) => v Ok(v) => v
.into_iter() .into_iter()
.map(|d| { .map(|d| {
let (id, name) = <(i64, String)>::from_row(&d)?; let (_, name, uuid) = <(i64, String, sqlx::types::Uuid)>::from_row(&d)?;
Ok(robots::Robot { id: id, name: name }) Ok(robots::Robot { uuid: uuid::Uuid::from_u128(uuid.as_u128()), name: name })
}) })
.collect(), .collect(),
Err(e) => Err(HandlingError::DBError(e)), Err(e) => Err(HandlingError::DBError(e)),
@ -80,16 +80,16 @@ where
pub async fn add( pub async fn add(
tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>, tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
m: robots::RobotModel, m: robots::RobotModel,
) -> Result<i64, HandlingError> { ) -> Result<uuid::Uuid, HandlingError> {
let r: robots::Robot = m.into(); let r: robots::Robot = m.into();
let result = sqlx::query("INSERT INTO robots (name) VALUES ($1::TEXT) RETURNING id") let result = sqlx::query("INSERT INTO robots (name) VALUES ($1::TEXT) RETURNING id, uuid")
.bind(r.name) .bind(r.name)
.fetch_one(tx) .fetch_one(tx)
.await; .await;
match result { match result {
Ok(v) => { Ok(v) => {
let (id,) = <(i64,)>::from_row(&v)?; let (_, uuid) = <(i64, sqlx::types::Uuid,)>::from_row(&v)?;
Ok(id) Ok(uuid::Uuid::from_u128(uuid.as_u128()))
} }
Err(sqlx::Error::RowNotFound) => Err(HandlingError::NotFound), Err(sqlx::Error::RowNotFound) => Err(HandlingError::NotFound),
Err(e) => Err(HandlingError::DBError(e)), Err(e) => Err(HandlingError::DBError(e)),
@ -98,16 +98,17 @@ pub async fn add(
pub async fn get_by_id( pub async fn get_by_id(
tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>, tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
id: i64, uuid: uuid::Uuid,
) -> Result<robots::Robot, HandlingError> { ) -> Result<robots::Robot, HandlingError> {
let result = sqlx::query("SELECT * FROM robots WHERE id = $1::INTEGER") let db_uuid = sqlx::types::Uuid::from_u128(uuid.as_u128());
.bind(id) let result = sqlx::query("SELECT id, name, uuid FROM robots WHERE uuid = $1::UUID")
.bind(db_uuid)
.fetch_one(tx) .fetch_one(tx)
.await; .await;
match result { match result {
Ok(v) => { Ok(v) => {
let (id, name) = <(i64, String)>::from_row(&v)?; let (_, name, uuid) = <(i64, String, sqlx::types::Uuid)>::from_row(&v)?;
Ok(robots::Robot { id: id, name: name }) Ok(robots::Robot { uuid: uuid::Uuid::from_u128(uuid.as_u128()), name: name })
} }
Err(sqlx::Error::RowNotFound) => Err(HandlingError::NotFound), Err(sqlx::Error::RowNotFound) => Err(HandlingError::NotFound),
Err(e) => Err(HandlingError::DBError(e)), Err(e) => Err(HandlingError::DBError(e)),
@ -119,9 +120,10 @@ pub async fn update(
m: robots::RobotModel, m: robots::RobotModel,
) -> Result<(), HandlingError> { ) -> Result<(), HandlingError> {
let r: robots::Robot = m.into(); let r: robots::Robot = m.into();
let result = sqlx::query("UPDATE robots SET name = $1::TEXT WHERE id = $2::INTEGER") let db_uuid = sqlx::types::Uuid::from_u128(r.uuid.as_u128());
let result = sqlx::query("UPDATE robots SET name = $1::TEXT WHERE uuid = $2::UUID")
.bind(r.name) .bind(r.name)
.bind(r.id) .bind(db_uuid)
.execute(tx) .execute(tx)
.await; .await;
match result { match result {
@ -137,10 +139,11 @@ pub async fn update(
pub async fn delete( pub async fn delete(
tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>, tx: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
id: i64, uuid: uuid::Uuid,
) -> Result<(), HandlingError> { ) -> Result<(), HandlingError> {
let result = sqlx::query("DELETE FROM robots WHERE id = $1::INTEGER") let db_uuid = sqlx::types::Uuid::from_u128(uuid.as_u128());
.bind(id) let result = sqlx::query("DELETE FROM robots WHERE uuid = $1::UUID")
.bind(db_uuid)
.execute(tx) .execute(tx)
.await; .await;
match result { match result {

@ -1,4 +1,3 @@
use crate::simple::database::PgSharedPool;
use crate::simple::http::reply_json; use crate::simple::http::reply_json;
use warp::{Filter, Rejection, Reply}; use warp::{Filter, Rejection, Reply};
@ -7,6 +6,7 @@ use warp::filters::{body, method, query as params};
use warp::http::StatusCode; use warp::http::StatusCode;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::app; use crate::app;
@ -33,18 +33,18 @@ async fn create(
// retrieve information of a single robot // retrieve information of a single robot
async fn get( async fn get(
shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, shared: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: Uuid,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
reply_json(app::robots::get_robot(shared, id).await) reply_json(app::robots::get_robot(shared, uuid).await)
} }
// updates robot information // updates robot information
async fn update( async fn update(
pool: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, pool: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: Uuid,
r: app::forms::GetRobot, r: app::forms::GetRobot,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
reply_json(app::robots::update_robot(pool, id, r).await) reply_json(app::robots::update_robot(pool, uuid, r).await)
} }
// returns a pagination of all robots // returns a pagination of all robots
@ -65,9 +65,9 @@ async fn get_all(
// will delete the requested robot // will delete the requested robot
async fn delete( async fn delete(
pool: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>, pool: std::sync::Arc<std::boxed::Box<crate::simple::shared::SharedContainer>>,
id: i64, uuid: Uuid,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
match app::robots::delete_robot(pool, id).await { match app::robots::delete_robot(pool, uuid).await {
Ok(_) => Ok(warp::reply::with_status( Ok(_) => Ok(warp::reply::with_status(
warp::reply(), warp::reply(),
StatusCode::NO_CONTENT, StatusCode::NO_CONTENT,
@ -118,7 +118,7 @@ pub fn with_id(
// we create a prefix containing the id of a robot and a shared database connection // we create a prefix containing the id of a robot and a shared database connection
// every filter is added after the prefix // every filter is added after the prefix
// so it receives a robot's id and a database connection // so it receives a robot's id and a database connection
let prefix = warp::path!("robot" / i64) let prefix = warp::path!("robot" / Uuid)
.map(move |id| (pool.clone(), id)) .map(move |id| (pool.clone(), id))
.untuple_one(); .untuple_one();

Loading…
Cancel
Save