diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 753badb..e0f28aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,6 @@ jobs: strategy: matrix: python-version: ["3.10"] - container: pgxn/pgxn-tools permissions: contents: write id-token: write diff --git a/Makefile b/Makefile index b640417..ed55b9d 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,11 @@ # SPDX-License-Identifier: CC-BY-NC-SA-4.0 EXTENSION = pgtfs -DATA = pgtfs--0.0.1.sql +DATA = sql/pgtfs--0.0.1.sql sql/pgtfs--0.0.2.sql MODULE_big = pgtfs OBJS = pgtfs.o src/models/network.o src/csa/csa.o REGRESS= pgtfs_test network_edge_cases_test -REGRESS_OPTS= --user=postgres +REGRESS_OPTS= --inputdir=tests --outputdir=tests --user=postgres PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/changelog.md b/changelog.md index 9f8a8fb..0940cbf 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.0.2](https://github.com/adrianprelipcean/pgtfs/releases/tag/v0.0.2) +### Changed +- use `double` instead of `float8` and `time_t` to maintain data type consistency between PostgreSQL and PGTFS +- `csa.cpp` correctly imports `postgres.h` for calling `elog` type functionality +- folder structure change: tests and relevant data is in the `tests/` folder and the (mostly versioning) extension specific sql files are in the `sql/` folder ## [0.0.1](https://github.com/adrianprelipcean/pgtfs/releases/tag/v0.0.1) ### Added diff --git a/docs/conf.py b/docs/conf.py index 6f089e5..1af1e7b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,7 +13,7 @@ project = 'PGTFS' copyright = '2024, Adrian C. Prelipcean' author = 'Adrian C. Prelipcean' -version = '0.0.1' +version = '0.0.2' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/pgtfs.control b/pgtfs.control index 048513f..1c2df10 100644 --- a/pgtfs.control +++ b/pgtfs.control @@ -1,3 +1,3 @@ comment = 'Contains public transportation routing functionality using the GTFS format' -default_version = '0.0.1' +default_version = '0.0.2' relocatable = true \ No newline at end of file diff --git a/pgtfs.cpp b/pgtfs.cpp index e81fe06..99ef856 100644 --- a/pgtfs.cpp +++ b/pgtfs.cpp @@ -21,15 +21,15 @@ extern "C" extern "C" { PG_MODULE_MAGIC; - static const char *EXTENSION_VERSION = "0.0.1"; + static const char *EXTENSION_VERSION = "0.0.2"; PG_FUNCTION_INFO_V1(pgtfs_csa); /** * @brief Implements the pgtfs_csa PostgreSQL extension function. - * + * * This function performs the Connection Scan Algorithm (CSA) to find connections * between the specified origin and destination at the given departure time. - * + * * @param fcinfo Function call information. * @return A set of rows representing the solutions found. */ @@ -112,14 +112,14 @@ extern "C" values[0] = CStringGetTextDatum(stop.stop_id.c_str()); values[1] = Int32GetDatum(stop.stop_sequence); - values[2] = Float8GetDatum((float)stop.arrival_time); + values[2] = Float8GetDatum(stop.arrival_time); values[3] = CStringGetTextDatum(stop.trip_id.c_str()); bool nulls[4]; - nulls[0] = stop.stop_id.empty(); - nulls[1] = false; - nulls[2] = false; - nulls[3] = stop.trip_id.empty(); + nulls[0] = stop.stop_id.empty(); + nulls[1] = false; + nulls[2] = false; + nulls[3] = stop.trip_id.empty(); HeapTuple tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); @@ -133,10 +133,10 @@ extern "C" PG_FUNCTION_INFO_V1(pgtfs_version); /** * @brief Returns version information about the extension. - * + * * This function returns a textual representation of version information * including the extension version, PostgreSQL version, and compiler version. - * + * * @param fcinfo Function call information. * @return A text representation of the version information. */ diff --git a/pgtfs--0.0.1.sql b/sql/pgtfs--0.0.1.sql similarity index 100% rename from pgtfs--0.0.1.sql rename to sql/pgtfs--0.0.1.sql diff --git a/sql/pgtfs--0.0.2.sql b/sql/pgtfs--0.0.2.sql new file mode 100644 index 0000000..f7a8c08 --- /dev/null +++ b/sql/pgtfs--0.0.2.sql @@ -0,0 +1,23 @@ +-- SPDX-FileCopyrightText: © 2024 Adrian C. Prelipcean +-- +-- SPDX-License-Identifier: EUPL-1.2 + +CREATE OR REPLACE FUNCTION pgtfs_csa( + origin TEXT, + destination TEXT, + departure_time DOUBLE PRECISION, + network TEXT +) +RETURNS TABLE ( + stop_id TEXT, + stop_sequence INT, + arrival_time DOUBLE PRECISION, + trip_id TEXT +) +AS '$libdir/pgtfs' +LANGUAGE c STRICT; + +CREATE OR REPLACE FUNCTION pgtfs_version() +RETURNS TEXT +AS '$libdir/pgtfs' +LANGUAGE c STRICT; diff --git a/src/csa/csa.cpp b/src/csa/csa.cpp index 950c131..a95bc36 100644 --- a/src/csa/csa.cpp +++ b/src/csa/csa.cpp @@ -12,17 +12,17 @@ std::vector perform_CSA(const char *origin, const char *destination, float8 departure_time, NetworkRow *network, int64_t network_size) { - time_t departure_epoch = (time_t)departure_time; + double departure_epoch = departure_time; int num_rows = network_size; std::vector stops; - std::priority_queue>>, - std::vector>>>, - std::greater>>>> + std::priority_queue>>, + std::vector>>>, + std::greater>>>> pq; - std::unordered_map shortest_times; + std::unordered_map shortest_times; shortest_times[std::string(origin)] = departure_epoch; pq.push({departure_epoch, std::string(origin), {{std::string(origin), "", departure_epoch}}}); @@ -55,14 +55,14 @@ std::vector perform_CSA(const char *origin, const char *destination { if (current_node == network[i].from_stop_id) { - if (current_time <= (time_t)network[i].departure_time) + if (current_time <= network[i].departure_time) { - time_t neighbor_arrival_time = (time_t)network[i].departure_time + (time_t)network[i].travel_time; + double neighbor_arrival_time = network[i].departure_time + network[i].travel_time; if (shortest_times.find(network[i].to_stop_id) == shortest_times.end() || neighbor_arrival_time < shortest_times[network[i].to_stop_id]) { shortest_times[network[i].to_stop_id] = neighbor_arrival_time; - std::vector> new_route = route; + std::vector> new_route = route; new_route.push_back(std::make_tuple(network[i].to_stop_id, network[i].trip_id, neighbor_arrival_time)); pq.push({neighbor_arrival_time, network[i].to_stop_id, new_route}); } diff --git a/src/csa/csa.h b/src/csa/csa.h index 186831f..62a785f 100644 --- a/src/csa/csa.h +++ b/src/csa/csa.h @@ -10,10 +10,12 @@ #ifndef CSA_H #define CSA_H +extern "C" { +#include "postgres.h" +} #include #include #include -#include "postgres.h" #include "src/models/network.h" /** diff --git a/src/models/network.h b/src/models/network.h index e1e9332..a4d597f 100644 --- a/src/models/network.h +++ b/src/models/network.h @@ -30,9 +30,9 @@ typedef struct { char trip_id[MAX_STRING_LENGTH]; /**< Trip ID */ char from_stop_id[MAX_STRING_LENGTH]; /**< From stop ID */ char to_stop_id[MAX_STRING_LENGTH]; /**< To stop ID */ - float8 arrival_time; /**< Arrival time as epoch*/ - float8 departure_time; /**< Departure time as epoch*/ - float8 travel_time; /**< Travel time */ + double arrival_time; /**< Arrival time as epoch*/ + double departure_time; /**< Departure time as epoch*/ + double travel_time; /**< Travel time */ bool nulls[6]; /**< Array of boolean flags indicating null values */ } NetworkRow; diff --git a/expected/network_edge_cases_test.out b/tests/expected/network_edge_cases_test.out similarity index 100% rename from expected/network_edge_cases_test.out rename to tests/expected/network_edge_cases_test.out diff --git a/expected/network_edge_cases_test.out.license b/tests/expected/network_edge_cases_test.out.license similarity index 100% rename from expected/network_edge_cases_test.out.license rename to tests/expected/network_edge_cases_test.out.license diff --git a/expected/pgtfs_test.out b/tests/expected/pgtfs_test.out similarity index 89% rename from expected/pgtfs_test.out rename to tests/expected/pgtfs_test.out index 6cbf0b6..1575c09 100644 --- a/expected/pgtfs_test.out +++ b/tests/expected/pgtfs_test.out @@ -24,7 +24,7 @@ $$ stop_id | stop_sequence | arrival_time | trip_id ---------+---------------+--------------+--------- 1 | 0 | 1712707200 | - 2 | 1 | 1712759936 | 1753 + 2 | 1 | 1712759880 | 1753 (2 rows) -- simple connectivity test where sequence has a gap (3 is missing) @@ -49,9 +49,9 @@ $$ stop_id | stop_sequence | arrival_time | trip_id ---------+---------------+--------------+--------- 1 | 0 | 1712707200 | - 2 | 1 | 1712759936 | 1753 - 3 | 2 | 1712761984 | 1753 - 4 | 3 | 1712762112 | 1753 + 2 | 1 | 1712759880 | 1753 + 3 | 2 | 1712762040 | 1753 + 4 | 3 | 1712762100 | 1753 (4 rows) -- connected and route on single trip @@ -137,19 +137,19 @@ $$ stop_id | stop_sequence | arrival_time | trip_id ---------+---------------+--------------+--------- 10017 | 0 | 1712707200 | - 50017 | 1 | 1712759936 | 1753 - 50213 | 2 | 1712761984 | 1753 - 50342 | 3 | 1712763904 | 1753 - 50433 | 4 | 1712765824 | 1753 - 50603 | 5 | 1712768128 | 1753 - 50691 | 6 | 1712769408 | 1753 - 50811 | 7 | 1712770816 | 1753 - 51059 | 8 | 1712773120 | 1753 - 51190 | 9 | 1712775296 | 1753 - 51358 | 10 | 1712777088 | 1753 - 51451 | 11 | 1712777984 | 1753 - 51530 | 12 | 1712779136 | 1753 - 51607 | 13 | 1712779776 | 1753 + 50017 | 1 | 1712759880 | 1753 + 50213 | 2 | 1712762040 | 1753 + 50342 | 3 | 1712763960 | 1753 + 50433 | 4 | 1712765820 | 1753 + 50603 | 5 | 1712768160 | 1753 + 50691 | 6 | 1712769360 | 1753 + 50811 | 7 | 1712770860 | 1753 + 51059 | 8 | 1712773080 | 1753 + 51190 | 9 | 1712775300 | 1753 + 51358 | 10 | 1712777040 | 1753 + 51451 | 11 | 1712778000 | 1753 + 51530 | 12 | 1712779080 | 1753 + 51607 | 13 | 1712779800 | 1753 (14 rows) -- connected and route on multiple trips @@ -216,24 +216,24 @@ $$ stop_id | stop_sequence | arrival_time | trip_id ---------+---------------+--------------+--------- 10017 | 0 | 1712707200 | - 50017 | 1 | 1712752640 | 1663 - 50213 | 2 | 1712754816 | 1663 - 50342 | 3 | 1712756864 | 1663 - 50433 | 4 | 1712758656 | 1663 - 50603 | 5 | 1712761088 | 1663 - 50653 | 6 | 1712763648 | 5105 - 50691 | 7 | 1712764288 | 5105 - 50732 | 8 | 1712764928 | 5105 - 50744 | 9 | 1712765184 | 5105 - 50768 | 10 | 1712765568 | 5105 - 50770 | 11 | 1712765824 | 5105 - 50811 | 12 | 1712766464 | 5105 - 51059 | 13 | 1712773120 | 1753 - 51190 | 14 | 1712775296 | 1753 - 51358 | 15 | 1712777088 | 1753 - 51451 | 16 | 1712777984 | 1753 - 51530 | 17 | 1712779136 | 1753 - 51607 | 18 | 1712779776 | 1753 + 50017 | 1 | 1712752620 | 1663 + 50213 | 2 | 1712754840 | 1663 + 50342 | 3 | 1712756820 | 1663 + 50433 | 4 | 1712758680 | 1663 + 50603 | 5 | 1712761080 | 1663 + 50653 | 6 | 1712763600 | 5105 + 50691 | 7 | 1712764320 | 5105 + 50732 | 8 | 1712764920 | 5105 + 50744 | 9 | 1712765190 | 5105 + 50768 | 10 | 1712765580 | 5105 + 50770 | 11 | 1712765850 | 5105 + 50811 | 12 | 1712766420 | 5105 + 51059 | 13 | 1712773080 | 1753 + 51190 | 14 | 1712775300 | 1753 + 51358 | 15 | 1712777040 | 1753 + 51451 | 16 | 1712778000 | 1753 + 51530 | 17 | 1712779080 | 1753 + 51607 | 18 | 1712779800 | 1753 (19 rows) -- disconnected (origin and destination exist) diff --git a/expected/pgtfs_test.out.license b/tests/expected/pgtfs_test.out.license similarity index 100% rename from expected/pgtfs_test.out.license rename to tests/expected/pgtfs_test.out.license diff --git a/sql/network_edge_cases_test.sql b/tests/sql/network_edge_cases_test.sql similarity index 100% rename from sql/network_edge_cases_test.sql rename to tests/sql/network_edge_cases_test.sql diff --git a/sql/pgtfs_test.sql b/tests/sql/pgtfs_test.sql similarity index 100% rename from sql/pgtfs_test.sql rename to tests/sql/pgtfs_test.sql