2 Commits

Author SHA1 Message Date
2771b5ea74 revert eeb63fa510
Some checks failed
Deploy Express API / deploy (push) Has been cancelled
revert Postgres DAL
2025-12-01 21:48:05 -08:00
eeb63fa510 Postgres DAL
Some checks failed
Deploy Express API / deploy (push) Has been cancelled
2025-12-01 22:44:15 -07:00
3 changed files with 2 additions and 293 deletions

150
package-lock.json generated
View File

@@ -10,8 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^5.1.0", "express": "^5.1.0"
"pg": "^8.16.3"
} }
}, },
"node_modules/accepts": { "node_modules/accepts": {
@@ -582,135 +581,6 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/pg": {
"version": "8.16.3",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
"license": "MIT",
"peer": true,
"dependencies": {
"pg-connection-string": "^2.9.1",
"pg-pool": "^3.10.1",
"pg-protocol": "^1.10.3",
"pg-types": "2.2.0",
"pgpass": "1.0.5"
},
"engines": {
"node": ">= 16.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.2.7"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
"integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
"license": "MIT",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
"integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
"license": "MIT"
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"license": "ISC",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-pool": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
"integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
"license": "MIT",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
"integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
"license": "MIT"
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"license": "MIT",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"license": "MIT",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"license": "MIT",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/proxy-addr": { "node_modules/proxy-addr": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -916,15 +786,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"license": "ISC",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/statuses": { "node_modules/statuses": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
@@ -980,15 +841,6 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC" "license": "ISC"
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
} }
} }
} }

View File

@@ -17,7 +17,6 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^5.1.0", "express": "^5.1.0"
"pg": "^8.16.3"
} }
} }

View File

@@ -1,142 +0,0 @@
import pkg from "pg";
const { Pool } = pkg;
const pool = new Pool({
user: "nate",
host: "localhost",
database: "gtfs",
password: "",
port: 5432,
});
// ---------------------- VEHICLES ----------------------
export async function getVehicles({ minLat, maxLat, minLng, maxLng, routeNum } = {}) {
let sql = `
SELECT vehicle_id, trip_id, route_id, ts, speed,
ST_Y(geom::geometry) AS latitude,
ST_X(geom::geometry) AS longitude
FROM rt_vehicles
`;
const params = [];
const conditions = [];
if (routeNum) {
conditions.push(`route_id = $${params.length + 1}`);
params.push(routeNum);
}
if (minLat != null) {
conditions.push(`ST_Y(geom::geometry) >= $${params.length + 1}`);
params.push(minLat);
}
if (maxLat != null) {
conditions.push(`ST_Y(geom::geometry) <= $${params.length + 1}`);
params.push(maxLat);
}
if (minLng != null) {
conditions.push(`ST_X(geom::geometry) >= $${params.length + 1}`);
params.push(minLng);
}
if (maxLng != null) {
conditions.push(`ST_X(geom::geometry) <= $${params.length + 1}`);
params.push(maxLng);
}
if (conditions.length) {
sql += " WHERE " + conditions.join(" AND ");
}
const { rows } = await pool.query(sql, params);
return rows.map(v => ({
vehicleId: v.vehicle_id,
tripId: v.trip_id,
routeId: v.route_id,
ts: Number(v.ts),
speed: v.speed,
location: { latitude: v.latitude, longitude: v.longitude }
}));
}
export async function getVehicleById(vehicleId) {
const sql = `
SELECT vehicle_id, trip_id, route_id, ts, speed,
ST_Y(geom::geometry) AS latitude,
ST_X(geom::geometry) AS longitude
FROM rt_vehicles
WHERE vehicle_id = $1
LIMIT 1
`;
const { rows } = await pool.query(sql, [vehicleId]);
if (!rows[0]) return null;
const v = rows[0];
return {
vehicleId: v.vehicle_id,
tripId: v.trip_id,
routeId: v.route_id,
ts: Number(v.ts),
speed: v.speed,
location: { latitude: v.latitude, longitude: v.longitude }
};
}
// ---------------------- ROUTES ----------------------
export async function getRoutes() {
const { rows } = await pool.query(`SELECT route_id, short_name, long_name, name FROM gtfs_routes`);
return rows;
}
export async function getRouteById(routeId) {
const { rows } = await pool.query(
`SELECT route_id, short_name, long_name, name FROM gtfs_routes WHERE route_id = $1 LIMIT 1`,
[routeId]
);
return rows[0] || null;
}
// ---------------------- STOPS ----------------------
export async function getStops() {
const { rows } = await pool.query(`
SELECT stop_id, stop_name, stop_lat, stop_lon
FROM gtfs_stops
`);
return rows;
}
export async function getStopById(stopId) {
const { rows } = await pool.query(`
SELECT stop_id, stop_name, stop_lat, stop_lon
FROM gtfs_stops
WHERE stop_id = $1
LIMIT 1
`, [stopId]);
return rows[0] || null;
}
// ---------------------- STOPS BY ROUTE ----------------------
export async function getStopsByRoute(routeId) {
const sql = `
SELECT s.stop_id, s.stop_name, s.stop_lat, s.stop_lon
FROM gtfs_stop_times st
JOIN gtfs_trips t ON st.trip_id = t.trip_id
JOIN gtfs_stops s ON st.stop_id = s.stop_id
WHERE t.route_id = $1
GROUP BY s.stop_id, s.stop_name, s.stop_lat, s.stop_lon
ORDER BY MIN(st.stop_sequence)
`;
const { rows } = await pool.query(sql, [routeId]);
return rows;
}
// ---------------------- TRIP SCHEDULE ----------------------
export async function getScheduleByTrip(tripId) {
const sql = `
SELECT st.stop_sequence, s.stop_id, s.stop_name, st.arrival_time, st.departure_time
FROM gtfs_stop_times st
JOIN gtfs_stops s ON st.stop_id = s.stop_id
WHERE st.trip_id = $1
ORDER BY st.stop_sequence
`;
const { rows } = await pool.query(sql, [tripId]);
return rows;
}