renamed it a bit

This commit is contained in:
Jonas Hinterdorfer 2025-03-16 11:57:29 +01:00
parent ec6b96aadc
commit 67e32285a6
11 changed files with 114 additions and 47 deletions

View File

@ -1,4 +1,4 @@
# Flight Management
# FlightModel Management
We return to the flight database we used in one of the first assignments.
However, this time it got extended by a passenger list instead of a simple count.
@ -10,39 +10,39 @@ hide empty methods
skinparam nodesep 80
skinparam linetype ortho
entity Airport {
entity AirportModel {
* icao: string <<PK>>
* name: string
* country: string
* runwayLength: int
}
entity Plane {
entity PlaneModel {
* tailNo: string <<PK>>
* model: string
* manufacturer: string
* capacity: int
}
entity Flight {
entity FlightModel {
* flightNo: string <<PK>>
* departure: datetime
arrival: datetime
}
entity Passenger {
entity PassengerModel {
* ssn: string <<PK>>
* name: string
* dateOfBirth: datetime
isFemale: bool
}
entity Reservation {
entity ReservationModel {
* ticketNo: int <<PK>>
* seat: string
}
Airport ||-l-o{ Flight: departs
Airport ||-l-o{ Flight: arrives
Flight }o-l-|| Plane: operates
Flight ||--o{ Reservation: has
Passenger ||-r-|{ Reservation: has
AirportModel ||-l-o{ FlightModel: departs
AirportModel ||-l-o{ FlightModel: arrives
FlightModel }o-l-|| PlaneModel: operates
FlightModel ||--o{ ReservationModel: has
PassengerModel ||-r-|{ ReservationModel: has
@enduml
```
@ -51,8 +51,8 @@ Passenger ||-r-|{ Reservation: has
- The original three tables are _mostly_ unchanged and can be taken from the previous assignment
- Make sure to use proper data types & foreign keys again
- Mind the following hints for the new tables
- Passenger: `isFemale` is _nullable_ on purpose, so we can put null in case a person is neither male nor female
- Reservation: we don't use a composite primary key here (despite it normally being the way to go here), because
- PassengerModel: `isFemale` is _nullable_ on purpose, so we can put null in case a person is neither male nor female
- ReservationModel: we don't use a composite primary key here (despite it normally being the way to go here), because
the `ticketNo` has to use the 'autoincrement' feature
- You already know this feature from DBI (a sequence in Oracle)
- [Read up on how to use it in SQLite](https://www.sqlite.org/autoinc.html) - you _won't_ need any keywords,
@ -79,7 +79,7 @@ Passenger ||-r-|{ Reservation: has
| **ICAO** | **Name** | **Country** | **RunwayLength** |
|----------|------------------------------------------|-------------|------------------|
| LOWL | Blue Danube Airport Linz | Austria | 9842 |
| LOWL | Blue Danube AirportModel Linz | Austria | 9842 |
| LOWW | Vienna International | Austria | 11811 |
| LIRF | Leonardo da VinciFiumicino | Italy | 12795 |
| EGLL | Heathrow | UK | 12802 |
@ -126,7 +126,7 @@ Passenger ||-r-|{ Reservation: has
- Both have to exist
- Departure time
- Has to be in the future
- Plane which will operate the flight
- PlaneModel which will operate the flight
- Has to be one of the available planes
- Implement an endpoint for creating such flights
- Also allow for updates - for which all conditions still apply
@ -141,8 +141,8 @@ Passenger ||-r-|{ Reservation: has
- It has to be verified that
- Person exists
- As a simplification you do _not_ have to check if the Person is already booked on _another_ flight at the same time
- Flight exists
- Flight still has open seats (= capacity not exceeded)
- FlightModel exists
- FlightModel still has open seats (= capacity not exceeded)
- Seat not taken by another passenger
- The ticket number is created automatically by the database and returned to the user
- To make it easier you don't have to worry about updates or delete this time

View File

@ -1,5 +1,5 @@
import express, {json} from 'express';
import flightRouter from "./routes/flight-router";
import flightRouter from "./routes/flight.router";
const app = express();
app.use(json())

View File

@ -1,5 +1,8 @@
import {Database, open} from "sqlite";
import {Database, open, Statement} from "sqlite";
import sqlite3 from "sqlite3";
import {AirportModel} from "../models/airport.model";
import {PlaneModel} from "../models/plane.model";
export class DB {
@ -10,6 +13,7 @@ export class DB {
});
await connection.exec('PRAGMA foreign_keys = ON;');
await this.createTables(connection);
await this.addDefaultDataIfNeeded(connection);
return connection;
}
@ -85,4 +89,69 @@ export class DB {
}
}
private static async addDefaultDataIfNeeded(db : Database)
{
const planeCount = await db.get('select count(*) num from Plane;')
const airportCount = await db.get('select count(*) num from Airport;')
if(planeCount.num === undefined || planeCount.num === 0)
{
await this.addDefaultPlanes(db);
}
if( airportCount.num === undefined || airportCount.num === 0)
{
await this.addDefaultAirports(db);
}
}
private static async addDefaultPlanes(db: Database) {
const planes: PlaneModel[] = [
new PlaneModel("OE-LAA", "A320 Neo", "Airbus", 164),
new PlaneModel("OE-LAB", "B737-800", "Boeing", 188),
new PlaneModel("OE-LAC", "A319", "Airbus", 152),
new PlaneModel("OE-LAD", "B787-900", "Boeing", 260),
new PlaneModel("OE-LAE", "B737-800", "Boeing", 188),
new PlaneModel("OH-LPE", "B777-200", "Boeing", 330),
]
const smt: Statement = await db.prepare('insert into Plane (tailNo, model, manufacturer, capacity) ' +
'VALUES (?1, ?2, ?3, ?4);');
await this.beginTransaction(db);
for (const plane of planes) {
await smt.bind({1: plane.tailNo, 2: plane.model, 3: plane.manufacturer, 4: plane.capacity})
await smt.run();
}
await smt.finalize();
await this.commitTransaction(db);
}
private static async addDefaultAirports(db: Database) {
const airports: AirportModel[] = [
new AirportModel("LOWL", "Blue Danube AirportModel Linz", "Austria", 9842),
new AirportModel("LOWW", "Vienna International", "Austria", 11811),
new AirportModel("LIRF", "Leonardo da VinciFiumicino", "Italy", 12795),
new AirportModel("EGLL", "Heathrow", "UK", 12802),
new AirportModel("EDDF", "Frankfurt", "Germany", 13123),
new AirportModel("RJAA", "Narita International", "Japan", 13123),
new AirportModel("KATL", "HartsfieldJackson Atlanta International", "USA", 12390),
]
const smt: Statement = await db.prepare('insert into Airport (icao, name, country, runwayLength) ' +
'VALUES (?1, ?2, ?3, ?4)');
await this.beginTransaction(db);
for (const airport of airports) {
await smt.bind({1: airport.icao, 2: airport.name, 3: airport.country, 4: airport.runwayLength});
await smt.run();
}
await smt.finalize();
await this.commitTransaction(db);
}
}

View File

@ -1,15 +0,0 @@
import {Flight} from "./Flight";
export class Reservation{
public ticketNo : number = -1;
public seat : string;
public flight : Flight;
public passenger : Reservation;
constructor(seat: string, flight: Flight, passenger: Reservation) {
this.seat = seat;
this.flight = flight;
this.passenger = passenger;
}
}

View File

@ -1,4 +1,4 @@
export class Airport{
export class AirportModel {
public icao : string;
public name : string;
public country: string;

View File

@ -1,16 +1,16 @@
import {Plane} from "./Plane";
import {Airport} from "./Airport";
import {PlaneModel} from "./plane.model";
import {AirportModel} from "./airport.model";
export class Flight {
export class FlightModel {
public flightNo : string;
public departure : Date;
public departs : Airport;
public arrives : Airport;
public departs : AirportModel;
public arrives : AirportModel;
public arrival : Date | null;
public operates : Plane;
public operates : PlaneModel;
constructor(flightNo: string, operates: Plane, departs: Airport, arrives : Airport,
constructor(flightNo: string, operates: PlaneModel, departs: AirportModel, arrives : AirportModel,
departure: Date, arrival: Date | null = null) {
this.flightNo = flightNo;
this.departure = departure;

View File

@ -1,4 +1,4 @@
export class Passenger{
export class PassengerModel {
public ssn: string
public name: string
public dateOfBirth: Date

View File

@ -1,4 +1,4 @@
export class Plane{
export class PlaneModel {
public tailNo : string;
public model : string;
public manufacturer : string;

View File

@ -0,0 +1,15 @@
import {FlightModel} from "./flight.model";
export class ReservationModel {
public ticketNo : number = -1;
public seat : string;
public flight : FlightModel;
public passenger : ReservationModel;
constructor(seat: string, flight: FlightModel, passenger: ReservationModel) {
this.seat = seat;
this.flight = flight;
this.passenger = passenger;
}
}

View File

@ -1,11 +1,9 @@
import express, {Request, Response} from "express";
import {Unit} from "../database/Unit";
import {Unit} from "../database/unit";
const router = express.Router();
router.get('/', async (req : Request , res:Response) : Promise<void> => {
await Unit.create(true);
res.sendStatus(200);