| 1 | package com.popx.persistenza; | |
| 2 | ||
| 3 | import com.popx.modello.OrdineBean; | |
| 4 | ||
| 5 | import javax.sql.DataSource; | |
| 6 | import java.sql.*; | |
| 7 | import java.util.ArrayList; | |
| 8 | import java.util.List; | |
| 9 | import java.util.logging.Level; | |
| 10 | import java.util.logging.Logger; | |
| 11 | ||
| 12 | public class OrdineDAOImpl implements OrdineDAO { | |
| 13 | ||
| 14 | private DataSource ds; | |
| 15 | private static final Logger LOGGER = Logger.getLogger(OrdineDAOImpl.class.getName()); | |
| 16 | ||
| 17 | /*@ public model boolean available; | |
| 18 | @ public invariant ds != null && available; | |
| 19 | @ represents available <- ds != null; | |
| 20 | @*/ | |
| 21 | ||
| 22 | public OrdineDAOImpl() { | |
| 23 | this.ds = DataSourceSingleton.getInstance(); | |
| 24 | } | |
| 25 | ||
| 26 | @Override | |
| 27 | /*@ public normal_behavior | |
| 28 | @ requires ordine != null | |
| 29 | @ && ordine.getSubtotal() >= 0 | |
| 30 | @ && ordine.getCustomerEmail() != null && !ordine.getCustomerEmail().isEmpty() | |
| 31 | @ && ordine.getStatus() != null && !ordine.getStatus().isEmpty() | |
| 32 | @ && ordine.getDataOrdine() != null; | |
| 33 | @ assignable \everything; | |
| 34 | @ ensures \result ==> ordine.getId() > 0; | |
| 35 | @*/ | |
| 36 | public boolean insertOrdine(OrdineBean ordine) { | |
| 37 | String query = "INSERT INTO Ordine (subtotal, customer_email, status, data_ordine) VALUES (?, ?, ?, ?)"; | |
| 38 | ||
| 39 | try (Connection con = ds.getConnection(); | |
| 40 | PreparedStatement ps = con.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS)) { | |
| 41 | ||
| 42 |
1
1. insertOrdine : removed call to java/sql/PreparedStatement::setFloat → KILLED |
ps.setFloat(1, ordine.getSubtotal()); |
| 43 |
1
1. insertOrdine : removed call to java/sql/PreparedStatement::setString → KILLED |
ps.setString(2, ordine.getCustomerEmail()); |
| 44 |
1
1. insertOrdine : removed call to java/sql/PreparedStatement::setString → KILLED |
ps.setString(3, ordine.getStatus()); |
| 45 |
1
1. insertOrdine : removed call to java/sql/PreparedStatement::setDate → KILLED |
ps.setDate(4, new java.sql.Date(ordine.getDataOrdine().getTime())); |
| 46 | ||
| 47 | int affectedRows = ps.executeUpdate(); | |
| 48 | ||
| 49 | // Recupera l'ID auto-generato | |
| 50 | ResultSet rs = ps.getGeneratedKeys(); | |
| 51 |
1
1. insertOrdine : negated conditional → KILLED |
if (rs.next()) { |
| 52 |
1
1. insertOrdine : removed call to com/popx/modello/OrdineBean::setId → KILLED |
ordine.setId(rs.getInt(1)); |
| 53 | } | |
| 54 | ||
| 55 | // Restituisce true se sono state modificate righe (quindi l'inserimento è riuscito) | |
| 56 |
2
1. insertOrdine : changed conditional boundary → SURVIVED 2. insertOrdine : negated conditional → KILLED |
return affectedRows > 0; |
| 57 | ||
| 58 | } catch (SQLException e) { | |
| 59 | LOGGER.log(Level.SEVERE, "SQL error in insertOrdine", e); | |
| 60 |
1
1. insertOrdine : replaced boolean return with true for com/popx/persistenza/OrdineDAOImpl::insertOrdine → NO_COVERAGE |
return false; // Restituisce false in caso di errore |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | ||
| 65 | @Override | |
| 66 | /*@ public normal_behavior | |
| 67 | @ requires id > 0; | |
| 68 | @ assignable \everything; | |
| 69 | @ ensures \result == null || \result.getId() == id; | |
| 70 | @*/ | |
| 71 | public OrdineBean getOrdineById(int id) { | |
| 72 | String query = "SELECT * FROM Ordine WHERE id = ?"; | |
| 73 | OrdineBean ordine = null; | |
| 74 | ||
| 75 | try (Connection con = ds.getConnection(); | |
| 76 | PreparedStatement ps = con.prepareStatement(query)) { | |
| 77 | ||
| 78 |
1
1. getOrdineById : removed call to java/sql/PreparedStatement::setInt → KILLED |
ps.setInt(1, id); |
| 79 | ResultSet rs = ps.executeQuery(); | |
| 80 | ||
| 81 |
1
1. getOrdineById : negated conditional → KILLED |
if (rs.next()) { |
| 82 | ordine = new OrdineBean(); | |
| 83 |
1
1. getOrdineById : removed call to com/popx/modello/OrdineBean::setId → KILLED |
ordine.setId(rs.getInt("id")); |
| 84 |
1
1. getOrdineById : removed call to com/popx/modello/OrdineBean::setSubtotal → KILLED |
ordine.setSubtotal(rs.getFloat("subtotal")); |
| 85 |
1
1. getOrdineById : removed call to com/popx/modello/OrdineBean::setCustomerEmail → KILLED |
ordine.setCustomerEmail(rs.getString("customer_email")); |
| 86 |
1
1. getOrdineById : removed call to com/popx/modello/OrdineBean::setStatus → KILLED |
ordine.setStatus(rs.getString("status")); |
| 87 |
1
1. getOrdineById : removed call to com/popx/modello/OrdineBean::setDataOrdine → KILLED |
ordine.setDataOrdine(rs.getDate("data_ordine")); |
| 88 | } | |
| 89 | ||
| 90 | } catch (SQLException e) { | |
| 91 | LOGGER.log(Level.SEVERE, "SQL error in getOrdineById", e); | |
| 92 | } | |
| 93 | ||
| 94 |
1
1. getOrdineById : replaced return value with null for com/popx/persistenza/OrdineDAOImpl::getOrdineById → KILLED |
return ordine; |
| 95 | } | |
| 96 | ||
| 97 | @Override | |
| 98 | /*@ public normal_behavior | |
| 99 | @ assignable \everything; | |
| 100 | @ ensures \result != null; | |
| 101 | @*/ | |
| 102 | public List<OrdineBean> getAllOrdini() { | |
| 103 | String query = "SELECT * FROM Ordine"; | |
| 104 | List<OrdineBean> ordini = new ArrayList<>(); | |
| 105 | ||
| 106 | try (Connection con = ds.getConnection(); | |
| 107 | PreparedStatement ps = con.prepareStatement(query); | |
| 108 | ResultSet rs = ps.executeQuery()) { | |
| 109 | ||
| 110 |
1
1. getAllOrdini : negated conditional → KILLED |
while (rs.next()) { |
| 111 | OrdineBean ordine = new OrdineBean(); | |
| 112 |
1
1. getAllOrdini : removed call to com/popx/modello/OrdineBean::setId → KILLED |
ordine.setId(rs.getInt("id")); |
| 113 |
1
1. getAllOrdini : removed call to com/popx/modello/OrdineBean::setSubtotal → KILLED |
ordine.setSubtotal(rs.getFloat("subtotal")); |
| 114 |
1
1. getAllOrdini : removed call to com/popx/modello/OrdineBean::setCustomerEmail → KILLED |
ordine.setCustomerEmail(rs.getString("customer_email")); |
| 115 |
1
1. getAllOrdini : removed call to com/popx/modello/OrdineBean::setStatus → SURVIVED |
ordine.setStatus(rs.getString("status")); |
| 116 |
1
1. getAllOrdini : removed call to com/popx/modello/OrdineBean::setDataOrdine → KILLED |
ordine.setDataOrdine(rs.getDate("data_ordine")); |
| 117 | ordini.add(ordine); | |
| 118 | } | |
| 119 | ||
| 120 | } catch (SQLException e) { | |
| 121 | LOGGER.log(Level.SEVERE, "SQL error in getAllOrdini", e); | |
| 122 | } | |
| 123 | ||
| 124 |
1
1. getAllOrdini : replaced return value with Collections.emptyList for com/popx/persistenza/OrdineDAOImpl::getAllOrdini → KILLED |
return ordini; |
| 125 | } | |
| 126 | ||
| 127 | @Override | |
| 128 | /*@ public normal_behavior | |
| 129 | @ requires clienteEmail != null && !clienteEmail.isEmpty(); | |
| 130 | @ assignable \everything; | |
| 131 | @ ensures \result != null | |
| 132 | @ && (\forall int i; 0 <= i && i < \result.size(); | |
| 133 | @ \result.get(i) != null | |
| 134 | @ && clienteEmail.equals(\result.get(i).getCustomerEmail())); | |
| 135 | @*/ | |
| 136 | public List<OrdineBean> getOrdiniByCliente(String clienteEmail) { | |
| 137 | String query = "SELECT * FROM Ordine WHERE customer_email = ?"; | |
| 138 | List<OrdineBean> ordini = new ArrayList<>(); | |
| 139 | ||
| 140 | try (Connection con = ds.getConnection(); | |
| 141 | PreparedStatement ps = con.prepareStatement(query)) { | |
| 142 | ||
| 143 |
1
1. getOrdiniByCliente : removed call to java/sql/PreparedStatement::setString → KILLED |
ps.setString(1, clienteEmail); |
| 144 | ResultSet rs = ps.executeQuery(); | |
| 145 | ||
| 146 |
1
1. getOrdiniByCliente : negated conditional → KILLED |
while (rs.next()) { |
| 147 | OrdineBean ordine = new OrdineBean(); | |
| 148 |
1
1. getOrdiniByCliente : removed call to com/popx/modello/OrdineBean::setId → SURVIVED |
ordine.setId(rs.getInt("id")); |
| 149 |
1
1. getOrdiniByCliente : removed call to com/popx/modello/OrdineBean::setSubtotal → SURVIVED |
ordine.setSubtotal(rs.getFloat("subtotal")); |
| 150 |
1
1. getOrdiniByCliente : removed call to com/popx/modello/OrdineBean::setCustomerEmail → KILLED |
ordine.setCustomerEmail(rs.getString("customer_email")); |
| 151 |
1
1. getOrdiniByCliente : removed call to com/popx/modello/OrdineBean::setStatus → SURVIVED |
ordine.setStatus(rs.getString("status")); |
| 152 |
1
1. getOrdiniByCliente : removed call to com/popx/modello/OrdineBean::setDataOrdine → SURVIVED |
ordine.setDataOrdine(rs.getDate("data_ordine")); |
| 153 | ordini.add(ordine); | |
| 154 | } | |
| 155 | ||
| 156 | } catch (SQLException e) { | |
| 157 | LOGGER.log(Level.SEVERE, "SQL error in getOrdiniByCliente", e); | |
| 158 | } | |
| 159 | ||
| 160 |
1
1. getOrdiniByCliente : replaced return value with Collections.emptyList for com/popx/persistenza/OrdineDAOImpl::getOrdiniByCliente → KILLED |
return ordini; |
| 161 | } | |
| 162 | ||
| 163 | @Override | |
| 164 | /*@ public normal_behavior | |
| 165 | @ requires email != null && !email.isEmpty(); | |
| 166 | @ assignable \everything; | |
| 167 | @ ensures \result >= 0; | |
| 168 | @*/ | |
| 169 | public int countOrdiniByCliente(String email) { | |
| 170 | int count = 0; | |
| 171 | try (Connection connection = ds.getConnection()) { | |
| 172 | String query = "SELECT COUNT(*) FROM Ordine WHERE customer_email = ?"; | |
| 173 | try (PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |
| 174 |
1
1. countOrdiniByCliente : removed call to java/sql/PreparedStatement::setString → NO_COVERAGE |
preparedStatement.setString(1, email); |
| 175 | ResultSet resultSet = preparedStatement.executeQuery(); | |
| 176 |
1
1. countOrdiniByCliente : negated conditional → NO_COVERAGE |
if (resultSet.next()) { |
| 177 | count = resultSet.getInt(1); | |
| 178 | } | |
| 179 | } | |
| 180 | } catch (SQLException e) { | |
| 181 | LOGGER.log(Level.SEVERE, "SQL error in countOrdiniByCliente", e); | |
| 182 | } | |
| 183 |
1
1. countOrdiniByCliente : replaced int return with 0 for com/popx/persistenza/OrdineDAOImpl::countOrdiniByCliente → NO_COVERAGE |
return count; |
| 184 | } | |
| 185 | ||
| 186 | @Override | |
| 187 | /*@ public normal_behavior | |
| 188 | @ requires email != null && !email.isEmpty() | |
| 189 | @ && currentPage >= 1 | |
| 190 | @ && itemsPerPage > 0; | |
| 191 | @ assignable \everything; | |
| 192 | @ ensures \result != null && \result.size() <= itemsPerPage; | |
| 193 | @*/ | |
| 194 | public List<OrdineBean> getOrdiniByClientePaginati(String email, int currentPage, int itemsPerPage) { | |
| 195 | List<OrdineBean> ordini = new ArrayList<>(); | |
| 196 | try (Connection connection = ds.getConnection()) { | |
| 197 |
2
1. getOrdiniByClientePaginati : Replaced integer subtraction with addition → NO_COVERAGE 2. getOrdiniByClientePaginati : Replaced integer multiplication with division → NO_COVERAGE |
int offset = (currentPage - 1) * itemsPerPage; |
| 198 | String query = "SELECT id, subtotal, status, data_ordine FROM Ordine WHERE customer_email = ? ORDER BY data_ordine DESC LIMIT ? OFFSET ?"; | |
| 199 | try (PreparedStatement preparedStatement = connection.prepareStatement(query)) { | |
| 200 |
1
1. getOrdiniByClientePaginati : removed call to java/sql/PreparedStatement::setString → NO_COVERAGE |
preparedStatement.setString(1, email); |
| 201 |
1
1. getOrdiniByClientePaginati : removed call to java/sql/PreparedStatement::setInt → NO_COVERAGE |
preparedStatement.setInt(2, itemsPerPage); |
| 202 |
1
1. getOrdiniByClientePaginati : removed call to java/sql/PreparedStatement::setInt → NO_COVERAGE |
preparedStatement.setInt(3, offset); |
| 203 | ResultSet resultSet = preparedStatement.executeQuery(); | |
| 204 |
1
1. getOrdiniByClientePaginati : negated conditional → NO_COVERAGE |
while (resultSet.next()) { |
| 205 | OrdineBean ordine = new OrdineBean(); | |
| 206 |
1
1. getOrdiniByClientePaginati : removed call to com/popx/modello/OrdineBean::setId → NO_COVERAGE |
ordine.setId(resultSet.getInt("id")); |
| 207 |
1
1. getOrdiniByClientePaginati : removed call to com/popx/modello/OrdineBean::setSubtotal → NO_COVERAGE |
ordine.setSubtotal(resultSet.getFloat("subtotal")); |
| 208 |
1
1. getOrdiniByClientePaginati : removed call to com/popx/modello/OrdineBean::setStatus → NO_COVERAGE |
ordine.setStatus(resultSet.getString("status")); |
| 209 |
1
1. getOrdiniByClientePaginati : removed call to com/popx/modello/OrdineBean::setDataOrdine → NO_COVERAGE |
ordine.setDataOrdine(resultSet.getDate("data_ordine")); |
| 210 | ordini.add(ordine); | |
| 211 | } | |
| 212 | } | |
| 213 | } catch (SQLException e) { | |
| 214 | LOGGER.log(Level.SEVERE, "SQL error in getOrdiniByClientePaginati", e); | |
| 215 | } | |
| 216 |
1
1. getOrdiniByClientePaginati : replaced return value with Collections.emptyList for com/popx/persistenza/OrdineDAOImpl::getOrdiniByClientePaginati → NO_COVERAGE |
return ordini; |
| 217 | } | |
| 218 | ||
| 219 | @Override | |
| 220 | /*@ public normal_behavior | |
| 221 | @ requires currentPage >= 1 && recordsPerPage > 0; | |
| 222 | @ assignable \everything; | |
| 223 | @ ensures \result != null && \result.size() <= recordsPerPage; | |
| 224 | @*/ | |
| 225 | public List<OrdineBean> getOrdiniPaginati(int currentPage, int recordsPerPage) { | |
| 226 | List<OrdineBean> ordini = new ArrayList<>(); | |
| 227 | String query = "SELECT * FROM Ordine LIMIT ? OFFSET ?"; | |
| 228 | ||
| 229 | try (Connection conn = ds.getConnection(); | |
| 230 | PreparedStatement pstmt = conn.prepareStatement(query)) { | |
| 231 | ||
| 232 |
1
1. getOrdiniPaginati : removed call to java/sql/PreparedStatement::setInt → NO_COVERAGE |
pstmt.setInt(1, recordsPerPage); |
| 233 |
3
1. getOrdiniPaginati : Replaced integer subtraction with addition → NO_COVERAGE 2. getOrdiniPaginati : removed call to java/sql/PreparedStatement::setInt → NO_COVERAGE 3. getOrdiniPaginati : Replaced integer multiplication with division → NO_COVERAGE |
pstmt.setInt(2, (currentPage - 1) * recordsPerPage); |
| 234 | ||
| 235 | try (ResultSet rs = pstmt.executeQuery()) { | |
| 236 |
1
1. getOrdiniPaginati : negated conditional → NO_COVERAGE |
while (rs.next()) { |
| 237 | OrdineBean ordine = new OrdineBean(); | |
| 238 |
1
1. getOrdiniPaginati : removed call to com/popx/modello/OrdineBean::setId → NO_COVERAGE |
ordine.setId(rs.getInt("id")); |
| 239 |
1
1. getOrdiniPaginati : removed call to com/popx/modello/OrdineBean::setSubtotal → NO_COVERAGE |
ordine.setSubtotal(rs.getFloat("subtotal")); |
| 240 |
1
1. getOrdiniPaginati : removed call to com/popx/modello/OrdineBean::setCustomerEmail → NO_COVERAGE |
ordine.setCustomerEmail(rs.getString("customer_email")); |
| 241 |
1
1. getOrdiniPaginati : removed call to com/popx/modello/OrdineBean::setStatus → NO_COVERAGE |
ordine.setStatus(rs.getString("status")); |
| 242 |
1
1. getOrdiniPaginati : removed call to com/popx/modello/OrdineBean::setDataOrdine → NO_COVERAGE |
ordine.setDataOrdine(rs.getDate("data_ordine")); |
| 243 | ordini.add(ordine); | |
| 244 | } | |
| 245 | } | |
| 246 | } catch (SQLException e) { | |
| 247 | LOGGER.log(Level.SEVERE, "SQL error in getOrdiniPaginati", e); | |
| 248 | } | |
| 249 | ||
| 250 |
1
1. getOrdiniPaginati : replaced return value with Collections.emptyList for com/popx/persistenza/OrdineDAOImpl::getOrdiniPaginati → NO_COVERAGE |
return ordini; |
| 251 | } | |
| 252 | ||
| 253 | @Override | |
| 254 | /*@ public normal_behavior | |
| 255 | @ assignable \everything; | |
| 256 | @ ensures \result >= 0; | |
| 257 | @*/ | |
| 258 | public int countTuttiOrdini() { | |
| 259 | int count = 0; | |
| 260 | String query = "SELECT COUNT(*) FROM Ordine"; | |
| 261 | ||
| 262 | try (Connection conn = ds.getConnection(); | |
| 263 | Statement stmt = conn.createStatement(); | |
| 264 | ResultSet rs = stmt.executeQuery(query)) { | |
| 265 | ||
| 266 |
1
1. countTuttiOrdini : negated conditional → NO_COVERAGE |
if (rs.next()) { |
| 267 | count = rs.getInt(1); | |
| 268 | } | |
| 269 | } catch (SQLException e) { | |
| 270 | LOGGER.log(Level.SEVERE, "SQL error in countTuttiOrdini", e); | |
| 271 | } | |
| 272 | ||
| 273 |
1
1. countTuttiOrdini : replaced int return with 0 for com/popx/persistenza/OrdineDAOImpl::countTuttiOrdini → NO_COVERAGE |
return count; |
| 274 | } | |
| 275 | ||
| 276 | @Override | |
| 277 | /*@ public normal_behavior | |
| 278 | @ requires ordineBean != null | |
| 279 | @ && ordineBean.getId() > 0 | |
| 280 | @ && ordineBean.getStatus() != null && !ordineBean.getStatus().isEmpty(); | |
| 281 | @ assignable \everything; | |
| 282 | @ ensures \result ==> true; | |
| 283 | @*/ | |
| 284 | public boolean updateStatus(OrdineBean ordineBean) { | |
| 285 | String sql = "UPDATE Ordine SET status = ? WHERE id = ?"; | |
| 286 | try (Connection conn = ds.getConnection(); | |
| 287 | PreparedStatement preparedStatement = conn.prepareStatement(sql)) { | |
| 288 | ||
| 289 | // Impostazione dei parametri della query | |
| 290 |
1
1. updateStatus : removed call to java/sql/PreparedStatement::setString → KILLED |
preparedStatement.setString(1, ordineBean.getStatus()); |
| 291 |
1
1. updateStatus : removed call to java/sql/PreparedStatement::setInt → KILLED |
preparedStatement.setInt(2, ordineBean.getId()); |
| 292 | ||
| 293 | // Esecuzione dell'aggiornamento | |
| 294 | int rowsUpdated = preparedStatement.executeUpdate(); | |
| 295 |
2
1. updateStatus : changed conditional boundary → SURVIVED 2. updateStatus : negated conditional → KILLED |
return rowsUpdated > 0; // Restituisce true se almeno una riga è stata aggiornata |
| 296 | } catch (SQLException e) { | |
| 297 | LOGGER.log(Level.SEVERE, "SQL error in updateStatus", e); | |
| 298 |
1
1. updateStatus : replaced boolean return with true for com/popx/persistenza/OrdineDAOImpl::updateStatus → NO_COVERAGE |
return false; // Gestisce l'errore restituendo false |
| 299 | } | |
| 300 | } | |
| 301 | ||
| 302 | ||
| 303 | ||
| 304 | } | |
Mutations | ||
| 42 |
1.1 |
|
| 43 |
1.1 |
|
| 44 |
1.1 |
|
| 45 |
1.1 |
|
| 51 |
1.1 |
|
| 52 |
1.1 |
|
| 56 |
1.1 2.2 |
|
| 60 |
1.1 |
|
| 78 |
1.1 |
|
| 81 |
1.1 |
|
| 83 |
1.1 |
|
| 84 |
1.1 |
|
| 85 |
1.1 |
|
| 86 |
1.1 |
|
| 87 |
1.1 |
|
| 94 |
1.1 |
|
| 110 |
1.1 |
|
| 112 |
1.1 |
|
| 113 |
1.1 |
|
| 114 |
1.1 |
|
| 115 |
1.1 |
|
| 116 |
1.1 |
|
| 124 |
1.1 |
|
| 143 |
1.1 |
|
| 146 |
1.1 |
|
| 148 |
1.1 |
|
| 149 |
1.1 |
|
| 150 |
1.1 |
|
| 151 |
1.1 |
|
| 152 |
1.1 |
|
| 160 |
1.1 |
|
| 174 |
1.1 |
|
| 176 |
1.1 |
|
| 183 |
1.1 |
|
| 197 |
1.1 2.2 |
|
| 200 |
1.1 |
|
| 201 |
1.1 |
|
| 202 |
1.1 |
|
| 204 |
1.1 |
|
| 206 |
1.1 |
|
| 207 |
1.1 |
|
| 208 |
1.1 |
|
| 209 |
1.1 |
|
| 216 |
1.1 |
|
| 232 |
1.1 |
|
| 233 |
1.1 2.2 3.3 |
|
| 236 |
1.1 |
|
| 238 |
1.1 |
|
| 239 |
1.1 |
|
| 240 |
1.1 |
|
| 241 |
1.1 |
|
| 242 |
1.1 |
|
| 250 |
1.1 |
|
| 266 |
1.1 |
|
| 273 |
1.1 |
|
| 290 |
1.1 |
|
| 291 |
1.1 |
|
| 295 |
1.1 2.2 |
|
| 298 |
1.1 |