@golemio/pid
Version:
Golemio PID Module
270 lines • 14.6 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeparturesRepository = void 0;
const RouteTypeEnums_1 = require("../../../../helpers/RouteTypeEnums");
const const_1 = require("../../../../schema-definitions/const");
const precomputed_1 = require("../../../../schema-definitions/ropid-gtfs/models/precomputed");
const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken");
const models_1 = require("@golemio/core/dist/integration-engine/models");
const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors");
const golemio_validator_1 = require("@golemio/core/dist/shared/golemio-validator");
const sequelize_1 = require("@golemio/core/dist/shared/sequelize");
const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
const SourceTableSuffixEnum_1 = require("../../helpers/SourceTableSuffixEnum");
let DeparturesRepository = class DeparturesRepository extends models_1.PostgresModel {
constructor(config, logger) {
super("DeparturesRepository", {
pgTableName: precomputed_1.DeparturesModel.TABLE_NAME,
pgSchema: const_1.PG_SCHEMA,
outputSequelizeAttributes: precomputed_1.DeparturesModel.attributeModel,
attributesToRemove: ["id", "created_at", "updated_at"],
savingType: "insertOnly",
}, new golemio_validator_1.JSONSchemaValidator("DeparturesRepository", precomputed_1.DeparturesModel.jsonSchema));
this.config = config;
this.logger = logger;
this.createAndPopulate = async (sourceTableSuffix) => {
const nodeEnv = this.config.getValue("env.NODE_ENV", "development");
const timeConstraintLiteral = nodeEnv !== "test" ? `WHERE gtfs_timestamp(t.arrival_time, t4.date) > now() - interval '6 hours'` : "";
/* eslint-disable max-len */
const sql = `
SELECT
t.stop_sequence,
t.stop_headsign,
t.pickup_type,
t.drop_off_type,
t.arrival_time,
gtfs_timestamp(t.arrival_time, t4.date) AS arrival_datetime,
t.departure_time,
gtfs_timestamp(t.departure_time, t4.date) AS departure_datetime,
t0.stop_id,
t0.stop_name,
t0.platform_code,
t0.wheelchair_boarding,
t1.min_stop_sequence,
t1.max_stop_sequence,
t2.trip_id,
t2.trip_headsign,
t2.trip_short_name,
t2.wheelchair_accessible,
t3.service_id,
t4.date,
t5.route_short_name,
coalesce(t5.route_type, :defaultRouteType) AS route_type,
t5.route_id,
t5.is_night,
t5.is_regional,
t5.is_substitute_transport,
t6.stop_sequence AS next_stop_sequence,
t6.stop_id AS next_stop_id,
t7.stop_sequence AS last_stop_sequence,
t7.stop_id AS last_stop_id,
cis_stop.cis AS cis_stop_group_id,
CASE
WHEN t.stop_headsign IS NOT NULL THEN t.headsign_icons
ELSE t2.headsign_icons
END AS trip_headsign_icons,
t8."connections" AS trip_connections,
next_route.route_short_name AS next_route_short_name,
next_trip.trip_headsign AS next_trip_headsign,
max_headsign_seq.max_seq_with_headsign AS max_stop_sequence_with_stop_headsign,
t2.direction_id
FROM ropidgtfs_stop_times${sourceTableSuffix} t
LEFT JOIN ropidgtfs_trips${sourceTableSuffix} t2 ON t.trip_id = t2.trip_id
INNER JOIN ropidgtfs_precomputed_services_calendar_tmp t4 ON t2.service_id = t4.service_id
INNER JOIN ropidgtfs_precomputed_minmax_stop_sequences_tmp t1 ON t.trip_id = t1.trip_id
LEFT JOIN ropidgtfs_calendar${sourceTableSuffix} t3 ON t2.service_id = t3.service_id
LEFT JOIN ropidgtfs_stops${sourceTableSuffix} t0 ON t.stop_id = t0.stop_id
LEFT JOIN ropidgtfs_routes${sourceTableSuffix} t5 ON t2.route_id = t5.route_id
LEFT JOIN ropidgtfs_stop_times${sourceTableSuffix} t6 ON t.trip_id = t6.trip_id AND t6.stop_sequence = t.stop_sequence + 1
LEFT JOIN ropidgtfs_stop_times${sourceTableSuffix} t7 ON t.trip_id = t7.trip_id AND t7.stop_sequence = t.stop_sequence - 1
LEFT JOIN ropidgtfs_cis_stops cis_stop ON cis_stop.id = t0.computed_cis_stop_id
LEFT JOIN ropidgtfs_precomputed_trip_connections_tmp t8 ON t8.to_trip_id = t2.trip_id AND t8.to_stop_id = t.stop_id
LEFT JOIN LATERAL (
SELECT
next_t.trip_id,
next_t.trip_headsign,
next_t.route_id
FROM ropidgtfs_trips${sourceTableSuffix} next_t
INNER JOIN ropidgtfs_precomputed_minmax_stop_sequences_tmp next_minmax ON next_t.trip_id = next_minmax.trip_id
INNER JOIN ropidgtfs_stop_times${sourceTableSuffix} next_st ON next_t.trip_id = next_st.trip_id
AND next_st.stop_sequence = next_minmax.min_stop_sequence
INNER JOIN ropidgtfs_stop_times${sourceTableSuffix} curr_last_st ON t2.trip_id = curr_last_st.trip_id
AND curr_last_st.stop_sequence = t1.max_stop_sequence
WHERE t2.block_id IS NOT NULL
AND next_t.block_id = t2.block_id
AND next_t.trip_id != t2.trip_id
AND next_t.service_id = t2.service_id
AND gtfs_timestamp(next_st.departure_time, t4.date) >= gtfs_timestamp(curr_last_st.arrival_time, t4.date)
ORDER BY gtfs_timestamp(next_st.departure_time, t4.date) ASC
LIMIT 1
) next_trip ON true
LEFT JOIN ropidgtfs_routes${sourceTableSuffix} next_route ON next_trip.route_id = next_route.route_id
LEFT JOIN LATERAL (
SELECT MAX(st.stop_sequence) AS max_seq_with_headsign
FROM ropidgtfs_stop_times${sourceTableSuffix} st
WHERE st.trip_id = t2.trip_id
AND st.stop_headsign IS NOT NULL
) max_headsign_seq ON true
${timeConstraintLiteral}`;
/* eslint-enable max-len */
try {
const tableName = precomputed_1.DeparturesModel.TABLE_NAME;
const tmpTableName = tableName + SourceTableSuffixEnum_1.SourceTableSuffixEnum.Tmp;
await this.sequelizeModel.sequelize.query(`
SET LOCAL search_path TO ${const_1.PG_SCHEMA};
DROP TABLE IF EXISTS ${tmpTableName};
CREATE TABLE ${tmpTableName} (LIKE ${tableName} including all);
INSERT INTO ${tmpTableName} ${sql};`, {
replacements: {
defaultRouteType: RouteTypeEnums_1.GTFSRouteTypeEnum.EXT_MISCELLANEOUS,
},
});
}
catch (err) {
this.logger.error(err);
throw err;
}
};
this.countDeparturesForPublicCache = async (intervalParams) => {
try {
return await this.sequelizeModel.count({
where: {
[sequelize_1.Op.and]: {
departure_datetime: {
[sequelize_1.Op.between]: [
sequelize_1.Sequelize.literal(`now() + interval '${intervalParams.intervalFromHours} hours'`),
sequelize_1.Sequelize.literal(`now() + interval '${intervalParams.intervalToHours} hours'`),
],
},
next_stop_sequence: {
[sequelize_1.Op.not]: null,
},
},
},
});
}
catch (err) {
throw new golemio_errors_1.GeneralError("Error while getting number of departures", this.constructor.name, err);
}
};
this.getDepaturesForPublicCache = async (page, pageSize, intervalParams) => {
try {
return await this.sequelizeModel.findAll({
attributes: [
"stop_id",
"departure_datetime",
"arrival_datetime",
"route_short_name",
"route_type",
"trip_id",
"stop_sequence",
"platform_code",
"trip_headsign",
"stop_headsign",
"trip_headsign_icons",
"trip_connections",
"wheelchair_accessible",
"direction_id",
"is_night",
"is_regional",
"is_substitute_transport",
],
where: {
departure_datetime: {
[sequelize_1.Op.between]: [
sequelize_1.Sequelize.literal(`now() + interval '${intervalParams.intervalFromHours} hours'`),
sequelize_1.Sequelize.literal(`now() + interval '${intervalParams.intervalToHours} hours'`),
],
},
next_stop_sequence: { [sequelize_1.Op.not]: null },
pickup_type: { [sequelize_1.Op.ne]: "1" },
stop_sequence: {
[sequelize_1.Op.ne]: sequelize_1.Sequelize.col("max_stop_sequence"),
},
},
order: [["departure_datetime", "ASC"]],
offset: page * pageSize,
limit: pageSize,
raw: true,
});
}
catch (err) {
throw new golemio_errors_1.GeneralError("Error while getting departures for public cache", this.constructor.name, err);
}
};
this.replaceByTmp = async (transaction) => {
try {
const tableName = precomputed_1.DeparturesModel.TABLE_NAME;
const tmpTableName = tableName + SourceTableSuffixEnum_1.SourceTableSuffixEnum.Tmp;
const dropTableName = tableName + SourceTableSuffixEnum_1.SourceTableSuffixEnum.Drop;
await this.sequelizeModel.sequelize.query(`
SET LOCAL search_path TO ${const_1.PG_SCHEMA};
LOCK ${tableName} IN EXCLUSIVE MODE;
ALTER TABLE ${tableName} RENAME TO ${dropTableName};
ALTER TABLE ${tmpTableName} RENAME TO ${tableName};
DROP TABLE ${dropTableName} CASCADE;`, { transaction });
}
catch (err) {
this.logger.error(err);
throw err;
}
};
this.getTripStopsForCache = async () => {
const nodeEnv = this.config.getValue("env.NODE_ENV", "development");
const departureTimeFilter = nodeEnv !== "test"
? `AND date BETWEEN (now() - interval '1 day')::date AND (now() + interval '1 day')::date
AND departure_datetime BETWEEN now() - interval '1 hour' AND now() + interval '2 hours'`
: "";
try {
const [results] = await this.sequelizeModel.sequelize.query(`
SELECT
pd.trip_id,
json_agg(json_build_array(stop_id, stop_name) ORDER BY stop_sequence) as stops
FROM ${const_1.PG_SCHEMA}.${precomputed_1.DeparturesModel.TABLE_NAME} AS pd
INNER JOIN (
SELECT date, trip_id
FROM ${const_1.PG_SCHEMA}.${precomputed_1.DeparturesModel.TABLE_NAME}
WHERE stop_sequence = 1
${departureTimeFilter}
) AS target
ON pd.date = target.date AND pd.trip_id = target.trip_id
WHERE pd.stop_id IS NOT NULL
GROUP BY pd.date, pd.trip_id;
`);
return results;
}
catch (err) {
throw new golemio_errors_1.GeneralError("Error while getting trip stops for cache", this.constructor.name, err);
}
};
this.analyze = async () => {
try {
await this.sequelizeModel.sequelize.query(`analyze ${const_1.PG_SCHEMA}.${precomputed_1.DeparturesModel.TABLE_NAME}${SourceTableSuffixEnum_1.SourceTableSuffixEnum.Tmp};`);
}
catch (err) {
this.logger.error(err);
throw err;
}
};
}
};
exports.DeparturesRepository = DeparturesRepository;
exports.DeparturesRepository = DeparturesRepository = __decorate([
(0, tsyringe_1.injectable)(),
__param(0, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.SimpleConfig)),
__param(1, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.Logger)),
__metadata("design:paramtypes", [Object, Object])
], DeparturesRepository);
//# sourceMappingURL=DeparturesRepository.js.map