implemented task 6

This commit is contained in:
Jonas Hinterdorfer 2025-03-16 18:11:14 +01:00
parent 89dc70e3e1
commit b4dcd13773
8 changed files with 202 additions and 73 deletions

View File

@ -19,3 +19,15 @@ GET http://localhost:3000/api/airports/?icaoCodes=true
### get one airports ### get one airports
GET http://localhost:3000/api/airports/EDDF GET http://localhost:3000/api/airports/EDDF
###
PUT http://localhost:3000/api/flights/AB123
Content-Type: application/json
{
"departure": "2023-12-01T10:00:00.000Z",
"arrival": "2023-12-01T14:00:00.000Z",
"operates": "OE-LAB",
"departs": "LOWW",
"arrives": "EDDF"
}

View File

@ -6,7 +6,7 @@ import {PlaneModel} from "../models/plane.model";
export class DB { export class DB {
static async createDBConnection() : Promise<Database> { static async createDBConnection(): Promise<Database> {
const connection = await open({ const connection = await open({
filename: `./flights.db`, filename: `./flights.db`,
driver: sqlite3.Database driver: sqlite3.Database
@ -29,79 +29,75 @@ export class DB {
await db.exec("rollback;") await db.exec("rollback;")
} }
private static async createTables(db: Database){ private static async createTables(db: Database) {
await this.beginTransaction(db); await this.beginTransaction(db);
try{ try {
await db.exec(`create table if not exists Airport ( await db.exec(`create table if not exists Airport
icao TEXT NOT NULL, (
name TEXT NOT NULL, icao TEXT NOT NULL,
country TEXT NOT NULL, name TEXT NOT NULL,
runwayLength TEXT NOT NULL, country TEXT NOT NULL,
CONSTRAINT pk_airport PRIMARY KEY (icao) runwayLength TEXT NOT NULL,
)`); CONSTRAINT pk_airport PRIMARY KEY (icao)
)`);
await db.exec(`create table if not exists Plane await db.exec(`create table if not exists Plane
( (
tailNo Text Not Null, tailNo Text Not Null,
model Text not null, model Text not null,
manufacturer text not null, manufacturer text not null,
capacity int not null, capacity int not null,
constraint pk_plane primary key (tailNo) constraint pk_plane primary key (tailNo)
);`) );`)
await db.exec(`create table if not exists Flight await db.exec(`create table if not exists Flight
( (
flightNo TEXT not null , flightNo TEXT not null,
departure text not null, departure text not null,
arrival text, arrival text,
operates Text not null, operates Text not null,
departs text not null, departs text not null,
arrives text not null, arrives text not null,
constraint pk_plane primary key (flightNo), constraint pk_plane primary key (flightNo),
constraint fk_arrives foreign key (arrives) references Airport (icao), constraint fk_arrives foreign key (arrives) references Airport (icao),
constraint fk_departs foreign key (arrives) references Airport (icao) constraint fk_departs foreign key (arrives) references Airport (icao)
);`); );`);
await db.exec(` create table if not exists Passenger await db.exec(` create table if not exists Passenger
( (
ssn TEXT not null, ssn TEXT not null,
name TEXT not null, name TEXT not null,
dateOfBirth text not null, dateOfBirth text not null,
isFemale boolean, isFemale boolean,
constraint pk_passenger primary key (ssn) constraint pk_passenger primary key (ssn)
); );
`); `);
await db.exec(`create table if not exists Reservation await db.exec(`create table if not exists Reservation
( (
ticketNo INTEGER not null primary key autoincrement, ticketNo INTEGER not null primary key autoincrement,
seat TEXT not null, seat TEXT not null,
flight TEXT not null, flight TEXT not null,
passenger TEXT not null, passenger TEXT not null,
constraint fk_flight foreign key (flight) references Flight (flightNo), constraint fk_flight foreign key (flight) references Flight (flightNo),
constraint fk_passenger foreign key (passenger) references Passenger (ssn) constraint fk_passenger foreign key (passenger) references Passenger (ssn)
);`); );`);
await this.commitTransaction(db); await this.commitTransaction(db);
} } catch (error) {
catch (error){
console.error(error); console.error(error);
await this.rollbackTransaction(db) await this.rollbackTransaction(db)
} }
} }
private static async addDefaultDataIfNeeded(db : Database) private static async addDefaultDataIfNeeded(db: Database) {
{
const planeCount = await db.get('select count(*) num from Plane;') const planeCount = await db.get('select count(*) num from Plane;')
const airportCount = await db.get('select count(*) num from Airport;') const airportCount = await db.get('select count(*) num from Airport;')
if(planeCount.num === undefined || planeCount.num === 0) if (planeCount.num === undefined || planeCount.num === 0) {
{
await this.addDefaultPlanes(db); await this.addDefaultPlanes(db);
} }
if( airportCount.num === undefined || airportCount.num === 0) if (airportCount.num === undefined || airportCount.num === 0) {
{
await this.addDefaultAirports(db); await this.addDefaultAirports(db);
} }
@ -110,7 +106,6 @@ export class DB {
private static async addDefaultPlanes(db: Database) { private static async addDefaultPlanes(db: Database) {
const planes: PlaneModel[] = [ const planes: PlaneModel[] = [
new PlaneModel("OE-LAA", "A320 Neo", "Airbus", 164), new PlaneModel("OE-LAA", "A320 Neo", "Airbus", 164),
new PlaneModel("OE-LAB", "B737-800", "Boeing", 188), new PlaneModel("OE-LAB", "B737-800", "Boeing", 188),

View File

@ -1,16 +1,16 @@
import {PlaneModel} from "./plane.model";
import {AirportModel} from "./airport.model";
export class FlightModel { import {isNullOrUndefined} from "../utility";
export class FlightModel{
public flightNo : string; public flightNo : string;
public departure : Date; public departure : Date;
public departs : AirportModel; public departs : string;
public arrives : AirportModel; public arrives : string;
public arrival : Date | null; public arrival : Date | null;
public operates : PlaneModel; public operates : string;
constructor(flightNo: string, operates: PlaneModel, departs: AirportModel, arrives : AirportModel, constructor(flightNo: string, operates: string, departs: string, arrives : string,
departure: Date, arrival: Date | null = null) { departure: Date, arrival: Date | null = null) {
this.flightNo = flightNo; this.flightNo = flightNo;
this.departure = departure; this.departure = departure;
@ -19,4 +19,17 @@ export class FlightModel {
this.arrival = arrival; this.arrival = arrival;
this.operates = operates; this.operates = operates;
} }
// check the loical validaity of the flight model
static isValid(element : FlightModel): boolean {
return !isNullOrUndefined(element.flightNo) &&
!isNullOrUndefined(element.departure) &&
!isNullOrUndefined(element.departs) &&
!isNullOrUndefined(element.arrives) &&
!isNullOrUndefined(element.operates) &&
element.departure.getTime() > Date.now();
}
} }

View File

@ -1,12 +1,50 @@
import express, {Request, Response} from "express"; import express, {Request, Response} from "express";
import {Unit} from "../database/unit"; import {FlightModel} from "../models/flight.model";
import {StatusCodes} from "http-status-codes";
import {getDate, isNullOrUndefined} from "../utility";
import {AirportService} from "../services/airport.service";
import {PlaneService} from "../services/plane.service";
import {FlightService} from "../services/flight.service";
const router = express.Router(); const router = express.Router();
router.get('/', async (req : Request , res:Response) : Promise<void> => { router.put('/:flightNo', async (req : Request<{flightNo: string}, FlightModel>, res : Response) : Promise<void> => {
await Unit.create(true); const flightNo : string = req.params.flightNo;
res.sendStatus(200); const flight: FlightModel = req.body;
const departureDate = getDate(flight.departure);
const arrivalDate = flight.arrival === null ? { date : flight.arrival, isValid : true} : getDate(flight.arrival);
if(!departureDate.isValid || !arrivalDate.isValid || departureDate.date === null)
{
res.sendStatus(StatusCodes.BAD_REQUEST);
return;
}
flight.arrival = arrivalDate.date;
flight.departure = departureDate.date;
flight.flightNo = flightNo;
if(FlightModel.isValid(flight))
{
res.sendStatus(StatusCodes.BAD_REQUEST);
return;
}
const arrivalAirport = await AirportService.getOne(flight.arrives)
const departureAirport = await AirportService.getOne(flight.departs)
const plane = await PlaneService.getOne(flight.operates);
if(isNullOrUndefined(arrivalAirport) || isNullOrUndefined(departureAirport) || isNullOrUndefined(plane))
{
res.sendStatus(StatusCodes.BAD_REQUEST);
return;
}
await FlightService.updateOrCreate(flight);
res.sendStatus(StatusCodes.OK);
}) })
export default router; export default router;

View File

@ -2,6 +2,7 @@ import express, {Request, Response, Router} from "express";
import {PassengerModel} from "../models/passenger.model"; import {PassengerModel} from "../models/passenger.model";
import {StatusCodes} from "http-status-codes"; import {StatusCodes} from "http-status-codes";
import {PassengerService} from "../services/passenger.service"; import {PassengerService} from "../services/passenger.service";
import {getDate} from "../utility";
const router: Router = express.Router(); const router: Router = express.Router();
@ -10,14 +11,13 @@ router.put('/:ssn', async (request: Request<{ ssn: string }, PassengerModel>, re
const ssn: string = request.params.ssn; const ssn: string = request.params.ssn;
const passenger: PassengerModel = request.body; const passenger: PassengerModel = request.body;
if (typeof passenger.dateOfBirth === "string") { //warning because of type loss at run time const returnType = getDate(passenger.dateOfBirth)
passenger.dateOfBirth = new Date(Date.parse(passenger.dateOfBirth));
}
if (ssn === undefined || ssn.length != 9) { if ( !returnType.isValid || returnType.date === null || ssn === undefined || ssn.length != 9) {
response.sendStatus(StatusCodes.BAD_REQUEST); response.sendStatus(StatusCodes.BAD_REQUEST);
return; return;
} }
passenger.dateOfBirth = returnType.date;
passenger.ssn = ssn; passenger.ssn = ssn;
await PassengerService.updateOrCreate(passenger) await PassengerService.updateOrCreate(passenger)

View File

@ -0,0 +1,54 @@
import {ServiceBase} from "./serviceBase";
import {FlightModel} from "../models/flight.model";
export class FlightService extends ServiceBase {
static async getOne(flightNo : string) : Promise<FlightModel | null>{
const sql = `select flightNo, departure, arrival, operates, departs, arrives from Flight where flightNo = ?1`
const params = {
1: flightNo
}
return await this.get<FlightModel>(sql, params);
}
static async create(flight: FlightModel): Promise<boolean> {
const sql = `insert into Flight (flightNo, departure, arrival, operates, departs, arrives) VALUES
(?1, ?2, ?3, ?4, ?5, ?6)`;
const params = {
1: flight.flightNo,
2: flight.departure.toISOString(),
3: flight.arrival === null ? null : flight.arrival.toISOString(),
4: flight.operates,
5: flight.departs,
6: flight.arrives
};
return await this.run(sql, params, 1);
}
static async update(flight: FlightModel): Promise<boolean> {
const sql = `UPDATE Flight SET departure = ?1, arrival = ?2, operates = ?3, departs = ?4, arrives = ?5 WHERE flightNo = ?6`;
const params = {
1: flight.departure.toISOString(),
2: flight.arrival === null ? null : flight.arrival.toISOString(),
3: flight.operates,
4: flight.departs,
5: flight.arrives,
6: flight.flightNo
};
return await this.run(sql, params, 1);
}
static async updateOrCreate(flightModel : FlightModel) : Promise<void>{
const dbPassenger = await this.getOne(flightModel.flightNo);
if(dbPassenger === null)
{
await this.create(flightModel);
}
else{
await this.update(flightModel);
}
}
}

View File

@ -28,5 +28,4 @@ export class PlaneService extends ServiceBase {
return await this.all<string>(sql, params); return await this.all<string>(sql, params);
} }
} }

18
src/utility.ts Normal file
View File

@ -0,0 +1,18 @@
export function isNullOrUndefined(element : any)
{
return element === undefined || element === null
}
export function getDate(date : Date | string) : {date: Date | null, isValid: boolean} {
if (typeof date === "string") { //warning because of type loss at run time
const dateNum = Date.parse(date);
if(Number.isNaN(dateNum)){
return {date: null,isValid: true};
}
return {date: new Date(dateNum),isValid: true};
}
return {date: date,isValid: true};
}