Skip to content

Commit

Permalink
Allow querying elements by BTC Map ID and OSM ID
Browse files Browse the repository at this point in the history
  • Loading branch information
bubelov committed Aug 9, 2024
1 parent a2350d7 commit 1dc73ad
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
24 changes: 17 additions & 7 deletions src/element/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use crate::{osm::overpass::OverpassElement, Error};
use deadpool_sqlite::Pool;
use rusqlite::{named_params, Connection, OptionalExtension, Row};
use serde_json::{Map, Value};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use std::{collections::HashMap, sync::Arc};
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
use tokio::time::sleep;
use tracing::{debug, info};
Expand Down Expand Up @@ -211,6 +212,18 @@ impl Element {
.collect::<Result<Vec<_>, _>>()?)
}

pub fn select_by_id_or_osm_id(id: &str, conn: &Connection) -> Result<Option<Element>> {
match id.parse::<i64>() {
Ok(id) => Element::select_by_id(id, conn),
Err(_) => {
let parts: Vec<_> = id.split(':').collect();
let osm_type = parts[0];
let osm_id = parts[1].parse::<i64>().unwrap();
Element::select_by_osm_type_and_id(osm_type, osm_id, conn)
}
}
}

pub fn select_by_id(id: i64, conn: &Connection) -> Result<Option<Element>> {
let query = format!(
r#"
Expand Down Expand Up @@ -451,15 +464,12 @@ const fn mapper() -> fn(&Row) -> rusqlite::Result<Element> {

#[cfg(test)]
mod test {
use std::collections::HashMap;

use super::Element;
use crate::{osm::overpass::OverpassElement, test::mock_conn, Result};
use serde_json::json;
use std::collections::HashMap;
use time::{macros::datetime, OffsetDateTime};

use crate::{osm::overpass::OverpassElement, test::mock_conn, Result};

use super::Element;

#[test]
fn insert() -> Result<()> {
let conn = mock_conn();
Expand Down
16 changes: 16 additions & 0 deletions src/element/v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ use crate::Error;
use actix_web::get;
use actix_web::web::Data;
use actix_web::web::Json;
use actix_web::web::Path;
use actix_web::web::Query;
use deadpool_sqlite::Pool;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
use time::OffsetDateTime;

#[derive(Deserialize)]
Expand Down Expand Up @@ -76,6 +79,19 @@ pub async fn get(
))
}

#[get("{id}")]
pub async fn get_by_id(id: Path<String>, pool: Data<Arc<Pool>>) -> Result<Json<GetItem>, Error> {
let id_clone = id.clone();
pool.get()
.await?
.interact(move |conn| Element::select_by_id_or_osm_id(&id_clone, conn))
.await??
.ok_or(Error::HttpNotFound(format!(
"Element with id {id} doesn't exist"
)))
.map(|it| it.into())
}

#[cfg(test)]
mod test {
use crate::element::ElementRepo;
Expand Down
6 changes: 6 additions & 0 deletions src/osm/overpass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,23 @@ struct Osm3s {
pub struct OverpassElement {
pub r#type: String,
pub id: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub lat: Option<f64>, // for nodes only
#[serde(skip_serializing_if = "Option::is_none")]
pub lon: Option<f64>, // for nodes only
pub timestamp: Option<String>,
pub version: Option<i64>,
pub changeset: Option<i64>,
pub user: Option<String>,
pub uid: Option<i64>,
pub tags: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bounds: Option<Bounds>, // for ways and relations only
#[serde(skip_serializing_if = "Option::is_none")]
pub nodes: Option<Value>, // for ways only
#[serde(skip_serializing_if = "Option::is_none")]
pub geometry: Option<Value>, // for ways only
#[serde(skip_serializing_if = "Option::is_none")]
pub members: Option<Value>, // for relations only
}

Expand Down
6 changes: 5 additions & 1 deletion src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ pub async fn run() -> Result<()> {
.service(
scope("v3")
.wrap(Governor::new(&rate_limit_conf))
.service(scope("elements").service(element::v3::get))
.service(
scope("elements")
.service(element::v3::get)
.service(element::v3::get_by_id),
)
.service(
scope("events")
.service(event::v3::get)
Expand Down

0 comments on commit 1dc73ad

Please sign in to comment.