2024-04-09 21:54:47 +00:00
|
|
|
-- downloads data async into the http response table.
|
2024-04-10 07:11:23 +00:00
|
|
|
SELECT
|
2024-04-09 21:54:47 +00:00
|
|
|
cron.schedule(
|
|
|
|
'download-bus-data',
|
|
|
|
'5 seconds',
|
|
|
|
$$
|
|
|
|
select gather_bus_data();
|
|
|
|
$$
|
|
|
|
);
|
|
|
|
|
2024-04-10 07:11:23 +00:00
|
|
|
-- copies data into a more permanent tabe/more useful format. note: in
|
|
|
|
-- supabase, you cannot delete triggers on net._http_response
|
|
|
|
-- directly. but a cascading delete of the trigger function also
|
2024-04-09 21:54:47 +00:00
|
|
|
-- removes the trigger itself.
|
|
|
|
CREATE FUNCTION copy_to_raw_table() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
|
|
BEGIN
|
|
|
|
-- NOTE: the http_response sequence resets on DB restart, so there
|
|
|
|
-- is potential for old responses to have duplicated ids. we use a
|
|
|
|
-- constraint to only update newer entries (within the last 30
|
|
|
|
-- seconds). this should make accidentally overwriting older data
|
|
|
|
-- with newer values difficult. The API also provides a
|
|
|
|
-- lastUpdated value. we require that raw.created is at or after
|
|
|
|
-- that value to be updated.
|
2024-04-10 08:38:35 +00:00
|
|
|
WITH mapped_response_rows as (
|
|
|
|
select x.*
|
|
|
|
from jsonb_to_recordset(NEW.content::jsonb->'data'->'BusLocationByRoute'->'results') x (
|
|
|
|
"busId" text,
|
|
|
|
"tripId" text,
|
|
|
|
"routeNr" text,
|
|
|
|
headsign text,
|
|
|
|
tag text,
|
|
|
|
direction int,
|
|
|
|
lat decimal,
|
|
|
|
lng decimal
|
|
|
|
)
|
|
|
|
)
|
|
|
|
INSERT INTO raw_bus_positions
|
|
|
|
-- This needs to be in the same order as the jsonb_to_recordset call to work properly.
|
|
|
|
(response_status, measured_at, bus_id, trip_id, route_number, headsign, tag, direction, lat, lon)
|
|
|
|
SELECT
|
|
|
|
NEW.status_code,
|
|
|
|
(NEW.content::jsonb->'data'->'BusLocationByRoute'->>'lastUpdate')::timestamptz,
|
|
|
|
mr.*
|
|
|
|
FROM mapped_response_rows mr
|
|
|
|
JOIN raw_bus_position_requests raw_request ON raw_request.request_id = NEW.id
|
|
|
|
WHERE
|
2024-04-09 21:54:47 +00:00
|
|
|
-- fairly generous constraint to account for long requests.
|
2024-04-10 08:38:35 +00:00
|
|
|
raw_request.created >= (NEW.created - '30 seconds'::interval)
|
2024-04-10 07:11:23 +00:00
|
|
|
-- the response must be at or after we actually sent the request.
|
2024-04-10 08:38:35 +00:00
|
|
|
AND raw_request.created >= (NEW.content::jsonb->'data'->'BusLocationByRoute'->>'lastUpdate')::timestamptz
|
|
|
|
AND NEW.status_code = 200;
|
|
|
|
|
|
|
|
DELETE FROM raw_bus_position_requests where request_id = NEW.id;
|
2024-04-10 07:11:23 +00:00
|
|
|
|
|
|
|
-- what if we want to stream other data? we can do multiple updates in
|
|
|
|
-- different tables, where the request id is.
|
2024-04-09 21:54:47 +00:00
|
|
|
RETURN NULL; -- this is an AFTER trigger
|
|
|
|
END;
|
|
|
|
$$;
|
|
|
|
|
|
|
|
CREATE CONSTRAINT TRIGGER copy_http_response
|
|
|
|
AFTER INSERT ON net._http_response
|
|
|
|
DEFERRABLE INITIALLY DEFERRED
|
|
|
|
FOR EACH ROW
|
|
|
|
EXECUTE FUNCTION copy_to_raw_table();
|