58 lines
2.0 KiB
PL/PgSQL
58 lines
2.0 KiB
PL/PgSQL
-- encode straeto API params into the query string by the graphql API.
|
|
-- yes, javascript in the database: the lazy way.
|
|
CREATE OR REPLACE FUNCTION encode_straeto_querystring(obj jsonb) RETURNS text
|
|
LANGUAGE plv8 STRICT IMMUTABLE AS $$
|
|
return Object.keys(obj).map(function(variableName) {
|
|
const variableValue = obj[variableName];
|
|
if (typeof variableValue == 'object') {
|
|
return encodeURIComponent(variableName) + '=' + encodeURIComponent(JSON.stringify(variableValue));
|
|
} else {
|
|
return encodeURIComponent(variableName) + '=' + encodeURIComponent(variableValue);
|
|
}
|
|
}).join('&');
|
|
$$;
|
|
|
|
CREATE OR REPLACE FUNCTION create_straeto_parameters(bus_routes text[]) RETURNS jsonb
|
|
LANGUAGE plpgsql AS $$
|
|
DECLARE query_params jsonb;
|
|
BEGIN
|
|
-- This is the unencoded GraphQL request payload.
|
|
query_params := '{
|
|
"operationName": "BusLocationByRoute",
|
|
"variables": { "trips":[], "routes": [] },
|
|
"extensions": {
|
|
"persistedQuery": {
|
|
"version": 1,
|
|
"sha256Hash": "8f9ee84171961f8a3b9a9d1a7b2a7ac49e7e122e1ba1727e75cfe3a94ff3edb8"
|
|
}
|
|
}
|
|
}'::jsonb;
|
|
|
|
-- Add requested bus routes to the `routes` GraphQL variable.
|
|
SELECT INTO query_params
|
|
jsonb_set(query_params, '{variables, routes}', array_to_json(bus_routes)::jsonb);
|
|
RETURN query_params;
|
|
END
|
|
$$;
|
|
|
|
-- Builds the full request URL to download bus positions of the given
|
|
-- route numbers.
|
|
CREATE OR REPLACE FUNCTION build_api_url(bus_routes text[]) RETURNS text LANGUAGE sql AS $$
|
|
SELECT concat(
|
|
'https://straeto.is/graphql?',
|
|
encode_straeto_querystring(create_straeto_parameters(bus_routes))
|
|
);
|
|
$$;
|
|
|
|
-- Called by a scheduled job to request data on a timer. A trigger
|
|
-- handles insertion of the response after record initially inserted.
|
|
CREATE OR REPLACE FUNCTION gather_bus_data()
|
|
RETURNS void LANGUAGE sql
|
|
as $$
|
|
INSERT INTO raw_bus_positions (request_id) SELECT
|
|
net.http_get(
|
|
url := build_api_url(array['1', '2', '3']),
|
|
headers := '{"Content-Type": "application/json"}'::jsonb
|
|
);
|
|
$$;
|