diff --git a/migrations/1_project.sql b/migrations/1_project.sql index 2737b87..7ddc1e5 100644 --- a/migrations/1_project.sql +++ b/migrations/1_project.sql @@ -1,5 +1,6 @@ CREATE TABLE IF NOT EXISTS "project" ( id UUID PRIMARY KEY, + project_state VARCHAR NOT NULL, project_type VARCHAR NOT NULL, project_condition VARCHAR NOT NULL, agent_id UUID NOT NULL, @@ -7,6 +8,7 @@ CREATE TABLE IF NOT EXISTS "project" ( title VARCHAR, description TEXT NOT NULL, admin_tag VARCHAR, + finish_date TIMESTAMP NOT NULL, floors SMALLINT NOT NULL, media TEXT NOT NULL, time_created TIMESTAMPTZ NOT NULL, diff --git a/sql/project/fetch_by_ids.sql b/sql/project/fetch_by_ids.sql index 46ae5a1..b22ae05 100644 --- a/sql/project/fetch_by_ids.sql +++ b/sql/project/fetch_by_ids.sql @@ -1,5 +1,6 @@ SELECT id, +project_state as "project_state: _", project_type as "project_type: _", project_condition as "project_condition: _", agent_id, @@ -7,6 +8,7 @@ location_id, title, description, admin_tag, +finish_date, floors, media as "media: _", time_created, diff --git a/sql/project/fetch_with_filters_paged.sql b/sql/project/fetch_with_filters_paged.sql index e69de29..5980510 100644 --- a/sql/project/fetch_with_filters_paged.sql +++ b/sql/project/fetch_with_filters_paged.sql @@ -0,0 +1,26 @@ +SELECT + p.id, + p.project_state as "project_state: _", + p.project_type as "project_type: _", + p.project_condition as "project_condition: _", + p.agent_id, + p.location_id, + p.title, + p.description, + p.admin_tag, + p.finish_date, + p.floors, + p.media as "media: _", + p.time_created, + p.last_updated +FROM project p, location l +WHERE p.location_id = l.id +-- Filters here: +AND (LOWER(l.city) LIKE '%' || LOWER($1) || '%' OR $1 IS null) -- City Filter +AND (LOWER(l.district) LIKE '%' || LOWER($2) || '%' OR $2 IS null) -- District Filter +AND (p.project_type = $3 OR $3 IS null) -- ProjectType +AND (p.project_condition = $4 OR $4 IS null) -- ProjectCondition +AND (p.project_state = $5 OR $5 IS null) -- ProjectState +-- End of filters +ORDER BY p.time_created DESC +LIMIT 50 OFFSET $6; \ No newline at end of file diff --git a/sql/project/get_with_id.sql b/sql/project/get_with_id.sql index 67963bc..e98782c 100644 --- a/sql/project/get_with_id.sql +++ b/sql/project/get_with_id.sql @@ -1,14 +1,16 @@ -SELECT -id, -project_type as "project_type: _", -project_condition as "project_condition: _", -agent_id, -location_id, -title, -description, -admin_tag, -floors, -media as "media: _", -time_created, -last_updated + SELECT + id, + project_state as "project_state: _", + project_type as "project_type: _", + project_condition as "project_condition: _", + agent_id, + location_id, + title, + description, + admin_tag, + finish_date, + floors, + media as "media: _", + time_created, + last_updated FROM project WHERE id = $1; \ No newline at end of file diff --git a/sql/project/insert.sql b/sql/project/insert.sql index ae87b4c..304c506 100644 --- a/sql/project/insert.sql +++ b/sql/project/insert.sql @@ -1,5 +1,6 @@ INSERT INTO project ( id, + project_state, project_type, project_condition, agent_id, @@ -7,14 +8,16 @@ INSERT INTO project ( title, description, admin_tag, + finish_date, floors, media, time_created, last_updated ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $11 + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $13 ) RETURNING id, +project_state as "project_state: _", project_type as "project_type: _", project_condition as "project_condition: _", agent_id, @@ -22,6 +25,7 @@ location_id, title, description, admin_tag, +finish_date, floors, media as "media: _", time_created, diff --git a/sql/project/update.sql b/sql/project/update.sql index ba4cc42..3da76c6 100644 --- a/sql/project/update.sql +++ b/sql/project/update.sql @@ -1,11 +1,29 @@ UPDATE project SET -project_type = $1, -project_condition = $2, -agent_id = $3, -location_id = $4, -title = $5, -description = $6, -admin_tag = $7, -floors = $8, -media = $9, -last_updated = $10, \ No newline at end of file + project_state = $1, + project_type = $2, + project_condition = $3, + agent_id = $4, + location_id = $5, + title = $6, + description = $7, + admin_tag = $8, + finish_date = $9, + floors = $10, + media = $11, + last_updated = $12 +WHERE id = $13 +RETURNING + id, + project_state as "project_state: _", + project_type as "project_type: _", + project_condition as "project_condition: _", + agent_id, + location_id, + title, + description, + admin_tag, + finish_date, + floors, + media as "media: _", + time_created, + last_updated; diff --git a/src/dao/agent.rs b/src/dao/agent.rs index d5c0c4d..2d3a1a4 100644 --- a/src/dao/agent.rs +++ b/src/dao/agent.rs @@ -1,24 +1,64 @@ use jl_types::domain::agent::Agent; -use sqlx::{Transaction, Postgres, PgPool, postgres::PgQueryResult}; +use sqlx::{postgres::PgQueryResult, PgPool, Postgres, Transaction}; use uuid::Uuid; - -pub async fn insert_agent(tx: &mut Transaction<'_, Postgres>, agent: &Agent) -> Result { - sqlx::query_file_as!(Agent, "sql/agent/insert.sql", agent.id, agent.full_name, agent.credential, agent.credential_type as _, agent.time_created).fetch_one(tx).await +pub async fn insert_agent( + tx: &mut Transaction<'_, Postgres>, + agent: &Agent, +) -> Result { + sqlx::query_file_as!( + Agent, + "sql/agent/insert.sql", + agent.id, + agent.full_name, + agent.credential, + agent.credential_type as _, + agent.time_created + ) + .fetch_one(tx) + .await } -pub async fn get_agent_with_id(conn: &PgPool, agent_id: &Uuid) -> Result, sqlx::Error> { - sqlx::query_file_as!(Agent, "sql/agent/get_with_id.sql", agent_id).fetch_optional(conn).await +pub async fn get_agent_with_id( + conn: &PgPool, + agent_id: &Uuid, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Agent, "sql/agent/get_with_id.sql", agent_id) + .fetch_optional(conn) + .await } -pub async fn get_agents_with_ids(conn: &PgPool, agent_ids: &Vec) -> Result, sqlx::Error> { - sqlx::query_file_as!(Agent, "sql/agent/fetch_with_ids.sql", agent_ids).fetch_all(conn).await +pub async fn get_agents_with_ids( + conn: &PgPool, + agent_ids: &Vec, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Agent, "sql/agent/fetch_with_ids.sql", agent_ids) + .fetch_all(conn) + .await } -pub async fn update_agent(tx: &mut Transaction<'_, Postgres>, agent: Agent) -> Result { - sqlx::query_file_as!(Agent, "sql/agent/update.sql", agent.full_name, agent.credential, agent.credential_type as _, agent.last_updated, agent.id).fetch_one(tx).await +pub async fn update_agent( + tx: &mut Transaction<'_, Postgres>, + agent: Agent, +) -> Result { + sqlx::query_file_as!( + Agent, + "sql/agent/update.sql", + agent.full_name, + agent.credential, + agent.credential_type as _, + agent.last_updated, + agent.id + ) + .fetch_one(tx) + .await } -pub async fn delete_agent(tx: &mut Transaction<'_, Postgres>, agent_id: &Uuid) -> Result { - sqlx::query_file!("sql/agent/delete.sql", agent_id).execute(tx).await -} \ No newline at end of file +pub async fn delete_agent( + tx: &mut Transaction<'_, Postgres>, + agent_id: &Uuid, +) -> Result { + sqlx::query_file!("sql/agent/delete.sql", agent_id) + .execute(tx) + .await +} diff --git a/src/dao/location.rs b/src/dao/location.rs index 90bd188..b5563ba 100644 --- a/src/dao/location.rs +++ b/src/dao/location.rs @@ -1,20 +1,45 @@ use jl_types::domain::location::Location; -use sqlx::{Transaction, Postgres, postgres::PgQueryResult, PgPool}; +use sqlx::{postgres::PgQueryResult, PgPool, Postgres, Transaction}; use uuid::Uuid; - -pub async fn insert_location(tx: &mut Transaction<'_, Postgres>, location: Location) -> Result { - sqlx::query_file_as!(Location, "sql/location/insert.sql", location.id, location.city, location.district).fetch_one(tx).await +pub async fn insert_location( + tx: &mut Transaction<'_, Postgres>, + location: Location, +) -> Result { + sqlx::query_file_as!( + Location, + "sql/location/insert.sql", + location.id, + location.city, + location.district + ) + .fetch_one(tx) + .await } -pub async fn get_location_with_id(conn: &PgPool, location_id: &Uuid) -> Result, sqlx::Error> { - sqlx::query_file_as!(Location, "sql/location/get_with_id.sql", location_id).fetch_optional(conn).await +pub async fn get_location_with_id( + conn: &PgPool, + location_id: &Uuid, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Location, "sql/location/get_with_id.sql", location_id) + .fetch_optional(conn) + .await } -pub async fn get_locations_in_city(conn: &PgPool, city: &String) -> Result, sqlx::Error> { - sqlx::query_file_as!(Location, "sql/location/fetch_with_city.sql", city).fetch_all(conn).await +pub async fn get_locations_in_city( + conn: &PgPool, + city: &String, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Location, "sql/location/fetch_with_city.sql", city) + .fetch_all(conn) + .await } -pub async fn delete_location(tx: &mut Transaction<'_, Postgres>, location_id: Uuid) -> Result { - sqlx::query_file!("sql/location/delete.sql", location_id).execute(tx).await -} \ No newline at end of file +pub async fn delete_location( + tx: &mut Transaction<'_, Postgres>, + location_id: Uuid, +) -> Result { + sqlx::query_file!("sql/location/delete.sql", location_id) + .execute(tx) + .await +} diff --git a/src/dao/mod.rs b/src/dao/mod.rs index 9ea8269..18e5321 100644 --- a/src/dao/mod.rs +++ b/src/dao/mod.rs @@ -1,5 +1,5 @@ -pub mod main_dao; -pub mod project; pub mod agent; pub mod location; -pub mod unit; \ No newline at end of file +pub mod main_dao; +pub mod project; +pub mod unit; diff --git a/src/dao/project.rs b/src/dao/project.rs index 8b50a7c..48a2601 100644 --- a/src/dao/project.rs +++ b/src/dao/project.rs @@ -1,16 +1,103 @@ -use jl_types::domain::project::Project; -use sqlx::postgres::PgQueryResult; +use jl_types::{domain::{project::Project, project_state::ProjectState}, dto::filters::Filter}; +use sqlx::{postgres::PgQueryResult, PgPool, Postgres, Transaction}; +use uuid::Uuid; - - -pub async fn insert() -> Result { - todo!() +pub async fn insert( + tx: &mut Transaction<'_, Postgres>, + project: &Project, +) -> Result { + sqlx::query_file_as!( + Project, + "sql/project/insert.sql", + project.id, + project.project_state as _, + project.project_type as _, + project.project_condition as _, + project.agent_id, + project.location_id, + project.title, + project.description, + project.admin_tag, + project.finish_date, + project.floors, + project.media as _, + project.time_created + ) + .fetch_one(tx) + .await } -pub async fn delete() -> Result { - todo!() +pub async fn delete( + tx: &mut Transaction<'_, Postgres>, + project_id: &Uuid, +) -> Result { + sqlx::query_file!("sql/project/delete.sql", project_id) + .execute(tx) + .await } -pub async fn update() -> Result { - todo!() -} \ No newline at end of file +pub async fn update( + tx: &mut Transaction<'_, Postgres>, + project: &Project, +) -> Result { + sqlx::query_file_as!( + Project, + "sql/project/update.sql", + project.project_state as _, + project.project_type as _, + project.project_condition as _, + project.agent_id, + project.location_id, + project.title, + project.description, + project.admin_tag, + project.finish_date, + project.floors, + project.media as _, + project.last_updated, + project.id + ).fetch_one(tx).await +} + +pub async fn get_with_id(conn: &PgPool, project_id: &Uuid) -> Result, sqlx::Error> { + sqlx::query_file_as!(Project, "sql/project/get_with_id.sql", project_id).fetch_optional(conn).await +} + +pub async fn fetch_by_ids( + conn: &PgPool, + project_ids: &Vec, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Project, "sql/project/fetch_by_ids.sql", project_ids).fetch_all(conn).await +} + +pub async fn fetch_with_filters_paged( + conn: &PgPool, + filters: &Vec, + page: &i64, +) -> Result, sqlx::Error> { + let offset = (page - 1) * 50; + let mut city_filter = None; + let mut district_filter = None; + let mut project_type_filter = None; + let mut project_state_filter = ProjectState::InConstruction; + let mut project_condition_filter = None; + + for filter in filters { + match filter { + Filter::InCity(city) => city_filter = Some(city), + Filter::InDistrict(district) => district_filter = Some(district), + Filter::Finished => project_state_filter = ProjectState::InConstruction, + Filter::ByProjectType(project_type) => project_type_filter = Some(project_type), + Filter::ByProjectCondition(project_condition) => project_condition_filter = Some(project_condition), + } + } + + sqlx::query_file_as!(Project, "sql/project/fetch_with_filters_paged.sql", + city_filter, + district_filter, + project_type_filter as _, + project_condition_filter as _, + project_state_filter as _, + offset + ).fetch_all(conn).await +} diff --git a/src/dao/unit.rs b/src/dao/unit.rs index 6f6e3a3..9bda472 100644 --- a/src/dao/unit.rs +++ b/src/dao/unit.rs @@ -1,20 +1,60 @@ use jl_types::domain::unit::Unit; -use sqlx::{PgPool, Transaction, Postgres, postgres::PgQueryResult}; +use sqlx::{postgres::PgQueryResult, PgPool, Postgres, Transaction}; use uuid::Uuid; - -pub async fn fetch_with_project_id(conn: &PgPool, project_id: &Uuid) -> Result, sqlx::Error> { - sqlx::query_file_as!(Unit, "sql/unit/fetch_with_project_id.sql", project_id).fetch_all(conn).await +pub async fn fetch_with_project_id( + conn: &PgPool, + project_id: &Uuid, +) -> Result, sqlx::Error> { + sqlx::query_file_as!(Unit, "sql/unit/fetch_with_project_id.sql", project_id) + .fetch_all(conn) + .await } -pub async fn delete(tx: &mut Transaction<'_, Postgres>, unit_id: &Uuid) -> Result { - sqlx::query_file!("sql/unit/delete.sql", unit_id).execute(tx).await +pub async fn delete( + tx: &mut Transaction<'_, Postgres>, + unit_id: &Uuid, +) -> Result { + sqlx::query_file!("sql/unit/delete.sql", unit_id) + .execute(tx) + .await } pub async fn insert(tx: &mut Transaction<'_, Postgres>, unit: &Unit) -> Result { - sqlx::query_file_as!(Unit, "sql/unit/insert.sql", unit.id, unit.project_id, unit.price_usd, unit.unit_type as _, unit.rooms, unit.bathrooms, unit.area, unit.description, unit.media as _, unit.admin_tag, unit.time_created).fetch_one(tx).await + sqlx::query_file_as!( + Unit, + "sql/unit/insert.sql", + unit.id, + unit.project_id, + unit.price_usd, + unit.unit_type as _, + unit.rooms, + unit.bathrooms, + unit.area, + unit.description, + unit.media as _, + unit.admin_tag, + unit.time_created + ) + .fetch_one(tx) + .await } pub async fn update(conn: &PgPool, unit: &Unit) -> Result { - sqlx::query_file_as!(Unit, "sql/unit/update.sql", unit.price_usd, unit.unit_type as _, unit.rooms, unit.bathrooms, unit.area, unit.description, unit.media as _, unit.admin_tag, unit.last_updated, unit.id).fetch_one(conn).await -} \ No newline at end of file + sqlx::query_file_as!( + Unit, + "sql/unit/update.sql", + unit.price_usd, + unit.unit_type as _, + unit.rooms, + unit.bathrooms, + unit.area, + unit.description, + unit.media as _, + unit.admin_tag, + unit.last_updated, + unit.id + ) + .fetch_one(conn) + .await +} diff --git a/src/main.rs b/src/main.rs index 0385ed1..39e3efc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ pub mod utils; #[tokio::main] async fn main() { let start_time = Utc::now().timestamp_millis(); - + let db_conn = Arc::new(main_dao::connect_to_database().await.unwrap()); // Pass shared state to server and start it diff --git a/src/routes/main_router.rs b/src/routes/main_router.rs index 8342f79..1c08ed3 100644 --- a/src/routes/main_router.rs +++ b/src/routes/main_router.rs @@ -18,16 +18,17 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc) -> Result<( .wrap(cors_policy) .app_data(client_state.clone()) .app_data(web::Data::new(db_conn.clone())) - .service(web::scope("/admin") - /*.service(super::admin::create_new_agent_profile) - .service(super::admin::create_new_location) - .service(super::admin::create_new_property) - .service(super::admin::update_agent_info) - .service(super::admin::update_listing)) - .service(web::scope("/read") - .service(super::read::get_all_agents) - .service(super::read::get_listing_container) - .service(super::read::get_property_listings_paged)*/) + .service( + web::scope("/admin"), /*.service(super::admin::create_new_agent_profile) + .service(super::admin::create_new_location) + .service(super::admin::create_new_property) + .service(super::admin::update_agent_info) + .service(super::admin::update_listing)) + .service(web::scope("/read") + .service(super::read::get_all_agents) + .service(super::read::get_listing_container) + .service(super::read::get_property_listings_paged)*/ + ) }) .bind((HOST_ADDR, HOST_PORT))? .run(); diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 17723fe..abbbe10 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1 +1 @@ -pub mod main_router; \ No newline at end of file +pub mod main_router; diff --git a/src/services/mod.rs b/src/services/mod.rs index e69de29..8b13789 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -0,0 +1 @@ + diff --git a/src/utils/mod.rs b/src/utils/mod.rs index e69de29..8b13789 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -0,0 +1 @@ +