268 lines
9.6 KiB
Java
Executable file
268 lines
9.6 KiB
Java
Executable file
package datamodel;
|
|
|
|
import java.sql.*;
|
|
import java.util.ArrayList;
|
|
/**
|
|
* Database is a class that specifies the interface to the
|
|
* movie database. Uses JDBC and the MySQL Connector/J driver.
|
|
*/
|
|
public class Database {
|
|
/**
|
|
* The database connection.
|
|
*/
|
|
private Connection conn;
|
|
|
|
/**
|
|
* Create the database interface object. Connection to the database
|
|
* is performed later.
|
|
*/
|
|
public Database() {
|
|
conn = null;
|
|
}
|
|
|
|
/**
|
|
* Open a connection to the database, using the specified user name
|
|
* and password.
|
|
*
|
|
* @param userName The user name.
|
|
* @param password The user's password.
|
|
* @return true if the connection succeeded, false if the supplied
|
|
* user name and password were not recognized. Returns false also
|
|
* if the JDBC driver isn't found.
|
|
*/
|
|
public boolean openConnection(String userName, String password) {
|
|
try {
|
|
// Connection strings for included DBMS clients:
|
|
// [MySQL] jdbc:mysql://[host]/[database]
|
|
// [PostgreSQL] jdbc:postgresql://[host]/[database]
|
|
// [SQLite] jdbc:sqlite://[filepath]
|
|
|
|
// Use "jdbc:mysql://puccini.cs.lth.se/" + userName if you using our shared server
|
|
// If outside, this statement will hang until timeout.
|
|
conn = DriverManager.getConnection
|
|
("jdbc:sqlite:movieBookings.db3", userName, password);
|
|
}
|
|
catch (SQLException e) {
|
|
System.err.println(e);
|
|
e.printStackTrace();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Reads a file from the resources folder and returns the content as a string
|
|
private String readResourceFile(String fileName) {
|
|
String content = "";
|
|
try {
|
|
content = new String(getClass().getResourceAsStream(fileName).readAllBytes());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return content;
|
|
}
|
|
|
|
public void runMigration() {
|
|
// This path needs to start with a /
|
|
String migration = readResourceFile("/migration.sql");
|
|
try {
|
|
Statement stmt = conn.createStatement();
|
|
stmt.executeUpdate(migration);
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close the connection to the database.
|
|
*/
|
|
public void closeConnection() {
|
|
try {
|
|
if (conn != null)
|
|
conn.close();
|
|
}
|
|
catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
conn = null;
|
|
|
|
System.err.println("Database connection closed.");
|
|
}
|
|
|
|
/**
|
|
* Check if the connection to the database has been established
|
|
*
|
|
* @return true if the connection has been established
|
|
*/
|
|
public boolean isConnected() {
|
|
return conn != null;
|
|
}
|
|
|
|
// Gets the Show object with the given title and date
|
|
public Show getShowData(String movie, String date) {
|
|
if (!isConnected()) {
|
|
System.err.println("getShowData: no connection to database");
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
// Using prepared statements here to avoid injection, but this is never done anywhere else in this file
|
|
String query = "SELECT m.name AS movie_title, s.show_date, t.name AS theater_name, t.total_seats - COUNT(r.reservation_id) AS free_seats " +
|
|
"FROM Showings s " +
|
|
"JOIN Theaters t ON s.theater_id = t.theater_id " +
|
|
"JOIN Movies m ON s.movie_id = m.movie_id " +
|
|
"LEFT JOIN Reservations r ON s.showing_id = r.showing_id " +
|
|
"WHERE m.name = ? AND s.show_date = ? " +
|
|
"GROUP BY s.show_date, t.theater_id";
|
|
PreparedStatement pstmt = conn.prepareStatement(query);
|
|
pstmt.setString(1, movie);
|
|
pstmt.setString(2, date);
|
|
ResultSet rs = pstmt.executeQuery();
|
|
if (rs.next()) {
|
|
String title = rs.getString("movie_title");
|
|
String showDate = rs.getString("show_date");
|
|
String venue = rs.getString("theater_name");
|
|
int freeSeats = rs.getInt("free_seats");
|
|
|
|
return new Show(title, showDate, venue, freeSeats);
|
|
}
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
public ArrayList<Show> getAllShows() {
|
|
ArrayList<Show> shows = new ArrayList<Show>();
|
|
|
|
if(!isConnected()) {
|
|
System.err.println("getAllShows: no connection to database");
|
|
return shows;
|
|
}
|
|
|
|
try {
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet rs = stmt.executeQuery("SELECT *, Theaters.name AS theater_name FROM Showings JOIN Movies ON Showings.movie_id = Movies.movie_id JOIN Theaters ON Showings.theater_id = Theaters.theater_id");
|
|
while (rs.next()) {
|
|
String mTitle = rs.getString("name");
|
|
String mDate = rs.getString("show_date");
|
|
Integer mFreeSeats = rs.getInt("total_seats");
|
|
String mVenue = rs.getString("theater_name");
|
|
shows.add(new Show(mTitle, mDate, mVenue, mFreeSeats));
|
|
}
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return shows;
|
|
}
|
|
|
|
public ArrayList<String> getDatesForMovie(String mTitle) {
|
|
ArrayList<String> dates = new ArrayList<String>();
|
|
|
|
if(!isConnected()) {
|
|
System.err.println("getDatesForMovie: no connection to database");
|
|
return dates;
|
|
}
|
|
|
|
try {
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet rs = stmt.executeQuery("SELECT show_date FROM Showings JOIN Movies ON Showings.movie_id = Movies.movie_id WHERE name = '" + mTitle + "'");
|
|
while (rs.next()) {
|
|
dates.add(rs.getString("show_date"));
|
|
}
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return dates;
|
|
}
|
|
|
|
public boolean login(String username) {
|
|
if(!isConnected()) {
|
|
System.err.println("login: no connection to database");
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE username = '" + username + "'");
|
|
if (rs.next()) {
|
|
return true;
|
|
}
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public Reservation addReservation(String username, String movie, String date) {
|
|
if(!isConnected()) {
|
|
System.err.println("addReservation: no connection to database");
|
|
return null;
|
|
}
|
|
|
|
System.out.println("Adding reservation for " + username + " for " + movie + " on " + date);
|
|
|
|
try(Statement stmt = conn.createStatement()) {
|
|
conn.setAutoCommit(false);
|
|
Show s = getShowData(movie, date);
|
|
|
|
if (s.getSeats() <= 0) {
|
|
System.err.println("addReservation: no free seats for " + movie + " on " + date);
|
|
return null;
|
|
}
|
|
|
|
ResultSet rs = stmt.executeQuery("SELECT * FROM Users WHERE username = '" + username + "'");
|
|
if (rs.next()) {
|
|
int user_id = rs.getInt("id");
|
|
rs = stmt.executeQuery("SELECT * FROM Showings JOIN Movies ON Showings.movie_id = Movies.movie_id WHERE name = '" + movie + "' AND show_date = '" + date + "'");
|
|
if (rs.next()) {
|
|
System.out.println("Adding reservation");
|
|
int showing_id = rs.getInt("showing_id");
|
|
String theater = rs.getString("theater_id");
|
|
stmt.executeUpdate("INSERT INTO Reservations (user_id, showing_id) VALUES (" + user_id + ", " + showing_id + ")");
|
|
System.out.println("Reservation added");
|
|
conn.commit();
|
|
conn.setAutoCommit(true);
|
|
int bookingId = stmt.getGeneratedKeys().getInt(1);
|
|
return new Reservation(bookingId, movie, date, theater);
|
|
}
|
|
rs.close();
|
|
}
|
|
else {
|
|
System.err.println(String.format("addReservation: user %s not found", username));
|
|
}
|
|
conn.commit();
|
|
} catch (SQLException e) {
|
|
try {
|
|
conn.rollback();
|
|
} catch (SQLException e2) {
|
|
e2.printStackTrace();
|
|
}
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public ArrayList<Reservation> getReservations(String username) {
|
|
ArrayList<Reservation> reservations = new ArrayList<Reservation>();
|
|
|
|
if(!isConnected()) {
|
|
System.err.println("getReservations: no connection to database");
|
|
return reservations;
|
|
}
|
|
|
|
try {
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet rs = stmt.executeQuery("SELECT *, Theaters.name AS theater_name FROM Reservations JOIN Showings ON Reservations.showing_id = Showings.showing_id JOIN Movies ON Showings.movie_id = Movies.movie_id JOIN Theaters ON Showings.theater_id = Theaters.theater_id JOIN users ON Reservations.user_id = Users.id WHERE username = '" + username + "'");
|
|
while (rs.next()) {
|
|
reservations.add(new Reservation(rs.getInt("reservation_id"), rs.getString("name"), rs.getString("show_date"), rs.getString("theater_name")));
|
|
}
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return reservations;
|
|
}
|
|
}
|