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.*;
public class CarrelloDAOImpl implements CarrelloDAO {
private DataSource ds;
/*@ 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) {
e.printStackTrace();
}
}
@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) {
e.printStackTrace();
}
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 = ?";
Connection connection = null;
try {
connection = ds.getConnection();
// Avvia una transazione
connection.setAutoCommit(false);
try (PreparedStatement psProdottoCarrello = connection.prepareStatement(queryProdottoCarrello)) {
psProdottoCarrello.setString(1, email);
psProdottoCarrello.executeUpdate();
}
try (PreparedStatement psCarrello = connection.prepareStatement(queryCarrello)) {
psCarrello.setString(1, email);
psCarrello.executeUpdate();
}
// Conferma la transazione
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
// In caso di errore, esegui il rollback
if (connection != null) {
connection.rollback();
}
} catch (SQLException rollbackEx) {
rollbackEx.printStackTrace();
}
} finally {
try {
// Ripristina l'auto-commit
if (connection != null) {
connection.setAutoCommit(true);
connection.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}