Skip to content

Commit

Permalink
Room API (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
JijoBose authored Dec 29, 2023
1 parent 1c83f1b commit d4deaf5
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 4 deletions.
2 changes: 2 additions & 0 deletions migrations/2023-12-28-134303_create_rooms/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
DROP TABLE rooms
6 changes: 6 additions & 0 deletions migrations/2023-12-28-134303_create_rooms/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- Your SQL goes here
CREATE TABLE rooms (
id VARCHAR NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
home_id VARCHAR NOT NULL REFERENCES homes(id) on DELETE CASCADE
)
1 change: 1 addition & 0 deletions src/app/actions/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod home;
pub mod room;
40 changes: 40 additions & 0 deletions src/app/actions/room.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use actix_web::web::Json;
use diesel::prelude::*;
use uuid::Uuid;

use crate::app::models::room;

type DbError = Box<dyn std::error::Error + Send + Sync>;

pub fn insert_new_room(
conn: &mut PgConnection,
form: &Json<room::NewRoom>,
) -> Result<room::Room, DbError> {
use crate::schema::rooms::dsl::*;

match form.validate() {
Ok(_) => {
let new_room = room::Room {
id: Uuid::new_v4().to_string(),
name: form.name.to_owned(),
home_id: form.home_id.to_owned(),
};

diesel::insert_into(rooms).values(&new_room).execute(conn)?;

Ok(new_room)
}
Err(error) => Err(DbError::from(error)),
}
}

pub fn delete_room(conn: &mut PgConnection, uid: Uuid) -> Result<String, DbError> {
use crate::schema::rooms::dsl::*;

let result = diesel::delete(rooms.filter(id.eq(uid.to_string()))).execute(conn);

match result {
Ok(_) => Ok("Success".to_string()),
Err(e) => Err(DbError::from(e)),
}
}
1 change: 1 addition & 0 deletions src/app/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod home;
pub mod room;
22 changes: 22 additions & 0 deletions src/app/api/room.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use actix_web::{error, post, web, HttpResponse, Responder, Result};
use diesel::{r2d2, PgConnection};

use crate::app::actions;
use crate::app::models;

type DbPool = r2d2::Pool<r2d2::ConnectionManager<PgConnection>>;

#[post("/room")]
async fn add_room(
pool: web::Data<DbPool>,
form: web::Json<models::room::NewRoom>,
) -> Result<impl Responder> {
let response = web::block(move || {
let mut conn = pool.get()?;
actions::room::insert_new_room(&mut conn, &form)
})
.await?
.map_err(error::ErrorBadRequest)?;

Ok(HttpResponse::Created().json(response))
}
1 change: 1 addition & 0 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod db;

pub mod models {
pub mod home;
pub mod room;
}
4 changes: 2 additions & 2 deletions src/app/models/home.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use diesel::{prelude::Insertable, Queryable};
use diesel::{prelude::Insertable, Queryable, associations::Identifiable};
use serde::{Deserialize, Serialize};

use crate::schema::homes;

/// User details.
#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Insertable)]
#[derive(Debug, Clone, PartialEq, Identifiable, Serialize, Deserialize, Queryable, Insertable)]
#[diesel(table_name = homes)]
pub struct Home {
pub id: String,
Expand Down
33 changes: 33 additions & 0 deletions src/app/models/room.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use diesel::prelude::*;
use diesel::{prelude::Insertable, Queryable};
use serde::{Deserialize, Serialize};

use crate::schema::rooms;
use crate::app::models::home::Home;

/// Room details.
#[derive(Queryable, Serialize, Selectable, Identifiable, Associations, Debug, PartialEq, Insertable)]
#[diesel(belongs_to(Home))]
#[diesel(table_name = rooms)]
pub struct Room {
pub id: String,
pub name: String,
pub home_id: String,
}

/// New room details.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewRoom {
pub name: String,
pub home_id: String,
}

// validations
impl NewRoom {
pub fn validate(&self) -> Result<(), String> {
if self.name.trim().is_empty() {
return Err("Name is empty".to_string());
}
Ok(())
}
}
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use app::api::home::{
delete_home
};

use app::api::room::add_room;

use app::db::{
initialize_db_pool,
initial_migration
Expand Down Expand Up @@ -37,6 +39,7 @@ async fn main() -> std::io::Result<()> {
.service(add_home)
.service(find_home)
.service(delete_home)
.service(add_room)
})
.bind(("127.0.0.1", 8080))?
.run()
Expand Down
19 changes: 17 additions & 2 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@

diesel::table! {
homes (id) {
id -> Text,
title -> Text,
id -> Varchar,
title -> Varchar,
body -> Text,
}
}

diesel::table! {
rooms (id) {
id -> Varchar,
name -> Varchar,
home_id -> Varchar,
}
}

diesel::joinable!(rooms -> homes (home_id));

diesel::allow_tables_to_appear_in_same_query!(
homes,
rooms,
);

0 comments on commit d4deaf5

Please sign in to comment.