diff --git a/service/src/airports/model.rs b/service/src/airports/model.rs index 0ca1176..2c48306 100644 --- a/service/src/airports/model.rs +++ b/service/src/airports/model.rs @@ -1,6 +1,7 @@ use crate::db; use crate::error_handler::ServiceError; use crate::schema::airports; +use diesel::dsl::count_star; use diesel::prelude::*; // use log::trace; use postgis_diesel::types::*; @@ -43,16 +44,9 @@ pub struct QueryAirport { } impl QueryAirport { - pub fn get_all(bounds: Option>, category: Option, filter: Option, limit: Option, page: Option) -> Result, ServiceError> { + pub fn get_all(bounds: &Option>, category: &Option, filter: &Option, limit: i32, page: i32) -> Result, ServiceError> { let mut conn = db::connection()?; - let limit = match limit { - Some(l) => l, - None => 100 - }; - let page = match page { - Some(p) => p, - None => 1 - }; + let mut query = airports::table .limit(limit as i64) .into_boxed(); @@ -70,12 +64,31 @@ impl QueryAirport { .or(airports::full_name.ilike(format!("%{}%", filter))) ) } - // let debug = diesel::debug_query::(&query); - // trace!("{}", debug); - let airports: Vec = query.order(airports::category.asc()).load::(&mut conn)?; + let airports: Vec = query.order((airports::id.asc(), airports::category.asc())).load::(&mut conn)?; Ok(airports) } + pub fn get_count(bounds: &Option>, category: &Option, filter: &Option) -> Result { + let mut conn = db::connection()?; + let mut query = airports::table.select(count_star()).into_boxed(); + + if let Some(bounds) = bounds { + query = query.filter(st_contains(bounds, airports::point)); + } + if let Some(category) = category { + query = query.filter(airports::category.eq(category)); + } + if let Some(filter) = filter { + query = query.filter(airports::icao + .ilike(format!("%{}%", filter)) + .or(airports::full_name.ilike(format!("%{}%", filter))) + ) + } + + let count: i64 = query.first(&mut conn)?; + return Ok(count); + } + pub fn find(icao: String) -> Result { let mut conn = db::connection()?; let airport = airports::table.filter(airports::icao.eq(icao)).first(&mut conn)?; diff --git a/service/src/airports/routes.rs b/service/src/airports/routes.rs index d0ec87b..616de6a 100644 --- a/service/src/airports/routes.rs +++ b/service/src/airports/routes.rs @@ -82,10 +82,24 @@ async fn get_all(req: HttpRequest) -> HttpResponse { None => None }; - match web::block(move || QueryAirport::get_all(polygon, category, filter, params.limit, params.page)).await.unwrap() { + let limit = match params.limit { + Some(l) => l, + None => 100 + }; + let page = match params.page { + Some(p) => p, + None => 1 + }; + let total = match QueryAirport::get_count(&polygon, &category, &filter) { + Ok(t) => t, + Err(_) => 0 + }; + let pages = ((total as f64) / (if limit <= 0 { 1 } else { limit} as f64)).ceil() as i64; + + match web::block(move || QueryAirport::get_all(&polygon, &category, &filter, limit, page)).await.unwrap() { Ok(a) => HttpResponse::Ok().json(AirportsResponse { data: a, - meta: Metadata { page: 0, limit: 0, pages: 0, total: 0 } + meta: Metadata { page, limit, pages, total } }), Err(err) => { error!("{}", err); @@ -105,7 +119,7 @@ async fn get(icao: web::Path) -> HttpResponse { match QueryAirport::find(icao.into_inner()) { Ok(a) => HttpResponse::Ok().json(AirportResponse { data: a, - meta: Metadata { page: 0, limit: 0, pages: 0, total: 0 } + meta: Metadata { page: 1, limit: 1, pages: 1, total: 1 } }), Err(err) => { error!("{}", err); diff --git a/service/src/db.rs b/service/src/db.rs index 0bc91c7..7ebb960 100644 --- a/service/src/db.rs +++ b/service/src/db.rs @@ -69,8 +69,8 @@ pub fn import_data() { pub struct Metadata { pub page: i32, pub limit: i32, - pub pages: i32, - pub total: i32, + pub pages: i64, + pub total: i64, } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] diff --git a/service/src/main.rs b/service/src/main.rs index 51e3689..efa33e7 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -63,4 +63,4 @@ async fn main() -> std::io::Result<()> { } }; server.run().await -} +} \ No newline at end of file