Some checks failed
Create and publish a Docker image / build-and-push-image (push) Has been cancelled
108 lines
3.2 KiB
Rust
108 lines
3.2 KiB
Rust
use sqlx::{Postgres, Transaction};
|
|
use crate::traits::{DbObj, FromSeptaJson};
|
|
use crate::septa_json;
|
|
|
|
use libseptastic::stop::{Stop, StopType};
|
|
|
|
impl DbObj<Stop> for Stop {
|
|
async fn create_table(tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
|
|
sqlx::query("
|
|
CREATE TYPE septa_stop_type AS ENUM (
|
|
'far_side',
|
|
'middle_block_near_side',
|
|
'normal'
|
|
);
|
|
")
|
|
.execute(&mut **tx)
|
|
.await?;
|
|
|
|
sqlx::query("
|
|
CREATE TABLE IF NOT EXISTS septa_stops (
|
|
id BIGINT PRIMARY KEY,
|
|
name VARCHAR(128) NOT NULL,
|
|
lat DOUBLE PRECISION NOT NULL,
|
|
lng DOUBLE PRECISION NOT NULL,
|
|
stop_type septa_stop_type NOT NULL
|
|
);
|
|
")
|
|
.execute(&mut **tx)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
async fn insert_many(stations: Vec<Stop>, tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
|
|
let mut ids: Vec<i64> = Vec::new();
|
|
let mut names: Vec<String> = Vec::new();
|
|
let mut lats: Vec<f64> = Vec::new();
|
|
let mut lngs: Vec<f64> = Vec::new();
|
|
let mut stop_types: Vec<StopType> = Vec::new();
|
|
|
|
for station in stations {
|
|
ids.push(station.id);
|
|
names.push(station.name);
|
|
lats.push(station.lat);
|
|
lngs.push(station.lng);
|
|
stop_types.push(station.stop_type);
|
|
}
|
|
|
|
sqlx::query("
|
|
INSERT INTO
|
|
septa_stops
|
|
(
|
|
id,
|
|
name,
|
|
lat,
|
|
lng,
|
|
stop_type
|
|
)
|
|
SELECT * FROM UNNEST(
|
|
$1::bigint[],
|
|
$2::text[],
|
|
$3::double precision[],
|
|
$4::double precision[],
|
|
$5::septa_stop_type[]
|
|
)
|
|
ON CONFLICT DO NOTHING
|
|
;
|
|
")
|
|
.bind(&ids[..])
|
|
.bind(&names[..])
|
|
.bind(&lats[..])
|
|
.bind(&lngs[..])
|
|
.bind(&stop_types[..])
|
|
.execute(&mut **tx)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn insert(&self, tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
|
|
Self::insert_many(vec![self.clone()], tx).await?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl FromSeptaJson<septa_json::route_stop::RouteStop> for Stop {
|
|
fn from_septa_json(json_station: septa_json::route_stop::RouteStop) -> ::anyhow::Result<Box<Stop>> {
|
|
let mut name = json_station.stop_name;
|
|
let mut stop_type = StopType::Normal;
|
|
|
|
if let Some(new_name) = name.strip_suffix("- MNBS") {
|
|
stop_type = StopType::MiddleBlockNearSide;
|
|
name = new_name.to_string();
|
|
}
|
|
|
|
if let Some(new_name) = name.strip_suffix("- FS") {
|
|
stop_type = StopType::FarSide;
|
|
name = new_name.to_string();
|
|
}
|
|
|
|
Ok(Box::new(Stop {
|
|
name,
|
|
id: json_station.stop_id,
|
|
lat: json_station.stop_lat,
|
|
lng: json_station.stop_lon,
|
|
stop_type
|
|
}))
|
|
}
|
|
}
|