CarrelloDAOImpl.java
package com.popx.persistenza;
import com.popx.modello.CarrelloBean;
import com.popx.modello.ProdottoCarrelloBean;
import javax.sql.DataSource;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CarrelloDAOImpl implements CarrelloDAO {
private DataSource ds;
private static final Logger LOGGER = Logger.getLogger(CarrelloDAOImpl.class.getName());
/*@ public model boolean available;
@ public invariant ds != null && available;
@ represents available <- ds != null;
@*/
public CarrelloDAOImpl() {
this.ds = DataSourceSingleton.getInstance();
}
/*@ public normal_behavior
@ requires carrello != null
@ && carrello.getClienteEmail() != null && !carrello.getClienteEmail().isEmpty()
@ && carrello.getProdottiCarrello() != null
@ && (\forall int i; 0 <= i && i < carrello.getProdottiCarrello().size();
@ carrello.getProdottiCarrello().get(i) != null
@ && carrello.getProdottiCarrello().get(i).getProdottoId() != null
@ && !carrello.getProdottiCarrello().get(i).getProdottoId().isEmpty()
@ && carrello.getProdottiCarrello().get(i).getQuantity() >= 0
@ && carrello.getProdottiCarrello().get(i).getUnitaryCost() >= 0);
@ assignable \everything;
@ ensures available;
@*/
@Override
public void salvaCarrello(CarrelloBean carrello) {
String upsertCart =
"INSERT INTO Carrello (cliente_email) VALUES (?) " +
"ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)";
String insertProdottoCarrello =
"INSERT INTO ProdottoCarrello (carrello_id, prodotto_id, quantity, unitary_cost) " +
"VALUES (?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE quantity = VALUES(quantity), unitary_cost = VALUES(unitary_cost)";
try (Connection connection = ds.getConnection()) {
connection.setAutoCommit(false);
int carrelloId;
// 1) Inserisci (o recupera) il carrello e ottieni l'id
try (PreparedStatement psCart = connection.prepareStatement(upsertCart, Statement.RETURN_GENERATED_KEYS)) {
psCart.setString(1, carrello.getClienteEmail());
psCart.executeUpdate();
try (ResultSet keys = psCart.getGeneratedKeys()) {
if (keys.next()) {
carrelloId = keys.getInt(1);
} else {
throw new SQLException("Impossibile ottenere l'ID del carrello.");
}
}
}
// 2) Inserisci/aggiorna prodotti del carrello (batch)
try (PreparedStatement psProd = connection.prepareStatement(insertProdottoCarrello)) {
for (ProdottoCarrelloBean prodotto : carrello.getProdottiCarrello()) {
psProd.setInt(1, carrelloId);
psProd.setString(2, prodotto.getProdottoId());
psProd.setInt(3, prodotto.getQuantity());
psProd.setFloat(4, prodotto.getUnitaryCost());
psProd.addBatch();
}
psProd.executeBatch();
}
connection.commit();
} catch (SQLException e) {
LOGGER.log(Level.SEVERE, "SQL error in salvaCarrello", e);
}
}
@Override
/*@ public normal_behavior
@ requires email != null && !email.isEmpty();
@ assignable \everything;
@ ensures \result != null
@ && \result.getClienteEmail().equals(email)
@ && \result.getProdottiCarrello() != null
@ && (\forall int i; 0 <= i && i < \result.getProdottiCarrello().size();
@ \result.getProdottiCarrello().get(i) != null
@ && \result.getProdottiCarrello().get(i).getProdottoId() != null
@ && !\result.getProdottiCarrello().get(i).getProdottoId().isEmpty()
@ && \result.getProdottiCarrello().get(i).getQuantity() >= 0
@ && \result.getProdottiCarrello().get(i).getUnitaryCost() >= 0);
@*/
public CarrelloBean ottieniCarrelloPerEmail(String email) {
String queryCarrello = "SELECT * FROM Carrello WHERE cliente_email = ?";
String queryProdotti = "SELECT * FROM ProdottoCarrello WHERE carrello_id = ?";
CarrelloBean carrello = null;
List<ProdottoCarrelloBean> prodottiCarrello = new ArrayList<>();
try (Connection connection = ds.getConnection()) {
// Recupera il carrello
try (PreparedStatement psCarrello = connection.prepareStatement(queryCarrello)) {
psCarrello.setString(1, email);
ResultSet rsCarrello = psCarrello.executeQuery();
if (rsCarrello.next()) {
// Recupera l'ID del carrello
int carrelloId = rsCarrello.getInt("id");
// Recupera i prodotti associati al carrello
try (PreparedStatement psProdotti = connection.prepareStatement(queryProdotti)) {
psProdotti.setInt(1, carrelloId);
ResultSet rsProdotti = psProdotti.executeQuery();
while (rsProdotti.next()) {
ProdottoCarrelloBean prodotto = new ProdottoCarrelloBean(
email,
rsProdotti.getString("prodotto_id"),
rsProdotti.getInt("quantity"),
rsProdotti.getFloat("unitary_cost")
);
prodottiCarrello.add(prodotto);
}
}
// Crea il carrello
carrello = new CarrelloBean(email, prodottiCarrello);
}
}
} catch (SQLException e) {
LOGGER.log(Level.SEVERE, "SQL error in ottieniCarrelloPerEmail", e);
}
return carrello != null ? carrello : new CarrelloBean(email, prodottiCarrello);
}
@Override
/*@ public normal_behavior
@ requires email != null && !email.isEmpty();
@ assignable \everything;
@ ensures available;
@*/
public void clearCartByUserEmail(String email) {
String queryProdottoCarrello =
"DELETE FROM ProdottoCarrello WHERE carrello_id = (SELECT id FROM Carrello WHERE cliente_email = ?)";
String queryCarrello =
"DELETE FROM Carrello WHERE cliente_email = ?";
try (Connection connection = ds.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement psProdottoCarrello = connection.prepareStatement(queryProdottoCarrello);
PreparedStatement psCarrello = connection.prepareStatement(queryCarrello)) {
psProdottoCarrello.setString(1, email);
psProdottoCarrello.executeUpdate();
psCarrello.setString(1, email);
psCarrello.executeUpdate();
connection.commit();
} catch (SQLException ex) {
// se qualcosa va male durante i DELETE, rollback della transazione
try {
connection.rollback();
} catch (SQLException rollbackEx) {
LOGGER.log(Level.SEVERE, "Error during rollback in clearCartByUserEmail", rollbackEx);
}
throw ex; // rilancia per finire nel catch esterno
} finally {
// best-effort: ripristina autocommit prima della chiusura
try {
connection.setAutoCommit(true);
} catch (SQLException ignore) {
// ignore / log se preferisci
}
}
} catch (SQLException e) {
LOGGER.log(Level.SEVERE, "SQL error in clearCartByUserEmail", e);
}
}
}