1 | DROP TABLE IF EXISTS SupportTicket CASCADE;
|
---|
2 | DROP TABLE IF EXISTS Wishlist CASCADE;
|
---|
3 | DROP TABLE IF EXISTS Notification CASCADE;
|
---|
4 | DROP TABLE IF EXISTS Payment CASCADE;
|
---|
5 | DROP TABLE IF EXISTS Review CASCADE;
|
---|
6 | DROP TABLE IF EXISTS BookingFlight CASCADE;
|
---|
7 | DROP TABLE IF EXISTS Booking CASCADE;
|
---|
8 | DROP TABLE IF EXISTS Flight CASCADE;
|
---|
9 | DROP TABLE IF EXISTS Airport CASCADE;
|
---|
10 | DROP TABLE IF EXISTS Destination CASCADE;
|
---|
11 | DROP TABLE IF EXISTS ApplicationUser CASCADE;
|
---|
12 | DROP TABLE IF EXISTS Administrator CASCADE;
|
---|
13 |
|
---|
14 | -- 1. Users
|
---|
15 | CREATE TABLE ApplicationUser (
|
---|
16 | UserID SERIAL PRIMARY KEY,
|
---|
17 | Name VARCHAR(100) NOT NULL,
|
---|
18 | Surname VARCHAR(100) NOT NULL,
|
---|
19 | Email VARCHAR(255) NOT NULL UNIQUE,
|
---|
20 | Password VARCHAR(255) NOT NULL,
|
---|
21 | PhoneNumber VARCHAR(50) UNIQUE,
|
---|
22 | DateJoined TIMESTAMP NOT NULL DEFAULT NOW()
|
---|
23 | );
|
---|
24 |
|
---|
25 | -- 2. Destinations
|
---|
26 | CREATE TABLE Destination (
|
---|
27 | DestinationID SERIAL PRIMARY KEY,
|
---|
28 | Name VARCHAR(255) NOT NULL,
|
---|
29 | Country VARCHAR(100) NOT NULL,
|
---|
30 | Description TEXT,
|
---|
31 | PopularAttraction TEXT,
|
---|
32 | BestTimeToVisit VARCHAR(50)
|
---|
33 | );
|
---|
34 |
|
---|
35 | -- 3. Airports
|
---|
36 | CREATE TABLE Airport (
|
---|
37 | AirportID SERIAL PRIMARY KEY,
|
---|
38 | Name VARCHAR(255) NOT NULL,
|
---|
39 | Country VARCHAR(100) NOT NULL,
|
---|
40 | Code VARCHAR(10) UNIQUE NOT NULL,
|
---|
41 | DestinationID INT NOT NULL,
|
---|
42 | CONSTRAINT fk_airport_destination FOREIGN KEY (DestinationID) REFERENCES Destination(DestinationID)
|
---|
43 | );
|
---|
44 |
|
---|
45 | -- 4. Flights
|
---|
46 | CREATE TABLE Flight (
|
---|
47 | FlightID SERIAL PRIMARY KEY,
|
---|
48 | FlightNumber VARCHAR(50) NOT NULL,
|
---|
49 | DepartureAirportID INT NOT NULL,
|
---|
50 | ArrivalAirportID INT NOT NULL,
|
---|
51 | DepartureTime TIMESTAMP NOT NULL,
|
---|
52 | ArrivalTime TIMESTAMP NOT NULL,
|
---|
53 | Price DECIMAL(10,2),
|
---|
54 | AvailableSeats INT NOT NULL,
|
---|
55 | CONSTRAINT fk_flight_dep FOREIGN KEY (DepartureAirportID) REFERENCES Airport(AirportID),
|
---|
56 | CONSTRAINT fk_flight_arr FOREIGN KEY (ArrivalAirportID) REFERENCES Airport(AirportID)
|
---|
57 | );
|
---|
58 |
|
---|
59 | -- 5. Bookings
|
---|
60 | CREATE TABLE Booking (
|
---|
61 | BookingID SERIAL PRIMARY KEY,
|
---|
62 | UserID INT NOT NULL,
|
---|
63 | BookingDate TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
64 | PaymentStatus VARCHAR(20) CHECK (PaymentStatus IN ('Pending','Completed','Cancelled')),
|
---|
65 | TotalCost DECIMAL(10,2),
|
---|
66 | CONSTRAINT fk_booking_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID)
|
---|
67 | );
|
---|
68 |
|
---|
69 | -- 6. BookingFlight (M:N)
|
---|
70 | CREATE TABLE BookingFlight (
|
---|
71 | BookingID INT NOT NULL,
|
---|
72 | FlightID INT NOT NULL,
|
---|
73 | SeatNumber INT,
|
---|
74 | PRIMARY KEY (BookingID, FlightID),
|
---|
75 | CONSTRAINT fk_bf_booking FOREIGN KEY (BookingID) REFERENCES Booking(BookingID),
|
---|
76 | CONSTRAINT fk_bf_flight FOREIGN KEY (FlightID) REFERENCES Flight(FlightID)
|
---|
77 | );
|
---|
78 |
|
---|
79 | -- 7. Reviews
|
---|
80 | CREATE TABLE Review (
|
---|
81 | ReviewID SERIAL PRIMARY KEY,
|
---|
82 | UserID INT NOT NULL,
|
---|
83 | BookingID INT NOT NULL,
|
---|
84 | TargetID INT NOT NULL,
|
---|
85 | TargetType VARCHAR(20) CHECK (TargetType IN ('Flight','Destination','Airport')),
|
---|
86 | ReviewComment TEXT,
|
---|
87 | Rating INT,
|
---|
88 | Date TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
89 | CONSTRAINT fk_review_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID),
|
---|
90 | CONSTRAINT fk_review_booking FOREIGN KEY (BookingID) REFERENCES Booking(BookingID)
|
---|
91 | );
|
---|
92 |
|
---|
93 | -- 8. Payments
|
---|
94 | CREATE TABLE Payment (
|
---|
95 | PaymentID SERIAL PRIMARY KEY,
|
---|
96 | BookingID INT NOT NULL,
|
---|
97 | UserID INT NOT NULL,
|
---|
98 | PaymentMethod VARCHAR(20) CHECK (PaymentMethod IN ('Credit Card','Debit Card','PayPal')),
|
---|
99 | Amount DECIMAL(10,2),
|
---|
100 | TransactionDate TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
101 | PaymentStatus VARCHAR(20) CHECK (PaymentStatus IN ('Success','Failed','Processing')),
|
---|
102 | CONSTRAINT fk_payment_booking FOREIGN KEY (BookingID) REFERENCES Booking(BookingID),
|
---|
103 | CONSTRAINT fk_payment_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID)
|
---|
104 | );
|
---|
105 |
|
---|
106 | -- 9. Notifications
|
---|
107 | CREATE TABLE Notification (
|
---|
108 | NotificationID SERIAL PRIMARY KEY,
|
---|
109 | UserID INT NOT NULL,
|
---|
110 | Message TEXT NOT NULL,
|
---|
111 | Type VARCHAR(50) CHECK (Type IN ('Booking Confirmation','Flight Delay','General Update')),
|
---|
112 | DateSent TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
113 | CONSTRAINT fk_notification_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID)
|
---|
114 | );
|
---|
115 |
|
---|
116 | -- 10. Wishlist
|
---|
117 | CREATE TABLE Wishlist (
|
---|
118 | WishlistID SERIAL PRIMARY KEY,
|
---|
119 | UserID INT NOT NULL,
|
---|
120 | TargetID INT NOT NULL,
|
---|
121 | TargetType VARCHAR(20) CHECK (TargetType IN ('Flight','Destination')),
|
---|
122 | DateAdded TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
123 | CONSTRAINT fk_wishlist_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID)
|
---|
124 | );
|
---|
125 |
|
---|
126 | -- 11. Administrators
|
---|
127 | CREATE TABLE Administrator (
|
---|
128 | AdminID SERIAL PRIMARY KEY,
|
---|
129 | Email VARCHAR(255) NOT NULL UNIQUE
|
---|
130 | );
|
---|
131 |
|
---|
132 | -- 12. Support Tickets
|
---|
133 | CREATE TABLE SupportTicket (
|
---|
134 | TicketID SERIAL PRIMARY KEY,
|
---|
135 | UserID INT NOT NULL,
|
---|
136 | Subject VARCHAR(255) NOT NULL,
|
---|
137 | Description TEXT NOT NULL,
|
---|
138 | Status VARCHAR(20) CHECK (Status IN ('Open','In Progress','Resolved')),
|
---|
139 | DateCreated TIMESTAMP NOT NULL DEFAULT NOW(),
|
---|
140 | DateResolved TIMESTAMP,
|
---|
141 | AssignedTo INT,
|
---|
142 | CONSTRAINT fk_ticket_user FOREIGN KEY (UserID) REFERENCES ApplicationUser(UserID),
|
---|
143 | CONSTRAINT fk_ticket_admin FOREIGN KEY (AssignedTo) REFERENCES Administrator(AdminID)
|
---|
144 | );
|
---|
145 |
|
---|
146 |
|
---|
147 | CREATE INDEX idx_booking_user ON Booking(UserID);
|
---|
148 | CREATE INDEX idx_flight_dep_time ON Flight(DepartureTime);
|
---|
149 | CREATE INDEX idx_payment_booking ON Payment(BookingID);
|
---|
150 | CREATE INDEX idx_review_user ON Review(UserID);
|
---|
151 |
|
---|
152 |
|
---|
153 | -- Prevent duplicate wishlist entries
|
---|
154 | CREATE OR REPLACE FUNCTION validate_wishlist_entry()
|
---|
155 | RETURNS TRIGGER AS $$
|
---|
156 | BEGIN
|
---|
157 | IF EXISTS (
|
---|
158 | SELECT 1 FROM Wishlist
|
---|
159 | WHERE UserID = NEW.UserID AND TargetID = NEW.TargetID
|
---|
160 | ) THEN
|
---|
161 | RAISE EXCEPTION 'Item already exists in wishlist!';
|
---|
162 | END IF;
|
---|
163 | RETURN NEW;
|
---|
164 | END;
|
---|
165 | $$ LANGUAGE plpgsql;
|
---|
166 |
|
---|
167 | CREATE TRIGGER trg_wishlist_validate
|
---|
168 | BEFORE INSERT ON Wishlist
|
---|
169 | FOR EACH ROW
|
---|
170 | EXECUTE FUNCTION validate_wishlist_entry();
|
---|
171 |
|
---|
172 | -- Validate new user email
|
---|
173 | CREATE OR REPLACE FUNCTION validate_new_user()
|
---|
174 | RETURNS TRIGGER AS $$
|
---|
175 | BEGIN
|
---|
176 | IF EXISTS (SELECT 1 FROM ApplicationUser WHERE Email = NEW.Email) THEN
|
---|
177 | RAISE EXCEPTION 'Email already registered!';
|
---|
178 | END IF;
|
---|
179 | RETURN NEW;
|
---|
180 | END;
|
---|
181 | $$ LANGUAGE plpgsql;
|
---|
182 |
|
---|
183 | CREATE TRIGGER trg_user_validate
|
---|
184 | BEFORE INSERT ON ApplicationUser
|
---|
185 | FOR EACH ROW
|
---|
186 | EXECUTE FUNCTION validate_new_user();
|
---|
187 |
|
---|
188 |
|
---|
189 | -- User Bookings with Flight Details
|
---|
190 | CREATE OR REPLACE VIEW v_user_bookings AS
|
---|
191 | SELECT
|
---|
192 | u.UserID,
|
---|
193 | u.Name || ' ' || u.Surname AS FullName,
|
---|
194 | b.BookingID,
|
---|
195 | b.BookingDate,
|
---|
196 | b.PaymentStatus,
|
---|
197 | b.TotalCost,
|
---|
198 | f.FlightID,
|
---|
199 | f.FlightNumber,
|
---|
200 | f.DepartureTime,
|
---|
201 | f.ArrivalTime,
|
---|
202 | dep.Name AS DepartureAirport,
|
---|
203 | arr.Name AS ArrivalAirport,
|
---|
204 | f.Price
|
---|
205 | FROM Booking b
|
---|
206 | JOIN ApplicationUser u ON b.UserID = u.UserID
|
---|
207 | JOIN BookingFlight bf ON b.BookingID = bf.BookingID
|
---|
208 | JOIN Flight f ON bf.FlightID = f.FlightID
|
---|
209 | JOIN Airport dep ON f.DepartureAirportID = dep.AirportID
|
---|
210 | JOIN Airport arr ON f.ArrivalAirportID = arr.AirportID;
|
---|
211 |
|
---|
212 | -- Flight Summary
|
---|
213 | CREATE OR REPLACE VIEW v_flight_summary AS
|
---|
214 | SELECT
|
---|
215 | f.FlightID,
|
---|
216 | f.FlightNumber,
|
---|
217 | dep.Name AS DepartureAirport,
|
---|
218 | arr.Name AS ArrivalAirport,
|
---|
219 | f.DepartureTime,
|
---|
220 | f.ArrivalTime,
|
---|
221 | f.Price,
|
---|
222 | f.AvailableSeats,
|
---|
223 | COUNT(bf.BookingID) AS TotalBookings
|
---|
224 | FROM Flight f
|
---|
225 | JOIN Airport dep ON f.DepartureAirportID = dep.AirportID
|
---|
226 | JOIN Airport arr ON f.ArrivalAirportID = arr.AirportID
|
---|
227 | LEFT JOIN BookingFlight bf ON f.FlightID = bf.FlightID
|
---|
228 | GROUP BY f.FlightID, f.FlightNumber, dep.Name, arr.Name, f.DepartureTime, f.ArrivalTime, f.Price, f.AvailableSeats;
|
---|
229 |
|
---|
230 | -- Reviews View
|
---|
231 | CREATE OR REPLACE VIEW v_reviews AS
|
---|
232 | SELECT
|
---|
233 | r.ReviewID,
|
---|
234 | u.Name || ' ' || u.Surname AS Reviewer,
|
---|
235 | r.TargetID,
|
---|
236 | r.TargetType,
|
---|
237 | r.ReviewComment,
|
---|
238 | r.Rating,
|
---|
239 | r.Date
|
---|
240 | FROM Review r
|
---|
241 | JOIN ApplicationUser u ON r.UserID = u.UserID;
|
---|
242 |
|
---|
243 | -- Payments Summary
|
---|
244 | CREATE OR REPLACE VIEW v_user_payments AS
|
---|
245 | SELECT
|
---|
246 | u.UserID,
|
---|
247 | u.Name || ' ' || u.Surname AS FullName,
|
---|
248 | COUNT(p.PaymentID) AS NumPayments,
|
---|
249 | SUM(p.Amount) AS TotalPaid,
|
---|
250 | AVG(p.Amount) AS AvgPayment
|
---|
251 | FROM Payment p
|
---|
252 | JOIN ApplicationUser u ON p.UserID = u.UserID
|
---|
253 | GROUP BY u.UserID, u.Name, u.Surname;
|
---|
254 |
|
---|
255 | -- Wishlist Summary
|
---|
256 | CREATE OR REPLACE VIEW v_user_wishlist AS
|
---|
257 | SELECT
|
---|
258 | u.UserID,
|
---|
259 | u.Name || ' ' || u.Surname AS FullName,
|
---|
260 | w.WishlistID,
|
---|
261 | w.TargetID,
|
---|
262 | w.TargetType,
|
---|
263 | w.DateAdded
|
---|
264 | FROM Wishlist w
|
---|
265 | JOIN ApplicationUser u ON w.UserID = u.UserID;
|
---|
266 |
|
---|
267 |
|
---|
268 | EXPLAIN ANALYZE
|
---|
269 | SELECT * FROM Flight
|
---|
270 | WHERE DepartureTime >= '2025-05-01' AND DepartureTime < '2025-06-01';
|
---|
271 |
|
---|
272 | EXPLAIN ANALYZE
|
---|
273 | SELECT * FROM Booking
|
---|
274 | WHERE BookingDate >= '2025-05-01' AND BookingDate < '2025-06-01';
|
---|
275 |
|
---|
276 | EXPLAIN ANALYZE
|
---|
277 | SELECT * FROM Payment
|
---|
278 | WHERE BookingID = 1;
|
---|