diff --git a/src/controllers/train.controllers.js b/src/controllers/train.controllers.js index b258751..1022432 100644 --- a/src/controllers/train.controllers.js +++ b/src/controllers/train.controllers.js @@ -30,6 +30,9 @@ async function get(req, res, next) { case 'headcode': res.json(await train.findByHeadcode(date, id)); break; + case 'trainuid': + res.json(await train.findByTrainUid(id, date)); + break; default: res.status(404).json({ status:'error', diff --git a/src/services/dbAccess.services.js b/src/services/dbAccess.services.js index fa2710a..6c1b0ef 100644 --- a/src/services/dbAccess.services.js +++ b/src/services/dbAccess.services.js @@ -26,6 +26,24 @@ async function query(collection, query, returnId = false){ return (await qcursor.toArray()); } +async function queryProject(collection, query, projection) { + await client.connect(); + log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, 'info'); + const qcoll = db.collection(collection); + const qcursor = qcoll.find(query).project(projection); + log.out(`dbAccess.query: Running Query: ${JSON.stringify(query)}, Projection: ${JSON.stringify(projection)}`, 'dbug'); + increment(collection); + return await qcursor.toArray(); +} + +async function queryAggregate(collection, pipeline) { + await client.connect(); + log.out(`dbAccess.queryProject: Connecting to col: '${collection}'`, 'info'); + log.out(`dbAccess.query: Running Aggregation: ${JSON.stringify(pipeline)}`, 'dbug'); + increment(collection); + return await db.collection(collection).aggregate(pipeline).toArray(); +} + async function increment(target) { log.out(`dbAccess.increment: Incrementing counter for: ${target}`, 'info'); await client.connect(); @@ -87,6 +105,8 @@ async function colCount(collection) { module.exports = { query, + queryProject, + queryAggregate, increment, addUser, userAtime, diff --git a/src/services/trainService.services.js b/src/services/trainService.services.js index c10a055..5646f9d 100644 --- a/src/services/trainService.services.js +++ b/src/services/trainService.services.js @@ -2,6 +2,7 @@ const log = require('../utils/log.utils'); const db = require('./dbAccess.services'); const clean = require('../utils/sanitizer.utils'); const pis = require('../services/pis.services'); +const { filter } = require('compression'); async function findByHeadcodeToday(headcode) { const sanitizedHeadcode = clean.removeNonAlphanumeric(headcode).toUpperCase(); @@ -56,30 +57,64 @@ async function findByHeadcode(date, headcode) { scheduleEndDate: {$gte: searchDate}, daysRun: {$in: [shortDay]} }; - const queryData = await db.query('timetable', query); - let trainData = await parseTrains(queryData); - let preparedData = []; - for (let trainService of trainData) { - // Search for PIS Code for each service if supported by PIS services - if (pis.supported.includes(trainService?.operator)) { - const tiplocList = await getPublicStops(trainService?.stops); - //console.log(tiplocList.length); console.log(tiplocList); - if (tiplocList.length) { - const pisDetail = await pis.findByTiplocArray(tiplocList); - trainService.pis = pisDetail?.[0]?.['code'] ?? 'None'; - } else if (trainService.operator === 'GW' && !tiplocList.length) { - // Not in Service code - for GWR Only - trainService.pis = '0015'; + const pipeline = [ + { + $match: query + }, + { + $project: { + operator: 1, + stops: { + $concatArrays: [ + [{ $first: '$stops'}], + [{ $arrayElemAt: ['$stops', -1]}] + ] + }, + trainUid: 1, + stpIndicator: 1 } } - preparedData.push(trainService); + ]; + const queryData = await db.queryAggregate('timetable', pipeline); + console.log(JSON.stringify(queryData)); + let filteredData = filterServices(queryData); + return await filteredData; +} + +async function findByTrainUid(uid, date = new Date()) { + let queryDate; + if (date === 'now') { + queryDate = new Date(); + } else { + queryDate = date; } - return preparedData; + const query = { + trainUid: uid, + scheduleStartDate: {$lte: queryDate}, + scheduleEndDate: {$gte: queryDate} + }; + const queryData = await db.query('timetable', query); + if (queryData.length === 0) { + return []; + } + let services; + services = await filterServices(queryData); + console.log(services); + let publicStops; + if (pis.supported.includes(services[0]?.operator)) { + publicStops = await getPublicStops(services[0]?.stops); + const pisCode = await pis.findByTiplocArray(publicStops); + services[0].pis = pisCode[0]?.code; + } else if ( services[0]?.operator === 'GW' && !publicStops.length) { + services[0].pis = '0015'; + } + return services[0]; } module.exports = { findByHeadcodeToday, - findByHeadcode + findByHeadcode, + findByTrainUid }; /* Internal Functions, not to be exported */ @@ -115,21 +150,9 @@ async function parseTrains(data) { return parsedData; } -/* Queries using a trainUid and filters all schedules that - have been over-ridden by overlays, cancellations and new - schedules. */ -async function findByTrainUid(uid, date = new Date()) { - const query = { - trainUid: uid, - scheduleStartDate: {$lte: date}, - scheduleEndDate: {$gte: date} - }; - const queryData = await db.query('timetable', query); - if (queryData.length === 0) { - return []; - } - let stpIndicators = {}; - for (const serviceDetail of queryData) { +async function filterServices(data) { + let stpIndicators = {}, filteredServices = []; + for (const serviceDetail of data) { const trainUid = serviceDetail['trainUid']; const stpIndicator = serviceDetail['stpIndicator']; if (!stpIndicators[trainUid]) { @@ -153,30 +176,30 @@ async function findByTrainUid(uid, date = new Date()) { stpIndicators[trainUid].hasP = true; } } - let preparedData = []; - for (const serviceDetail of queryData) { + let preparedData; + for (const serviceDetail of data) { const trainUid = serviceDetail['trainUid']; const thisStpIndicators = stpIndicators[trainUid]; const stpIndicator = serviceDetail['stpIndicator']; if (stpIndicator === 'C') { - return; + break; } if (stpIndicator === 'N' && !thisStpIndicators.hasC) { - return serviceDetail; + filteredServices.push(serviceDetail); } else if (stpIndicator === 'O' && !thisStpIndicators.hasC && !thisStpIndicators.hasN) { - return serviceDetail; + filteredServices.push(serviceDetail); } else if (stpIndicator === 'P' && !thisStpIndicators.hasC && !thisStpIndicators.hasN && !thisStpIndicators.hasO) { - return serviceDetail; + filteredServices.push(serviceDetail); } } - return preparedData; -} \ No newline at end of file + return filteredServices; +}