UNPKG

@golemio/pid

Version:
310 lines • 16.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); 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 __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); 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); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TripWithLastPositionRepository = void 0; const const_1 = require("../../../../schema-definitions/const"); const NotPublicVehiclesRedisRepository_1 = require("../cache/NotPublicVehiclesRedisRepository"); const ProcessedPositionRepository_1 = require("./ProcessedPositionRepository"); const VehicleTypeRepository_1 = require("../VehicleTypeRepository"); const VehicleDescriptorRepository_1 = require("../VehicleDescriptorRepository"); const OgVehiclePositionsToken_1 = require("../../ioc/OgVehiclePositionsToken"); const models_1 = require("../../../../schema-definitions/vehicle-descriptors/models"); const vehicle_positions_1 = require("../../../../schema-definitions/vehicle-positions"); const views_1 = require("../../../../schema-definitions/vehicle-positions/models/views"); const Geo_1 = require("@golemio/core/dist/output-gateway/Geo"); const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors"); const moment_timezone_1 = __importDefault(require("@golemio/core/dist/shared/moment-timezone")); const sequelize_1 = __importStar(require("@golemio/core/dist/shared/sequelize")); const const_2 = require("../../../../const"); const RouteTypeEnums_1 = require("../../../../helpers/RouteTypeEnums"); const PositionOutputMapper_1 = require("../helpers/PositionOutputMapper"); const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe"); const AbstractBasicRepository_1 = require("@golemio/core/dist/helpers/data-access/postgres/repositories/AbstractBasicRepository"); const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken"); let TripWithLastPositionRepository = class TripWithLastPositionRepository extends AbstractBasicRepository_1.AbstractBasicRepository { constructor(connector, logger, notPublicVehiclesRepository, processedPositionRepository, vehicleTypeRepository, vehicleDescriptorRepository) { super(connector, logger); this.notPublicVehiclesRepository = notPublicVehiclesRepository; this.processedPositionRepository = processedPositionRepository; this.vehicleTypeRepository = vehicleTypeRepository; this.vehicleDescriptorRepository = vehicleDescriptorRepository; this.schema = const_1.PG_SCHEMA; this.tableName = views_1.TripWithLastPositionModel.tableName; /** Retrieves all vehicle trips * @param {object} options Options object with params * @param {number} [options.limit] Limit * @param {number} [options.offset] Offset * @param {string} [options.routeId] Filter trips by specific route id * @param {string} [options.routeShortName] Filter trips by specific route short name * @param {string} [options.tripId] Filter trips by specific trip id * @param {boolean} [options.includeNotTracking] Should include not tracking vehicle positions (those off a trip) * @returns Array of the retrieved records */ this.GetAll = async (options) => { const { limit, offset, updatedSince } = options; const minUpdatedAt = (0, moment_timezone_1.default)().subtract(10, "minutes"); // updatedSince cannot be more than 10 minutes ago const maxUpdatedAt = updatedSince && (0, moment_timezone_1.default)(updatedSince).isSameOrAfter(minUpdatedAt) ? updatedSince.toISOString() : null; const include = this.composeIncludes(options); let notPublicWhereConditions = []; if (options.includeNotPublic) { notPublicWhereConditions = await this.getNotPublicWhereConditions(); } try { const rows = await this.sequelizeModel.findAll({ attributes: { exclude: ["id", "vehicle_type_id"], }, include, limit, offset, where: { [sequelize_1.Op.and]: [ { state_position: { [sequelize_1.Op.in]: this.determinePossibleStatePositions(options.includeNotTracking, options.includeNotPublic), }, }, { [sequelize_1.Op.or]: [{ gtfs_trip_id: { [sequelize_1.Op.ne]: null } }, ...notPublicWhereConditions], }, maxUpdatedAt ? { updated_at: { [sequelize_1.Op.gt]: maxUpdatedAt, }, } : {}, options.cisTripNumber ? { cis_trip_number: options.cisTripNumber } : {}, options.routeId ? { gtfs_route_id: options.routeId } : {}, options.routeShortName ? { gtfs_route_short_name: options.routeShortName } : {}, options.tripId ? { gtfs_trip_id: options.tripId } : {}, ], }, }); if (rows.length === 0) { return { data: (0, Geo_1.buildGeojsonFeatureCollection)([]), metadata: { maxUpdatedAt: maxUpdatedAt || new Date().toISOString(), }, }; } let returnData = []; let maxUpdatedAtData = null; for (const row of rows) { returnData.push(PositionOutputMapper_1.PositionOutputMapper.mapTripModelToDto(row)); if (maxUpdatedAtData === null || row.updated_at > maxUpdatedAtData) { maxUpdatedAtData = row.updated_at; } } return { data: (0, Geo_1.buildGeojsonFeatureCollection)(returnData), metadata: { maxUpdatedAt: maxUpdatedAtData?.toISOString() || new Date().toISOString(), }, }; } catch (err) { throw new golemio_errors_1.GeneralError("Database error", "VehiclepositionsTripsModel", err, 500); } }; /** Retrieves specific vehicle trip * @param {string} id Id of the trip * @param {object} [options] Options object with params * @param {string} [options.includeNotTracking] Returns last known trip even if it is not tracked at time * @param {boolean} [options.includePositions] Should include all vehicle positions * @returns Object of the retrieved record or null */ this.GetOneByGTFSTripId = async (id, options) => { try { const include = this.composeIncludes(options); const data = await this.sequelizeModel.findOne({ attributes: { exclude: ["id", "vehicle_type_id"], include: ["updated_at"], }, include, where: { gtfs_trip_id: id, }, order: [["updated_at", "DESC"]], }); if (!data) { return null; } if (data.lat === null || data.lng === null) { throw new golemio_errors_1.GeneralError("Missing lat or lng", this.constructor.name, undefined, 500, "pid"); } return PositionOutputMapper_1.PositionOutputMapper.mapTripModelToDto(data); } catch (err) { throw new golemio_errors_1.GeneralError("Database error", "VehiclePositionsTripsModel", err, 500); } }; this.composeIncludes = (options) => { const possibleStatePositions = this.determinePossibleStatePositions(options.includeNotTracking, options.includeNotPublic); const include = [ { as: "vehicle_type", model: this.connector.getConnection().models[vehicle_positions_1.VehiclePositions.vehicleTypes.pgTableName], }, { as: "vehicle_descriptor", model: this.connector.getConnection().models[models_1.DescriptorModel.tableName], attributes: ["is_air_conditioned", "has_usb_chargers"], }, ]; if (options.includePositions) { include.push({ attributes: { exclude: ["trips_id", "state_position"], }, as: "all_positions", model: this.connector.getConnection().models[views_1.ProcessedPositionModel.tableName], where: { state_position: { [sequelize_1.Op.in]: possibleStatePositions, }, }, }); } return include; }; this.determinePossibleStatePositions = (includeNotTracking, includeNotPublic) => { const possibleStatePosition = [const_2.StatePositionEnum.AT_STOP, const_2.StatePositionEnum.ON_TRACK]; if (includeNotTracking) { possibleStatePosition.push(const_2.StatePositionEnum.AFTER_TRACK, const_2.StatePositionEnum.AFTER_TRACK_DELAYED, const_2.StatePositionEnum.BEFORE_TRACK, const_2.StatePositionEnum.BEFORE_TRACK_DELAYED, const_2.StatePositionEnum.CANCELED, const_2.StatePositionEnum.OFF_TRACK); } if (includeNotPublic) { possibleStatePosition.push(const_2.StatePositionEnum.NOT_PUBLIC); } return possibleStatePosition; }; this.getNotPublicWhereConditions = async () => { const conditions = []; // Fetch not-public vehicles config from Redis const { tram: { registrationNumbers: tramRegistrationNumbers }, road: { registrationNumbers: roadRegistrationNumbers }, routeIds: allowedRouteNames, } = await this.notPublicVehiclesRepository.getConfig(); // Add tram vehicles condition only if we have tram registration numbers if (tramRegistrationNumbers && tramRegistrationNumbers.length > 0) { conditions.push({ [sequelize_1.Op.and]: [ { gtfs_route_type: RouteTypeEnums_1.GTFSRouteTypeEnum.TRAM }, { vehicle_registration_number: { [sequelize_1.Op.in]: tramRegistrationNumbers } }, ], }); } // Add road vehicles condition only if we have road registration numbers if (roadRegistrationNumbers && roadRegistrationNumbers.length > 0) { conditions.push({ [sequelize_1.Op.and]: [ { gtfs_route_type: { [sequelize_1.Op.in]: [RouteTypeEnums_1.GTFSRouteTypeEnum.BUS, RouteTypeEnums_1.GTFSRouteTypeEnum.TROLLEYBUS], }, }, { vehicle_registration_number: { [sequelize_1.Op.in]: roadRegistrationNumbers } }, ], }); } // Add route names condition only if we have route IDs if (allowedRouteNames && allowedRouteNames.length > 0) { conditions.push({ origin_route_name: { [sequelize_1.Op.in]: allowedRouteNames }, }); } return conditions; }; this.sequelizeModel = connector.getConnection().define(this.tableName, views_1.TripWithLastPositionModel.attributeModel, { schema: this.schema, }); // Set up associations this.sequelizeModel.hasMany(this.processedPositionRepository.sequelizeModel, { as: "all_positions", foreignKey: "trips_id", scope: { lat: { [sequelize_1.Op.not]: null }, lng: { [sequelize_1.Op.not]: null }, }, }); this.sequelizeModel.belongsTo(this.vehicleTypeRepository.sequelizeModel, { as: "vehicle_type", foreignKey: "vehicle_type_id", }); this.sequelizeModel.belongsTo(this.vehicleDescriptorRepository.sequelizeModel, { as: "vehicle_descriptor", foreignKey: "vehicle_registration_number", targetKey: "registration_number", scope: { [sequelize_1.default.Op.and]: [ sequelize_1.default.literal(`${views_1.TripWithLastPositionModel.tableName}.gtfs_route_type = vehicle_descriptor.gtfs_route_type`), ], }, }); } GetOne() { throw new Error("Not implemented"); } }; exports.TripWithLastPositionRepository = TripWithLastPositionRepository; exports.TripWithLastPositionRepository = TripWithLastPositionRepository = __decorate([ (0, tsyringe_1.injectable)(), __param(0, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.PostgresConnector)), __param(1, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.Logger)), __param(2, (0, tsyringe_1.inject)(OgVehiclePositionsToken_1.OgVehiclePositionsToken.NotPublicVehiclesRedisRepository)), __param(3, (0, tsyringe_1.inject)(OgVehiclePositionsToken_1.OgVehiclePositionsToken.ProcessedPositionRepository)), __param(4, (0, tsyringe_1.inject)(OgVehiclePositionsToken_1.OgVehiclePositionsToken.VehicleTypeRepository)), __param(5, (0, tsyringe_1.inject)(OgVehiclePositionsToken_1.OgVehiclePositionsToken.VehicleDescriptorRepository)), __metadata("design:paramtypes", [Object, Object, NotPublicVehiclesRedisRepository_1.NotPublicVehiclesRedisRepository, ProcessedPositionRepository_1.ProcessedPositionRepository, VehicleTypeRepository_1.VehicleTypeRepository, VehicleDescriptorRepository_1.VehicleDescriptorRepository]) ], TripWithLastPositionRepository); //# sourceMappingURL=TripWithLastPositionRepository.js.map