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,122 @@
use sqlx::{Postgres, Transaction};
use crate::traits::{DbObj, FromSeptaJson};
use crate::septa_json;
use libseptastic::route::{Route, RouteType};
impl DbObj<Route> for Route {
async fn create_table(tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
sqlx::query("
CREATE TYPE septa_route_type AS ENUM (
'trolley',
'subway_elevated',
'regional_rail',
'bus',
'trackless_trolley'
);
")
.execute(&mut **tx)
.await?;
sqlx::query("
CREATE TYPE septa_direction_type AS ENUM (
'northbound',
'southbound',
'eastbound',
'westbound',
'inbound',
'outbound',
'loop'
);
")
.execute(&mut **tx)
.await?;
sqlx::query("
CREATE TABLE IF NOT EXISTS septa_routes (
id VARCHAR(8) PRIMARY KEY,
name VARCHAR(64) NOT NULL,
short_name VARCHAR(32) NOT NULL,
color_hex VARCHAR(6) NOT NULL,
route_type septa_route_type NOT NULL
);
")
.execute(&mut **tx)
.await?;
Ok(())
}
async fn insert_many(routes: Vec<Route>, tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
let mut names = Vec::new();
let mut short_names = Vec::new();
let mut color_hexes = Vec::new();
let mut route_types: Vec<RouteType> = Vec::new();
let mut ids = Vec::new();
for route in routes {
ids.push(route.id);
names.push(route.name);
short_names.push(route.short_name);
color_hexes.push(route.color_hex);
route_types.push(route.route_type);
}
sqlx::query("
INSERT INTO
septa_routes
(
id,
name,
short_name,
color_hex,
route_type
)
SELECT * FROM UNNEST(
$1::text[],
$2::text[],
$3::text[],
$4::text[],
$5::septa_route_type[]
);
")
.bind(&ids)
.bind(&names)
.bind(&short_names)
.bind(&color_hexes)
.bind(&route_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::RouteType> for RouteType {
fn from_septa_json(json_rt: septa_json::route::RouteType) -> ::anyhow::Result<Box<RouteType>> {
Ok(Box::new(match json_rt {
septa_json::route::RouteType::Trolley => RouteType::Trolley,
septa_json::route::RouteType::SubwayElevated => RouteType::SubwayElevated,
septa_json::route::RouteType::RegionalRail => RouteType::RegionalRail,
septa_json::route::RouteType::Bus => RouteType::Bus,
septa_json::route::RouteType::TracklessTrolley => RouteType::TracklessTrolley,
}))
}
}
impl FromSeptaJson<septa_json::route::Route> for Route {
fn from_septa_json(json_route: septa_json::route::Route) -> ::anyhow::Result<Box<Route>> {
Ok(Box::new(Route {
name: json_route.route_long_name,
short_name: json_route.route_short_name,
color_hex: json_route.route_color,
route_type: *RouteType::from_septa_json(json_route.route_type)?,
id: json_route.route_id,
// FIXME: Actually get direction
}))
}
}