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,118 @@
use sqlx::{Postgres, Transaction};
use crate::traits::{DbObj, FromSeptaJson};
use crate::septa_json;
use libseptastic::stop_schedule::StopSchedule;
impl DbObj<StopSchedule> for StopSchedule {
async fn create_table(tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
sqlx::query("
CREATE TABLE IF NOT EXISTS septa_stop_schedules (
route_id TEXT NOT NULL,
trip_id TEXT NOT NULL,
service_id TEXT NOT NULL,
direction_id BIGINT NOT NULL,
arrival_time BIGINT NOT NULL,
stop_id BIGINT NOT NULL,
stop_sequence BIGINT NOT NULL,
PRIMARY KEY (trip_id, stop_id),
FOREIGN KEY (route_id) REFERENCES septa_routes(id) ON DELETE CASCADE,
FOREIGN KEY (stop_id) REFERENCES septa_stops(id) ON DELETE CASCADE
);
")
//FOREIGN KEY (route_id, direction_id) REFERENCES septa_directions(route_id, direction_id) ON DELETE CASCADE,
.execute(&mut **tx)
.await?;
Ok(())
}
async fn insert_many(scheds: Vec<StopSchedule>, tx: &mut Transaction<'_, Postgres>) -> anyhow::Result<()> {
let mut route_ids: Vec<String> = Vec::new();
let mut trip_ids: Vec<String> = Vec::new();
let mut service_ids: Vec<String> = Vec::new();
let mut direction_ids: Vec<i64> = Vec::new();
let mut arrival_times: Vec<i64> = Vec::new();
let mut stop_ids: Vec<i64> = Vec::new();
let mut stop_sequences: Vec<i64> = Vec::new();
for sched in scheds {
route_ids.push(sched.route_id);
trip_ids.push(sched.trip_id);
service_ids.push(sched.service_id);
direction_ids.push(sched.direction_id);
arrival_times.push(sched.arrival_time);
stop_ids.push(sched.stop_id);
stop_sequences.push(sched.stop_sequence);
}
sqlx::query("
INSERT INTO septa_stop_schedules (
route_id,
trip_id,
service_id,
direction_id,
arrival_time,
stop_id,
stop_sequence
)
SELECT * FROM UNNEST(
$1::text[],
$2::text[],
$3::text[],
$4::bigint[],
$5::bigint[],
$6::bigint[],
$7::bigint[]
)
ON CONFLICT DO NOTHING
;
")
.bind(&route_ids[..])
.bind(&trip_ids[..])
.bind(&service_ids[..])
.bind(&direction_ids[..])
.bind(&arrival_times[..])
.bind(&stop_ids[..])
.bind(&stop_sequences[..])
.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::stop_schedule::StopSchedule> for StopSchedule {
fn from_septa_json(json_sched: septa_json::stop_schedule::StopSchedule) -> ::anyhow::Result<Box<StopSchedule>> {
let time_parts: Vec<&str> = json_sched.arrival_time.split(":").collect();
let arrival_time: i64 = {
let hour: i64 = time_parts[0].parse::<i64>()?;
let minute: i64 = time_parts[1].parse::<i64>()?;
let second: i64 = time_parts[2].parse::<i64>()?;
(hour*3600) + (minute * 60) + second
};
Ok(Box::new(StopSchedule {
route_id: json_sched.route_id,
trip_id: match json_sched.trip_id{
septa_json::stop_schedule::TripId::RegionalRail(x) => x,
septa_json::stop_schedule::TripId::Other(y) => y.to_string()
},
service_id: json_sched.service_id,
// FIXME: Actually get direction
direction_id: json_sched.direction_id,
arrival_time,
stop_id: json_sched.stop_id,
stop_sequence: json_sched.stop_sequence
}))
}
}