package hirondelle.predict.main.prediction;
import static hirondelle.predict.main.prediction.PredictionAction.ADD_PREDICTION;
import static hirondelle.predict.main.prediction.PredictionAction.CHANGE_PREDICTION;
import static hirondelle.predict.main.prediction.PredictionAction.DELETE_PREDICTION;
import static hirondelle.predict.main.prediction.PredictionAction.FETCH_OWNER;
import static hirondelle.predict.main.prediction.PredictionAction.FETCH_PREDICTION;
import static hirondelle.predict.main.prediction.PredictionAction.LIST_PREDICTIONS;
import hirondelle.web4j.database.DAOException;
import hirondelle.web4j.database.Db;
import hirondelle.web4j.database.DbTx;
import hirondelle.web4j.database.DuplicateException;
import hirondelle.web4j.database.Tx;
import hirondelle.web4j.database.TxTemplate;
import hirondelle.web4j.model.Id;
import hirondelle.web4j.model.DateTime;
import hirondelle.web4j.util.Util;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Logger;
public final class PredictionDAO {
public List<Prediction> list(Id aPredictionListId) throws DAOException {
return Db.list(Prediction.class, LIST_PREDICTIONS, aPredictionListId);
}
Prediction fetch(Id aPredictionId, Id aPredictionListId) throws DAOException {
return Db.fetch(Prediction.class, FETCH_PREDICTION, aPredictionId, aPredictionListId);
}
Id add(Prediction aPrediction, Id aPredictionListId, DateTime aNow) throws DAOException, DuplicateException {
Object[] params = {
aPredictionListId, aPrediction.getText(), aNow,
aPrediction.getRemark(), getOutcomeId(aPrediction), getOutcomeDateForInsert(aPrediction, aNow)
};
return Db.add(ADD_PREDICTION, params);
}
boolean change(Prediction aPrediction, Id aPredictionListId, DateTime aToday) throws DAOException, DuplicateException {
Tx changeTx = new Change(aPrediction, aPredictionListId, aToday);
return Util.isSuccess(changeTx.executeTx());
}
void delete(Id aPredictionId, Id aPredictionListId) throws DAOException {
Db.delete(DELETE_PREDICTION, aPredictionId, aPredictionListId);
}
Id fetchLoginNameFor(Id aParentId) throws DAOException {
return Db.fetchValue(Id.class, FETCH_OWNER, aParentId);
}
private static final Logger fLogger = Util.getLogger(PredictionDAO.class);
private DateTime getOutcomeDateForInsert(Prediction aPrediction, DateTime aNow){
return aPrediction.getOutcome() != null ? aNow.truncate(DateTime.Unit.DAY) : null;
}
private DateTime getOutcomeDate(Prediction aNew, Prediction aOld, DateTime aToday){
DateTime result = aOld.getOutcomeDate(); if (hasChangedOutcome(aOld, aNew)) {
if( aNew.getOutcome() != null ){
result = aToday;
}
else {
result = null;
}
}
return result;
}
private boolean hasChangedOutcome(Prediction aOld, Prediction aNew){
boolean result = false;
if ( aOld.getOutcome() == null && aNew.getOutcome() != null ) {
result = true;
}
else if (aOld.getOutcome() != null && aNew.getOutcome() == null) {
result = true;
}
else if (aOld.getOutcome() != null && aNew.getOutcome() != null){
if (! aNew.getOutcome().getId().equals(aOld.getOutcome().getId())){
result = true;
}
}
fLogger.fine("Has changed outcome: " + result);
return result;
}
private Id getOutcomeId(Prediction aPrediction){
return aPrediction.getOutcome() != null ? aPrediction.getOutcome().getId() : null;
}
private final class Change extends TxTemplate {
Change(Prediction aNewPrediction, Id aPredictionListId, DateTime aToday){
fNew = aNewPrediction;
fListId = aPredictionListId;
fToday = aToday;
}
@Override public int executeMultipleSqls(Connection aConnection) throws SQLException, DAOException {
fLogger.fine("Executing transaction for update operation.");
Prediction old = DbTx.fetch(aConnection, Prediction.class, FETCH_PREDICTION, fNew.getId(), fListId);
Object[] params = {
fNew.getText(), fNew.getRemark(), getOutcomeId(fNew), getOutcomeDate(fNew, old, fToday),
fNew.getId(), fListId
} ;
return DbTx.edit(aConnection, CHANGE_PREDICTION, params);
}
private Prediction fNew;
private Id fListId;
private DateTime fToday;
}
}