001package edu.pdx.cs.joy.jdbc; 002 003import java.sql.*; 004import java.util.ArrayList; 005import java.util.List; 006 007/** 008 * Data Access Object implementation for managing AcademicTerm entities in the database. 009 * Demonstrates JDBC operations with date fields: CREATE, READ, UPDATE, DELETE. 010 */ 011public class AcademicTermDAOImpl implements AcademicTermDAO { 012 013 private final Connection connection; 014 015 /** 016 * Creates a new AcademicTermDAOImpl with the specified database connection. 017 * 018 * @param connection the database connection to use 019 */ 020 public AcademicTermDAOImpl(Connection connection) { 021 this.connection = connection; 022 } 023 024 /** 025 * Drops the academic_terms table from the database if it exists. 026 * 027 * @param connection the database connection to use 028 * @throws SQLException if a database error occurs 029 */ 030 public static void dropTable(Connection connection) throws SQLException { 031 try (Statement statement = connection.createStatement()) { 032 statement.execute("DROP TABLE IF EXISTS academic_terms"); 033 } 034 } 035 036 /** 037 * Creates the academic_terms table in the database if it does not already exist. 038 * 039 * @param connection the database connection to use 040 * @throws SQLException if a database error occurs 041 */ 042 public static void createTable(Connection connection) throws SQLException { 043 try (Statement statement = connection.createStatement()) { 044 statement.execute( 045 "CREATE TABLE IF NOT EXISTS academic_terms (" + 046 " id IDENTITY PRIMARY KEY," + 047 " name VARCHAR(255) NOT NULL," + 048 " start_date DATE NOT NULL," + 049 " end_date DATE NOT NULL" + 050 ")" 051 ); 052 } 053 } 054 055 /** 056 * Saves an academic term to the database. 057 * The term's ID will be automatically generated by the database and set on the object. 058 * 059 * @param term the academic term to save 060 * @throws SQLException if a database error occurs 061 */ 062 @Override 063 public void save(AcademicTerm term) throws SQLException { 064 String sql = "INSERT INTO academic_terms (name, start_date, end_date) VALUES (?, ?, ?)"; 065 066 try (PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { 067 statement.setString(1, term.getName()); 068 statement.setDate(2, Date.valueOf(term.getStartDate())); 069 statement.setDate(3, Date.valueOf(term.getEndDate())); 070 statement.executeUpdate(); 071 072 // Retrieve the auto-generated ID and set it on the term object 073 try (ResultSet generatedKeys = statement.getGeneratedKeys()) { 074 if (generatedKeys.next()) { 075 int generatedId = generatedKeys.getInt(1); 076 term.setId(generatedId); 077 } else { 078 throw new SQLException("Creating academic term failed, no ID obtained."); 079 } 080 } 081 } 082 } 083 084 /** 085 * Finds an academic term by its ID. 086 * 087 * @param id the ID to search for 088 * @return the academic term with the given ID, or null if not found 089 * @throws SQLException if a database error occurs 090 */ 091 @Override 092 public AcademicTerm findById(int id) throws SQLException { 093 String sql = "SELECT id, name, start_date, end_date FROM academic_terms WHERE id = ?"; 094 095 try (PreparedStatement statement = connection.prepareStatement(sql)) { 096 statement.setInt(1, id); 097 098 try (ResultSet resultSet = statement.executeQuery()) { 099 if (resultSet.next()) { 100 return extractAcademicTermFromResultSet(resultSet); 101 } 102 } 103 } 104 105 return null; 106 } 107 108 /** 109 * Finds an academic term by its name. 110 * 111 * @param name the name to search for 112 * @return the academic term with the given name, or null if not found 113 * @throws SQLException if a database error occurs 114 */ 115 @Override 116 public AcademicTerm findByName(String name) throws SQLException { 117 String sql = "SELECT id, name, start_date, end_date FROM academic_terms WHERE name = ?"; 118 119 try (PreparedStatement statement = connection.prepareStatement(sql)) { 120 statement.setString(1, name); 121 122 try (ResultSet resultSet = statement.executeQuery()) { 123 if (resultSet.next()) { 124 return extractAcademicTermFromResultSet(resultSet); 125 } 126 } 127 } 128 129 return null; 130 } 131 132 /** 133 * Finds all academic terms in the database. 134 * 135 * @return a list of all academic terms 136 * @throws SQLException if a database error occurs 137 */ 138 @Override 139 public List<AcademicTerm> findAll() throws SQLException { 140 List<AcademicTerm> terms = new ArrayList<>(); 141 String sql = "SELECT id, name, start_date, end_date FROM academic_terms ORDER BY start_date"; 142 143 try (Statement statement = connection.createStatement(); 144 ResultSet resultSet = statement.executeQuery(sql)) { 145 while (resultSet.next()) { 146 terms.add(extractAcademicTermFromResultSet(resultSet)); 147 } 148 } 149 150 return terms; 151 } 152 153 /** 154 * Updates an existing academic term in the database. 155 * Uses the term's ID to identify which record to update. 156 * 157 * @param term the academic term to update 158 * @throws SQLException if a database error occurs 159 */ 160 @Override 161 public void update(AcademicTerm term) throws SQLException { 162 String sql = "UPDATE academic_terms SET name = ?, start_date = ?, end_date = ? WHERE id = ?"; 163 164 try (PreparedStatement statement = connection.prepareStatement(sql)) { 165 statement.setString(1, term.getName()); 166 statement.setDate(2, Date.valueOf(term.getStartDate())); 167 statement.setDate(3, Date.valueOf(term.getEndDate())); 168 statement.setInt(4, term.getId()); 169 170 int rowsAffected = statement.executeUpdate(); 171 if (rowsAffected == 0) { 172 throw new SQLException("Update failed, no academic term found with ID: " + term.getId()); 173 } 174 } 175 } 176 177 /** 178 * Deletes an academic term from the database by ID. 179 * 180 * @param id the ID of the academic term to delete 181 * @throws SQLException if a database error occurs 182 */ 183 @Override 184 public void delete(int id) throws SQLException { 185 String sql = "DELETE FROM academic_terms WHERE id = ?"; 186 187 try (PreparedStatement statement = connection.prepareStatement(sql)) { 188 statement.setInt(1, id); 189 int rowsAffected = statement.executeUpdate(); 190 191 if (rowsAffected == 0) { 192 throw new SQLException("Delete failed, no academic term found with ID: " + id); 193 } 194 } 195 } 196 197 /** 198 * Extracts an AcademicTerm object from the current row of a ResultSet. 199 * 200 * @param resultSet the result set positioned at an academic term row 201 * @return an AcademicTerm object with data from the result set 202 * @throws SQLException if a database error occurs 203 */ 204 private AcademicTerm extractAcademicTermFromResultSet(ResultSet resultSet) throws SQLException { 205 int id = resultSet.getInt("id"); 206 String name = resultSet.getString("name"); 207 Date startDate = resultSet.getDate("start_date"); 208 Date endDate = resultSet.getDate("end_date"); 209 210 AcademicTerm term = new AcademicTerm(name, startDate.toLocalDate(), endDate.toLocalDate()); 211 term.setId(id); 212 return term; 213 } 214} 215 216