just add data loader here
Some checks failed
Create and publish a Docker image / build-and-push-image (push) Has been cancelled

This commit is contained in:
Nicholas Orlowsky 2025-09-12 19:34:35 -04:00
parent 04ae29eb27
commit 55df6bdb16
No known key found for this signature in database
GPG key ID: A9F3BA4C0AA7A70B
23 changed files with 4097 additions and 1 deletions

View file

@ -0,0 +1,108 @@
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
}))
}
}