/**
*
*/
package com.soundlooper.model.mark;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import com.soundlooper.exception.SoundLooperDatabaseException;
import com.soundlooper.exception.SoundLooperException;
import com.soundlooper.exception.SoundLooperObjectAlreadyExistsException;
import com.soundlooper.exception.SoundLooperRuntimeException;
import com.soundlooper.model.SoundLooperObject;
import com.soundlooper.model.database.ConnectionFactory;
import com.soundlooper.model.database.SoundLooperDAO;
import com.soundlooper.model.song.Song;
/**
* ------------------------------------------------------- Sound Looper is an
* audio player that allow user to loop between two points Copyright (C) 2014
* Alexandre NEDJARI
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* The class that access database for songs access
*
* @author Alexandre NEDJARI
* @since 5 sept. 2012 -------------------------------------------------------
*/
public class MarkDAO extends SoundLooperDAO<Mark> {
/**
* The instance
*/
private static MarkDAO instance;
/**
* Private constructor
*/
private MarkDAO() {
// To avoid construction
}
/**
* Get the instance
*
* @return the instance
*/
public static MarkDAO getInstance() {
if (MarkDAO.instance == null) {
MarkDAO.instance = new MarkDAO();
}
return MarkDAO.instance;
}
public Mark createNew(String name, int beginTime, int endTime, Song song, boolean editable)
throws SoundLooperObjectAlreadyExistsException {
return new Mark(name, beginTime, endTime, song, editable);
}
@Override
protected void insert(Mark mark) {
try {
// Check that there is no mark with this name
PreparedStatement statementCheckName = ConnectionFactory
.getNewPreparedStatement("SELECT id FROM mark WHERE name = ? and id_song=?");
statementCheckName.setString(1, mark.getName());
statementCheckName.setLong(2, mark.getSong().getId());
ResultSet checkQuery = statementCheckName.executeQuery();
if (checkQuery.next()) {
// there is already a mark for this name and this song
throw new SoundLooperDatabaseException(
"Mark with this name for this song already exists in database : " + mark.getDescription(),
SoundLooperDatabaseException.ERROR_CODE_MARK_NAME_ALREADY_EXISTS_FOR_THIS_SONG);
}
// cr�e un nouveau marqueur dans la base de donn�es, et rempli le
// champ ID
PreparedStatement updateStatement = ConnectionFactory
.getNewPreparedStatement("INSERT INTO mark (id_song, begintime, endtime, name) VALUES(?,?,?,?)");
updateStatement.setLong(1, mark.getSong().getId());
updateStatement.setInt(2, mark.getBeginMillisecond());
updateStatement.setInt(3, mark.getEndMillisecond());
updateStatement.setString(4, mark.getName());
updateStatement.executeUpdate();
ResultSet generatedKeys = updateStatement.getGeneratedKeys();
if (generatedKeys.next()) {
mark.setId(generatedKeys.getLong(1));
} else {
throw new SoundLooperDatabaseException("No ID generated when persisting mark : "
+ mark.getDescription(), SoundLooperDatabaseException.ERROR_CODE_NO_ID_GENERATED_FOR_NEW_MARK);
}
ConnectionFactory.commit();
} catch (SQLException | SoundLooperDatabaseException e) {
this.rollbackCurrentTransaction();
throw new SoundLooperRuntimeException("Error when creating new mark", e);
}
}
@Override
protected void update(Mark mark) {
try {
// check that the mark with this ID exists
ResultSet checkQueryID = ConnectionFactory.getNewStatement().executeQuery(
"SELECT id FROM mark WHERE id = '" + mark.getId() + "'");
if (!checkQueryID.next()) {
// there is no mark with this ID
throw new SoundLooperDatabaseException("Mark with this ID is not persisted : " + mark.getDescription(),
SoundLooperDatabaseException.ERROR_CODE_MARK_ID_DOES_NOT_EXISTS_IN_DATABASE);
}
// check that the path of the updated mark is not already used
PreparedStatement checkNameStatement = ConnectionFactory
.getNewPreparedStatement("SELECT id FROM mark WHERE id != ? AND name=? and id_song= ?");
checkNameStatement.setLong(1, mark.getId());
checkNameStatement.setString(2, mark.getName());
checkNameStatement.setLong(3, mark.getSong().getId());
ResultSet checkQueryPath = checkNameStatement.executeQuery();
if (checkQueryPath.next()) {
// There is a mark that have already this name
throw new SoundLooperDatabaseException("Mark with this name already exists for this song : "
+ mark.getDescription(),
SoundLooperDatabaseException.ERROR_CODE_MARK_NAME_ALREADY_EXISTS_FOR_THIS_SONG);
}
// modifie les attributs d'un marqueur en fonction de son ID
PreparedStatement updateStatement = ConnectionFactory
.getNewPreparedStatement("UPDATE mark SET name=?, begintime=?, endtime=?, id_song=? WHERE id =?");
updateStatement.setString(1, mark.getName());
updateStatement.setInt(2, mark.getBeginMillisecond());
updateStatement.setInt(3, mark.getEndMillisecond());
updateStatement.setLong(4, mark.getSong().getId());
updateStatement.setLong(5, mark.getId());
updateStatement.executeUpdate();
if (updateStatement.getUpdateCount() != 1) {
throw new SoundLooperDatabaseException("Update mark query must update 1 row and it update "
+ updateStatement.getUpdateCount() + " for the mark " + mark.getDescription());
}
ConnectionFactory.commit();
} catch (SQLException | SoundLooperDatabaseException e) {
this.rollbackCurrentTransaction();
throw new SoundLooperRuntimeException("Error when trying to update mark " + mark.getDescription(), e);
}
}
@Override
public Mark delete(Mark mark) {
try {
// check that the mark with this ID exists
ResultSet checkQueryID = ConnectionFactory.getNewStatement().executeQuery(
"SELECT id FROM mark WHERE id = '" + mark.getId() + "'");
if (!checkQueryID.next()) {
// there is no mark with this ID
throw new SoundLooperDatabaseException("Mark with this ID is not persisted : " + mark.getDescription(),
SoundLooperDatabaseException.ERROR_CODE_MARK_ID_DOES_NOT_EXISTS_IN_DATABASE);
}
Statement updateStatement = ConnectionFactory.getNewStatement();
updateStatement.executeUpdate("DELETE FROM MARK WHERE ID = '" + mark.getId() + "'");
if (updateStatement.getUpdateCount() != 1) {
throw new SoundLooperDatabaseException("Delete mark query must update 1 row and it delete "
+ updateStatement.getUpdateCount() + " for the mark " + mark.getDescription());
}
ConnectionFactory.commit();
mark.setId(SoundLooperObject.ID_NOT_INITIALIZED);
Song song = mark.getSong();
song.getMarks().remove(mark.getName());
return mark;
} catch (SQLException | SoundLooperDatabaseException e) {
this.rollbackCurrentTransaction();
throw new SoundLooperRuntimeException("Error when deleting mark", e);
}
}
/**
* Get the list of marks for a song
*
* @param song
* the song
* @return the list of marks
* @throws SoundLooperException
* if an error occured
*/
public ArrayList<Mark> getList(Song song) throws SoundLooperException {
ArrayList<Mark> markList = new ArrayList<Mark>();
try {
// r�cup�re la liste des chansons cr��es
ResultSet marksQuery = ConnectionFactory.getNewStatement().executeQuery(
"SELECT ID, name, begintime,endtime,id_song FROM mark WHERE id_song=" + song.getId()
+ " ORDER BY begintime");
while (marksQuery.next()) {
long id = marksQuery.getLong("id");
String name = marksQuery.getString("name");
int beginTime = marksQuery.getInt("begintime");
int endTime = marksQuery.getInt("endtime");
Mark mark = createNew(name, beginTime, endTime, song, true);
mark.setId(id);
markList.add(mark);
}
} catch (SQLException e) {
throw new SoundLooperRuntimeException("Error when get the marks list", e);
}
return markList;
}
@Override
public Mark createNew() {
return new Mark();
}
}