Repository navigation
Expand file tree
/
Copy pathflightRoutes.js
More file actions
244 lines (228 loc) · 8.1 KB
/
Copy pathflightRoutes.js
File metadata and controls
244 lines (228 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
const express = require("express");
const router = express.Router();
const { connection } = require("./db");
const { redisClient } = require("./redisClient");
async function checkCache(req, res, cacheKey, sql, queryParams = []) {
console.log("Checking cache for ", cacheKey);
try {
const data = await redisClient.get(cacheKey);
if (data !== null) {
console.log("Cache hit");
res.json(JSON.parse(data));
} else {
console.log("Cache miss");
// console.log(sql);
connection.query(sql, queryParams, (err, result) => {
if (err) {
console.error("Error querying database:", err);
res.status(500).send("Error querying database");
return;
}
// Cache the result in Redis for future requests
redisClient.setEx(cacheKey, 3600, JSON.stringify(result)); // Cache for 1 hour
res.json(result); // Send the database result to the client
});
}
} catch (err) {
console.error("Error fetching from Redis:", err);
res.status(500).send("Error fetching data");
}
}
router.get("/delay-history/city/:city", async (req, res) => {
const { city } = req.params;
const cacheKey = `delay-history:city:${city}`;
// console.log(`cacheKey: ${cacheKey}`);
const sql = `
SELECT
ORIGIN_AIRPORT,
a.CITY AS ori_city,
DESTINATION_AIRPORT,
a1.CITY AS des_city,
f.delay_count
f.total_flights
FROM
(SELECT
ORIGIN_AIRPORT,
DESTINATION_AIRPORT,
SUM(CASE WHEN ARRIVAL_DELAY > 0 THEN 1 ELSE 0 END) AS delay_count,
COUNT(*) AS total_flights
FROM Flights
WHERE
ORIGIN_AIRPORT NOT LIKE '1__' AND
DESTINATION_AIRPORT NOT LIKE '1__'
GROUP BY ORIGIN_AIRPORT, DESTINATION_AIRPORT
) f
JOIN Airports a ON a.IATA_CODE = f.ORIGIN_AIRPORT
JOIN Airports a1 ON a1.IATA_CODE = f.DESTINATION_AIRPORT
WHERE a.city= ?
LIMIT 50
`;
checkCache(req, res, cacheKey, sql, [city], (res) => {
//caculate delay rate after getting delay_count and total_flights in res
const responseWithDelayRate = results.map((row) => {
const delay_rate =
row.total_flights > 0 ? row.delay_count / row.total_flights : 0;
return {
...row, // Keep all other fields in the result
delay_rate: delay_rate, // Add the computed delay_rate field
};
});
res.json(responseWithDelayRate);
});
});
router.get("/delay-history/airport/:airport", async (req, res) => {
console.log("Checking cache for delay-history of airports...");
const { airport } = req.params;
const cacheKey = `delay-history:airport:${airport}`;
const sql = `
SELECT
ORIGIN_AIRPORT,
a.CITY AS ori_city,
DESTINATION_AIRPORT,
a1.CITY AS des_city,
SUM(CASE WHEN ARRIVAL_DELAY > 0 THEN 1 ELSE 0 END) / COUNT(*) AS delay_rate
FROM Flights f
JOIN Airports a ON a.IATA_CODE = f.ORIGIN_AIRPORT
JOIN Airports a1 ON a1.IATA_CODE = f.DESTINATION_AIRPORT
WHERE ORIGIN_AIRPORT NOT LIKE '1__' AND DESTINATION_AIRPORT NOT LIKE '1__'
GROUP BY ORIGIN_AIRPORT, DESTINATION_AIRPORT
HAVING f.ORIGIN_AIRPORT= ?
LIMIT 50
`;
checkCache(req, res, cacheKey, sql, [airport]);
});
router.get("/delay-history/flight/:airline_IATA/:number", async (req, res) => {
console.log("search delay-history of flight numbers");
const { airline_IATA, number } = req.params;
console.log(`${airline_IATA}, ${number}`);
const cacheKey = `delay-history:flight:${airline_IATA}:${number}`;
const sql = `
SELECT YEAR, MONTH, DAY, DEPARTURE_TIME, ARRIVAL_TIME, ARRIVAL_DELAY
FROM Flights
WHERE AIRLINE = ? AND FLIGHT_NUMBER = ? AND DEPARTURE_TIME > 0
`;
checkCache(req, res, cacheKey, sql, [airline_IATA, number]);
});
//search delay rate of all airport
router.get("/delay-rate/airport", async (req, res) => {
console.log(`Search delay rate of all airports.`);
const cacheKey = `delay-rate:all-airports`;
const sql = `
SELECT
f.ORIGIN_AIRPORT,
a.LATITUDE,
a.LONGITUDE,
AVG(CASE WHEN f.ARRIVAL_DELAY > 0
THEN 1
ELSE 0
END) AS AVG_Delay_Rate
FROM Flights f
JOIN Airports a ON f.ORIGIN_AIRPORT = a.IATA_CODE
GROUP BY f.ORIGIN_AIRPORT
HAVING f.ORIGIN_AIRPORT NOT LIKE '1__'
`;
//'1__' filter out suspicious row for now
checkCache(req, res, cacheKey, sql);
});
//search delay rate of an airport
router.get("/delay-rate/airport/:airport_IATA", async (req, res) => {
const { airport_IATA } = req.params;
console.log(`Searching cache for delay rate of airport ${airport_IATA}...`);
const cacheKey = `delay-rate:airport:${airport_IATA}`;
const sql = `
SELECT
f.ORIGIN_AIRPORT,
a.LATITUDE,
a.LONGITUDE,
AVG(CASE WHEN f.ARRIVAL_DELAY > 0
THEN 1
ELSE 0
END) AS AVG_Delay_Rate
FROM Flights f
JOIN Airports a ON f.ORIGIN_AIRPORT = a.IATA_CODE
GROUP BY f.ORIGIN_AIRPORT
HAVING f.ORIGIN_AIRPORT NOT LIKE '1__'
`;
checkCache(req, res, cacheKey, sql, [airport_IATA]);
});
//search delay rate of origin airport${airport_IATA}
router.get("/delay-rate/route/from/:airport_IATA", (req, res) => {
const { airport_IATA } = req.params;
const cacheKey = `delay-rate:route:${airport_IATA}`;
console.log(airport_IATA);
console.log(`search delay rate of origin airport${airport_IATA}`);
const sql = `
SELECT
ORIGIN_AIRPORT,
a.LATITUDE AS origin_lat,
a.LONGITUDE AS origin_lon,
DESTINATION_AIRPORT,
a1.LATITUDE AS dest_lat,
a1.LONGITUDE AS dest_lon,
SUM(CASE WHEN ARRIVAL_DELAY > 0 THEN 1 ELSE 0 END) / COUNT(*) AS delay_rate
FROM Flights f
JOIN Airports a ON a.IATA_CODE = f.ORIGIN_AIRPORT
JOIN Airports a1 ON a1.IATA_CODE = f.DESTINATION_AIRPORT
WHERE ORIGIN_AIRPORT= ? AND DESTINATION_AIRPORT NOT LIKE '1__'
GROUP BY ORIGIN_AIRPORT, DESTINATION_AIRPORT
`; //'1__' filter out suspicious row for now
checkCache(req, res, cacheKey, sql, [airport_IATA]);
});
//search delay rate of all routes, limit X rows
router.get("/delay-rate/route/:limitXRows", (req, res) => {
const { limitXRows } = req.params;
console.log(`search delay rate of all routes, limit ${limitXRows} rows`);
const cacheKey = `delay-rate:route:${limitXRows}`;
const sql = `
SELECT
ORIGIN_AIRPORT,
a.LATITUDE AS origin_lat,
a.LONGITUDE AS origin_lon,
DESTINATION_AIRPORT,
a1.LATITUDE AS dest_lat,
a1.LONGITUDE AS dest_lon,
SUM(CASE WHEN ARRIVAL_DELAY > 0 THEN 1 ELSE 0 END) / COUNT(*) AS delay_rate
FROM Flights f
JOIN Airports a ON a.IATA_CODE = f.ORIGIN_AIRPORT
JOIN Airports a1 ON a1.IATA_CODE = f.DESTINATION_AIRPORT
WHERE ORIGIN_AIRPORT NOT LIKE '1__' AND DESTINATION_AIRPORT NOT LIKE '1__'
GROUP BY ORIGIN_AIRPORT, DESTINATION_AIRPORT
LIMIT ?
`;
const limit = parseInt(limitXRows, 10); //10: decimal
if (isNaN(limit)) {
return res.status(400).send("Invalid limit parameter");
}
//'1__' filter out suspicious row for now
checkCache(req, res, cacheKey, sql, [limit]);
});
//search delay rate of an route
router.get(
"/delay-rate/route/from/:airport_origin/to/:airport_destination",
(req, res) => {
const { airport_origin, airport_destination } = req.params;
const cacheKey = `delay-rate:route:${airport_origin}:${airport_destination}`;
console.log(
`search delay rate of the route: from ${airport_origin} to ${airport_destination}`
);
const sql = `
SELECT
ORIGIN_AIRPORT,
a.LATITUDE AS origin_lat,
a.LONGITUDE AS origin_lon,
DESTINATION_AIRPORT,
a1.LATITUDE AS dest_lat,
a1.LONGITUDE AS dest_lon,
SUM(CASE WHEN ARRIVAL_DELAY > 0 THEN 1 ELSE 0 END) / COUNT(*) AS delay_rate
FROM Flights f
JOIN Airports a ON a.IATA_CODE = f.ORIGIN_AIRPORT
JOIN Airports a1 ON a1.IATA_CODE = f.DESTINATION_AIRPORT
WHERE ORIGIN_AIRPORT = ? AND DESTINATION_AIRPORT = ?
AND ORIGIN_AIRPORT NOT LIKE '1__' AND DESTINATION_AIRPORT NOT LIKE '1__'
GROUP BY ORIGIN_AIRPORT, DESTINATION_AIRPORT
`;
//'1__' filter out suspicious row for now
checkCache(req, res, cacheKey, sql, [airport_origin, airport_destination]);
}
);
module.exports = router;