diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AbstractDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AbstractDao.java index 2da6acb7..d7c7b8e4 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AbstractDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AbstractDao.java @@ -19,15 +19,23 @@ */ package org.libresonic.player.dao; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.*; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.libresonic.player.Logger; +import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.util.Assert; /** * Abstract superclass for all DAO's. @@ -107,6 +115,16 @@ public class AbstractDao { return result; } + protected List namedQueryWithLimit(String sql, RowMapper rowMapper, Map args, int limit) { + long t = System.nanoTime(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(daoHelper.getDataSource()); + jdbcTemplate.setMaxRows(limit); + NamedParameterJdbcTemplate namedTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); + List result = namedTemplate.query(sql, args, rowMapper); + log(sql, t); + return result; + } + protected List queryForStrings(String sql, Object... args) { long t = System.nanoTime(); List result = getJdbcTemplate().queryForList(sql, args, String.class); @@ -173,4 +191,5 @@ public class AbstractDao { public void setDaoHelper(DaoHelper daoHelper) { this.daoHelper = daoHelper; } + } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java index 71cffec2..19644344 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java @@ -41,10 +41,11 @@ import org.libresonic.player.util.FileUtil; * @author Sindre Mehus */ public class AlbumDao extends AbstractDao { - - private static final String COLUMNS = "id, path, name, artist, song_count, duration_seconds, cover_art_path, " + + private static final String INSERT_COLUMNS = "path, name, artist, song_count, duration_seconds, cover_art_path, " + "year, genre, play_count, last_played, comment, created, last_scanned, present, folder_id"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; + private final RowMapper rowMapper = new AlbumMapper(); /** @@ -55,7 +56,7 @@ public class AlbumDao extends AbstractDao { * @return The album or null. */ public Album getAlbum(String artistName, String albumName) { - return queryOne("select " + COLUMNS + " from album where artist=? and name=?", rowMapper, artistName, albumName); + return queryOne("select " + QUERY_COLUMNS + " from album where artist=? and name=?", rowMapper, artistName, albumName); } /** @@ -67,7 +68,7 @@ public class AlbumDao extends AbstractDao { public Album getAlbumForFile(MediaFile file) { // First, get all albums with the correct album name (irrespective of artist). - List candidates = query("select " + COLUMNS + " from album where name=?", rowMapper, file.getAlbumName()); + List candidates = query("select " + QUERY_COLUMNS + " from album where name=?", rowMapper, file.getAlbumName()); if (candidates.isEmpty()) { return null; } @@ -91,7 +92,7 @@ public class AlbumDao extends AbstractDao { } public Album getAlbum(int id) { - return queryOne("select " + COLUMNS + " from album where id=?", rowMapper, id); + return queryOne("select " + QUERY_COLUMNS + " from album where id=?", rowMapper, id); } public List getAlbumsForArtist(final String artist, final List musicFolders) { @@ -102,7 +103,8 @@ public class AlbumDao extends AbstractDao { put("artist", artist); put("folders", MusicFolder.toIdList(musicFolders)); }}; - return namedQuery("select " + COLUMNS + " from album where artist = :artist and present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + + " from album where artist = :artist and present and folder_id in (:folders) " + "order by name", rowMapper, args); } @@ -135,7 +137,7 @@ public class AlbumDao extends AbstractDao { if (n == 0) { - update("insert into album (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null, album.getPath(), + update("insert into album (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", album.getPath(), album.getName(), album.getArtist(), album.getSongCount(), album.getDurationSeconds(), album.getCoverArtPath(), album.getYear(), album.getGenre(), album.getPlayCount(), album.getLastPlayed(), album.getComment(), album.getCreated(), album.getLastScanned(), album.isPresent(), album.getFolderId()); @@ -164,7 +166,7 @@ public class AlbumDao extends AbstractDao { put("offset", offset); }}; String orderBy = byArtist ? "artist, name" : "name"; - return namedQuery("select " + COLUMNS + " from album where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "order by " + orderBy + " limit :count offset :offset", rowMapper, args); } @@ -185,7 +187,8 @@ public class AlbumDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from album where play_count > 0 and present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + + " from album where play_count > 0 and present and folder_id in (:folders) " + "order by play_count desc limit :count offset :offset", rowMapper, args); } @@ -206,7 +209,8 @@ public class AlbumDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from album where last_played is not null and present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + + " from album where last_played is not null and present and folder_id in (:folders) " + "order by last_played desc limit :count offset :offset", rowMapper, args); } @@ -227,7 +231,7 @@ public class AlbumDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from album where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "order by created desc limit :count offset :offset", rowMapper, args); } @@ -250,7 +254,7 @@ public class AlbumDao extends AbstractDao { put("offset", offset); put("username", username); }}; - return namedQuery("select " + prefix(COLUMNS, "album") + " from starred_album, album where album.id = starred_album.album_id and " + + return namedQuery("select " + prefix(QUERY_COLUMNS, "album") + " from starred_album, album where album.id = starred_album.album_id and " + "album.present and album.folder_id in (:folders) and starred_album.username = :username " + "order by starred_album.created desc limit :count offset :offset", rowMapper, args); @@ -275,7 +279,7 @@ public class AlbumDao extends AbstractDao { put("offset", offset); put("genre", genre); }}; - return namedQuery("select " + COLUMNS + " from album where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "and genre = :genre limit :count offset :offset", rowMapper, args); } @@ -302,18 +306,18 @@ public class AlbumDao extends AbstractDao { put("toYear", toYear); }}; if (fromYear <= toYear) { - return namedQuery("select " + COLUMNS + " from album where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "and year between :fromYear and :toYear order by year limit :count offset :offset", rowMapper, args); } else { - return namedQuery("select " + COLUMNS + " from album where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "and year between :toYear and :fromYear order by year desc limit :count offset :offset", rowMapper, args); } } public void markNonPresent(Date lastScanned) { - int minId = queryForInt("select top 1 id from album where last_scanned != ? and present", 0, lastScanned); + int minId = queryForInt("select min(id) from album where last_scanned != ? and present", 0, lastScanned); int maxId = queryForInt("select max(id) from album where last_scanned != ? and present", 0, lastScanned); final int batchSize = 1000; @@ -323,7 +327,7 @@ public class AlbumDao extends AbstractDao { } public void expunge() { - int minId = queryForInt("select top 1 id from album where not present", 0); + int minId = queryForInt("select min(id) from album where not present", 0); int maxId = queryForInt("select max(id) from album where not present", 0); final int batchSize = 1000; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java index f7b44367..df293c91 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java @@ -41,7 +41,8 @@ import java.util.Map; public class ArtistDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(ArtistDao.class); - private static final String COLUMNS = "id, name, cover_art_path, album_count, last_scanned, present, folder_id"; + private static final String INSERT_COLUMNS = "name, cover_art_path, album_count, last_scanned, present, folder_id"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final RowMapper rowMapper = new ArtistMapper(); @@ -52,7 +53,7 @@ public class ArtistDao extends AbstractDao { * @return The artist or null. */ public Artist getArtist(String artistName) { - return queryOne("select " + COLUMNS + " from artist where name=?", rowMapper, artistName); + return queryOne("select " + QUERY_COLUMNS + " from artist where name=?", rowMapper, artistName); } /** @@ -71,7 +72,7 @@ public class ArtistDao extends AbstractDao { put("folders", MusicFolder.toIdList(musicFolders)); }}; - return namedQueryOne("select " + COLUMNS + " from artist where name = :name and folder_id in (:folders)", + return namedQueryOne("select " + QUERY_COLUMNS + " from artist where name = :name and folder_id in (:folders)", rowMapper, args); } @@ -82,7 +83,7 @@ public class ArtistDao extends AbstractDao { * @return The artist or null. */ public Artist getArtist(int id) { - return queryOne("select " + COLUMNS + " from artist where id=?", rowMapper, id); + return queryOne("select " + QUERY_COLUMNS + " from artist where id=?", rowMapper, id); } /** @@ -102,7 +103,7 @@ public class ArtistDao extends AbstractDao { int n = update(sql, artist.getCoverArtPath(), artist.getAlbumCount(), artist.getLastScanned(), artist.isPresent(), artist.getFolderId(), artist.getName()); if (n == 0) { - update("insert into artist (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null, + update("insert into artist (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", artist.getName(), artist.getCoverArtPath(), artist.getAlbumCount(), artist.getLastScanned(), artist.isPresent(), artist.getFolderId()); } @@ -128,7 +129,7 @@ public class ArtistDao extends AbstractDao { put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from artist where present and folder_id in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from artist where present and folder_id in (:folders) " + "order by name limit :count offset :offset", rowMapper, args); } @@ -153,7 +154,7 @@ public class ArtistDao extends AbstractDao { put("offset", offset); }}; - return namedQuery("select " + prefix(COLUMNS, "artist") + " from starred_artist, artist " + + return namedQuery("select " + prefix(QUERY_COLUMNS, "artist") + " from starred_artist, artist " + "where artist.id = starred_artist.artist_id and " + "artist.present and starred_artist.username = :username and " + "artist.folder_id in (:folders) " + @@ -166,7 +167,7 @@ public class ArtistDao extends AbstractDao { } public void markNonPresent(Date lastScanned) { - int minId = queryForInt("select top 1 id from artist where last_scanned != ? and present", 0, lastScanned); + int minId = queryForInt("select min(id) from artist where last_scanned != ? and present", 0, lastScanned); int maxId = queryForInt("select max(id) from artist where last_scanned != ? and present", 0, lastScanned); final int batchSize = 1000; @@ -176,7 +177,7 @@ public class ArtistDao extends AbstractDao { } public void expunge() { - int minId = queryForInt("select top 1 id from artist where not present", 0); + int minId = queryForInt("select min(id) from artist where not present", 0); int maxId = queryForInt("select max(id) from artist where not present", 0); final int batchSize = 1000; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java index 118816ce..45c2ebc9 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AvatarDao.java @@ -33,7 +33,8 @@ import java.util.List; */ public class AvatarDao extends AbstractDao { - private static final String COLUMNS = "id, name, created_date, mime_type, width, height, data"; + private static final String INSERT_COLUMNS = "name, created_date, mime_type, width, height, data"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final AvatarRowMapper rowMapper = new AvatarRowMapper(); /** @@ -42,7 +43,7 @@ public class AvatarDao extends AbstractDao { * @return All system avatars. */ public List getAllSystemAvatars() { - String sql = "select " + COLUMNS + " from system_avatar"; + String sql = "select " + QUERY_COLUMNS + " from system_avatar"; return query(sql, rowMapper); } @@ -53,7 +54,7 @@ public class AvatarDao extends AbstractDao { * @return The avatar or null if not found. */ public Avatar getSystemAvatar(int id) { - String sql = "select " + COLUMNS + " from system_avatar where id=" + id; + String sql = "select " + QUERY_COLUMNS + " from system_avatar where id=" + id; return queryOne(sql, rowMapper); } @@ -64,7 +65,7 @@ public class AvatarDao extends AbstractDao { * @return The avatar or null if not found. */ public Avatar getCustomAvatar(String username) { - String sql = "select " + COLUMNS + " from custom_avatar where username=?"; + String sql = "select " + QUERY_COLUMNS + " from custom_avatar where username=?"; return queryOne(sql, rowMapper, username); } @@ -79,8 +80,9 @@ public class AvatarDao extends AbstractDao { update(sql, username); if (avatar != null) { - update("insert into custom_avatar(" + COLUMNS + ", username) values(" + questionMarks(COLUMNS) + ", ?)", - null, avatar.getName(), avatar.getCreatedDate(), avatar.getMimeType(), + update("insert into custom_avatar(" + INSERT_COLUMNS + + ", username) values(" + questionMarks(INSERT_COLUMNS) + ", ?)", + avatar.getName(), avatar.getCreatedDate(), avatar.getMimeType(), avatar.getWidth(), avatar.getHeight(), avatar.getData(), username); } } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java index 1ea9ac44..a4917b55 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java @@ -34,7 +34,8 @@ import org.libresonic.player.domain.Bookmark; */ public class BookmarkDao extends AbstractDao { - private static final String COLUMNS = "id, media_file_id, position_millis, username, comment, created, changed"; + private static final String INSERT_COLUMNS = "media_file_id, position_millis, username, comment, created, changed"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private BookmarkRowMapper bookmarkRowMapper = new BookmarkRowMapper(); @@ -44,7 +45,7 @@ public class BookmarkDao extends AbstractDao { * @return Possibly empty list of all bookmarks. */ public List getBookmarks() { - String sql = "select " + COLUMNS + " from bookmark"; + String sql = "select " + QUERY_COLUMNS + " from bookmark"; return query(sql, bookmarkRowMapper); } @@ -54,7 +55,7 @@ public class BookmarkDao extends AbstractDao { * @return Possibly empty list of all bookmarks for the user. */ public List getBookmarks(String username) { - String sql = "select " + COLUMNS + " from bookmark where username=?"; + String sql = "select " + QUERY_COLUMNS + " from bookmark where username=?"; return query(sql, bookmarkRowMapper, username); } @@ -66,9 +67,9 @@ public class BookmarkDao extends AbstractDao { bookmark.getPositionMillis(), bookmark.getComment(), bookmark.getChanged(), bookmark.getMediaFileId(), bookmark.getUsername()); if (n == 0) { - update("insert into bookmark (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null, - bookmark.getMediaFileId(), bookmark.getPositionMillis(), bookmark.getUsername(), bookmark.getComment(), - bookmark.getCreated(), bookmark.getChanged()); + update("insert into bookmark (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", + bookmark.getMediaFileId(), bookmark.getPositionMillis(), bookmark.getUsername(), bookmark.getComment(), + bookmark.getCreated(), bookmark.getChanged()); int id = queryForInt("select id from bookmark where media_file_id=? and username=?", 0, bookmark.getMediaFileId(), bookmark.getUsername()); bookmark.setId(id); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/DaoHelper.java b/libresonic-main/src/main/java/org/libresonic/player/dao/DaoHelper.java index b9c8bd0a..e423e2d8 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/DaoHelper.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/DaoHelper.java @@ -19,6 +19,7 @@ */ package org.libresonic.player.dao; +import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; @@ -43,4 +44,5 @@ public interface DaoHelper { */ NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(); + DataSource getDataSource(); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/GenericDaoHelper.java b/libresonic-main/src/main/java/org/libresonic/player/dao/GenericDaoHelper.java index d4007f80..b860b18e 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/GenericDaoHelper.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/GenericDaoHelper.java @@ -1,19 +1,23 @@ package org.libresonic.player.dao; +import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; public class GenericDaoHelper implements DaoHelper { - JdbcTemplate jdbcTemplate; + final JdbcTemplate jdbcTemplate; - NamedParameterJdbcTemplate namedParameterJdbcTemplate; + final NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + final DataSource dataSource; public GenericDaoHelper( - JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate + DataSource dataSource ) { - this.jdbcTemplate = jdbcTemplate; - this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; + this.dataSource = dataSource; + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); } @Override @@ -25,4 +29,9 @@ public class GenericDaoHelper implements DaoHelper { public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return namedParameterJdbcTemplate; } + + @Override + public DataSource getDataSource() { + return dataSource; + } } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java index 385e4a90..791436e1 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/InternetRadioDao.java @@ -36,7 +36,8 @@ import org.libresonic.player.domain.InternetRadio; public class InternetRadioDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(InternetRadioDao.class); - private static final String COLUMNS = "id, name, stream_url, homepage_url, enabled, changed"; + private static final String INSERT_COLUMNS = "name, stream_url, homepage_url, enabled, changed"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final InternetRadioRowMapper rowMapper = new InternetRadioRowMapper(); /** @@ -45,7 +46,7 @@ public class InternetRadioDao extends AbstractDao { * @return Possibly empty list of all internet radio stations. */ public List getAllInternetRadios() { - String sql = "select " + COLUMNS + " from internet_radio"; + String sql = "select " + QUERY_COLUMNS + " from internet_radio"; return query(sql, rowMapper); } @@ -55,7 +56,7 @@ public class InternetRadioDao extends AbstractDao { * @param radio The internet radio station to create. */ public void createInternetRadio(InternetRadio radio) { - String sql = "insert into internet_radio (" + COLUMNS + ") values (null, ?, ?, ?, ?, ?)"; + String sql = "insert into internet_radio (" + INSERT_COLUMNS + ") values (?, ?, ?, ?, ?)"; update(sql, radio.getName(), radio.getStreamUrl(), radio.getHomepageUrl(), radio.isEnabled(), radio.getChanged()); LOG.info("Created internet radio station " + radio.getName()); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java index 3d964a4b..7dc7ffd5 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java @@ -40,15 +40,16 @@ import static org.libresonic.player.domain.MediaFile.MediaType.*; * @author Sindre Mehus */ public class MediaFileDao extends AbstractDao { + private static final String INSERT_COLUMNS = "path, folder, type, format, title, album, artist, album_artist, disc_number, " + + "track_number, year, genre, bit_rate, variable_bit_rate, duration_seconds, file_size, width, height, cover_art_path, " + + "parent_path, play_count, last_played, comment, created, changed, last_scanned, children_last_updated, present, version"; - private static final String COLUMNS = "id, path, folder, type, format, title, album, artist, album_artist, disc_number, " + - "track_number, year, genre, bit_rate, variable_bit_rate, duration_seconds, file_size, width, height, cover_art_path, " + - "parent_path, play_count, last_played, comment, created, changed, last_scanned, children_last_updated, present, version"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private static final String GENRE_COLUMNS = "name, song_count, album_count"; public static final int VERSION = 4; - private final RowMapper rowMapper = new MediaFileMapper(); + private final RowMapper rowMapper = new MediaFileMapper(); private final RowMapper musicFileInfoRowMapper = new MusicFileInfoMapper(); private final RowMapper genreRowMapper = new GenreMapper(); @@ -59,7 +60,7 @@ public class MediaFileDao extends AbstractDao { * @return The media file or null. */ public MediaFile getMediaFile(String path) { - return queryOne("select " + COLUMNS + " from media_file where path=?", rowMapper, path); + return queryOne("select " + QUERY_COLUMNS + " from media_file where path=?", rowMapper, path); } /** @@ -69,7 +70,7 @@ public class MediaFileDao extends AbstractDao { * @return The media file or null. */ public MediaFile getMediaFile(int id) { - return queryOne("select " + COLUMNS + " from media_file where id=?", rowMapper, id); + return queryOne("select " + QUERY_COLUMNS + " from media_file where id=?", rowMapper, id); } /** @@ -79,18 +80,18 @@ public class MediaFileDao extends AbstractDao { * @return The list of children. */ public List getChildrenOf(String path) { - return query("select " + COLUMNS + " from media_file where parent_path=? and present", rowMapper, path); + return query("select " + QUERY_COLUMNS + " from media_file where parent_path=? and present", rowMapper, path); } public List getFilesInPlaylist(int playlistId) { - return query("select " + prefix(COLUMNS, "media_file") + " from playlist_file, media_file where " + + return query("select " + prefix(QUERY_COLUMNS, "media_file") + " from playlist_file, media_file where " + "media_file.id = playlist_file.media_file_id and " + "playlist_file.playlist_id = ? " + "order by playlist_file.id", rowMapper, playlistId); } public List getSongsForAlbum(String artist, String album) { - return query("select " + COLUMNS + " from media_file where album_artist=? and album=? and present " + + return query("select " + QUERY_COLUMNS + " from media_file where album_artist=? and album=? and present " + "and type in (?,?,?) order by disc_number, track_number", rowMapper, artist, album, MUSIC.name(), AUDIOBOOK.name(), PODCAST.name()); } @@ -105,7 +106,8 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and present and folder in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and present and folder in (:folders) " + "order by title limit :count offset :offset", rowMapper, args); } @@ -118,7 +120,7 @@ public class MediaFileDao extends AbstractDao { put("name", name); put("folders", MusicFolder.toPathList(musicFolders)); }}; - return namedQueryOne("select " + COLUMNS + " from media_file where type = :type and artist = :name " + + return namedQueryOne("select " + QUERY_COLUMNS + " from media_file where type = :type and artist = :name " + "and present and folder in (:folders)", rowMapper, args); } @@ -175,7 +177,7 @@ public class MediaFileDao extends AbstractDao { file.setPlayCount(musicFileInfo.getPlayCount()); } - update("insert into media_file (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null, + update("insert into media_file (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", file.getPath(), file.getFolder(), file.getMediaType().name(), file.getFormat(), file.getTitle(), file.getAlbumName(), file.getArtist(), file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(), file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(), @@ -228,7 +230,8 @@ public class MediaFileDao extends AbstractDao { put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and play_count > 0 and present and folder in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and play_count > 0 and present and folder in (:folders) " + "order by play_count desc limit :count offset :offset", rowMapper, args); } @@ -250,7 +253,8 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and last_played is not null and present " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and last_played is not null and present " + "and folder in (:folders) order by last_played desc limit :count offset :offset", rowMapper, args); } @@ -273,7 +277,8 @@ public class MediaFileDao extends AbstractDao { put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and folder in (:folders) and present " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and folder in (:folders) and present " + "order by created desc limit :count offset :offset", rowMapper, args); } @@ -298,7 +303,8 @@ public class MediaFileDao extends AbstractDao { }}; String orderBy = byArtist ? "artist, album" : "album"; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and folder in (:folders) and present " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and folder in (:folders) and present " + "order by " + orderBy + " limit :count offset :offset", rowMapper, args); } @@ -327,11 +333,13 @@ public class MediaFileDao extends AbstractDao { }}; if (fromYear <= toYear) { - return namedQuery("select " + COLUMNS + " from media_file where type = :type and folder in (:folders) and present " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and folder in (:folders) and present " + "and year between :fromYear and :toYear order by year limit :count offset :offset", rowMapper, args); } else { - return namedQuery("select " + COLUMNS + " from media_file where type = :type and folder in (:folders) and present " + + return namedQuery("select " + QUERY_COLUMNS + + " from media_file where type = :type and folder in (:folders) and present " + "and year between :toYear and :fromYear order by year desc limit :count offset :offset", rowMapper, args); } @@ -358,7 +366,7 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + COLUMNS + " from media_file where type = :type and folder in (:folders) " + + return namedQuery("select " + QUERY_COLUMNS + " from media_file where type = :type and folder in (:folders) " + "and present and genre = :genre limit :count offset :offset", rowMapper, args); } @@ -373,13 +381,14 @@ public class MediaFileDao extends AbstractDao { put("offset", offset); put("folders", MusicFolder.toPathList(musicFolders)); }}; - return namedQuery("select " + COLUMNS + " from media_file where type in (:types) and genre = :genre " + + return namedQuery("select " + QUERY_COLUMNS + " from media_file where type in (:types) and genre = :genre " + "and present and folder in (:folders) limit :count offset :offset", rowMapper, args); } public List getSongsByArtist(String artist, int offset, int count) { - return query("select " + COLUMNS + " from media_file where type in (?,?,?) and artist=? and present limit ? offset ?", + return query("select " + QUERY_COLUMNS + + " from media_file where type in (?,?,?) and artist=? and present limit ? offset ?", rowMapper, MUSIC.name(), PODCAST.name(), AUDIOBOOK.name(), artist, count, offset); } @@ -393,7 +402,7 @@ public class MediaFileDao extends AbstractDao { put("type", MUSIC.name()); put("folders", MusicFolder.toPathList(musicFolders)); }}; - return namedQueryOne("select " + COLUMNS + " from media_file where artist = :artist " + + return namedQueryOne("select " + QUERY_COLUMNS + " from media_file where artist = :artist " + "and title = :title and type = :type and present and folder in (:folders)" , rowMapper, args); } @@ -419,7 +428,7 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + prefix(COLUMNS, "media_file") + " from starred_media_file, media_file where media_file.id = starred_media_file.media_file_id and " + + return namedQuery("select " + prefix(QUERY_COLUMNS, "media_file") + " from starred_media_file, media_file where media_file.id = starred_media_file.media_file_id and " + "media_file.present and media_file.type = :type and media_file.folder in (:folders) and starred_media_file.username = :username " + "order by starred_media_file.created desc limit :count offset :offset", rowMapper, args); @@ -446,7 +455,7 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + prefix(COLUMNS, "media_file") + " from starred_media_file, media_file " + + return namedQuery("select " + prefix(QUERY_COLUMNS, "media_file") + " from starred_media_file, media_file " + "where media_file.id = starred_media_file.media_file_id and " + "media_file.present and media_file.type = :type and starred_media_file.username = :username and " + "media_file.folder in (:folders) " + @@ -475,7 +484,7 @@ public class MediaFileDao extends AbstractDao { put("count", count); put("offset", offset); }}; - return namedQuery("select " + prefix(COLUMNS, "media_file") + " from starred_media_file, media_file where media_file.id = starred_media_file.media_file_id and " + + return namedQuery("select " + prefix(QUERY_COLUMNS, "media_file") + " from starred_media_file, media_file where media_file.id = starred_media_file.media_file_id and " + "media_file.present and media_file.type in (:types) and starred_media_file.username = :username and " + "media_file.folder in (:folders) " + "order by starred_media_file.created desc limit :count offset :offset", @@ -490,7 +499,6 @@ public class MediaFileDao extends AbstractDao { Map args = new HashMap() {{ put("folders", MusicFolder.toPathList(criteria.getMusicFolders())); put("username", username); - put("count", criteria.getCount()); put("fromYear", criteria.getFromYear()); put("toYear", criteria.getToYear()); put("genre", criteria.getGenre()); @@ -508,7 +516,7 @@ public class MediaFileDao extends AbstractDao { boolean joinAlbumRating = (criteria.getMinAlbumRating() != null || criteria.getMaxAlbumRating() != null); boolean joinStarred = (criteria.isShowStarredSongs() ^ criteria.isShowUnstarredSongs()); - String query = "select top :count " + prefix(COLUMNS, "media_file") + " from media_file "; + String query = "select " + prefix(QUERY_COLUMNS, "media_file") + " from media_file "; if (joinStarred) { query += "left outer join starred_media_file on media_file.id = starred_media_file.media_file_id and starred_media_file.username = :username "; @@ -587,7 +595,7 @@ public class MediaFileDao extends AbstractDao { query += " order by rand()"; - return namedQuery(query, rowMapper, args); + return namedQueryWithLimit(query, rowMapper, args, criteria.getCount()); } public int getAlbumCount(final List musicFolders) { @@ -649,7 +657,7 @@ public class MediaFileDao extends AbstractDao { } public void markNonPresent(Date lastScanned) { - int minId = queryForInt("select top 1 id from media_file where last_scanned != ? and present", 0, lastScanned); + int minId = queryForInt("select min(id) from media_file where last_scanned != ? and present", 0, lastScanned); int maxId = queryForInt("select max(id) from media_file where last_scanned != ? and present", 0, lastScanned); final int batchSize = 1000; @@ -661,7 +669,7 @@ public class MediaFileDao extends AbstractDao { } public void expunge() { - int minId = queryForInt("select top 1 id from media_file where not present", 0); + int minId = queryForInt("select min(id) from media_file where not present", 0); int maxId = queryForInt("select max(id) from media_file where not present", 0); final int batchSize = 1000; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java index 49dcdc3e..e83ee296 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MusicFolderDao.java @@ -36,7 +36,8 @@ import java.util.List; public class MusicFolderDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(MusicFolderDao.class); - private static final String COLUMNS = "id, path, name, enabled, changed"; + private static final String INSERT_COLUMNS = "path, name, enabled, changed"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final MusicFolderRowMapper rowMapper = new MusicFolderRowMapper(); /** @@ -45,7 +46,7 @@ public class MusicFolderDao extends AbstractDao { * @return Possibly empty list of all music folders. */ public List getAllMusicFolders() { - String sql = "select " + COLUMNS + " from music_folder"; + String sql = "select " + QUERY_COLUMNS + " from music_folder"; return query(sql, rowMapper); } @@ -55,7 +56,7 @@ public class MusicFolderDao extends AbstractDao { * @param musicFolder The music folder to create. */ public void createMusicFolder(MusicFolder musicFolder) { - String sql = "insert into music_folder (" + COLUMNS + ") values (null, ?, ?, ?, ?)"; + String sql = "insert into music_folder (" + INSERT_COLUMNS + ") values (?, ?, ?, ?)"; update(sql, musicFolder.getPath(), musicFolder.getName(), musicFolder.isEnabled(), musicFolder.getChanged()); Integer id = queryForInt("select max(id) from music_folder", 0); @@ -86,7 +87,7 @@ public class MusicFolderDao extends AbstractDao { } public List getMusicFoldersForUser(String username) { - String sql = "select " + prefix(COLUMNS, "music_folder") + " from music_folder, music_folder_user " + + String sql = "select " + prefix(QUERY_COLUMNS, "music_folder") + " from music_folder, music_folder_user " + "where music_folder.id = music_folder_user.music_folder_id and music_folder_user.username = ?"; return query(sql, rowMapper, username); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java index a098c43b..28e32da7 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java @@ -33,11 +33,12 @@ import org.libresonic.player.domain.SavedPlayQueue; */ public class PlayQueueDao extends AbstractDao { - private static final String COLUMNS = "id, username, current, position_millis, changed, changed_by"; + private static final String INSERT_COLUMNS = "username, current, position_millis, changed, changed_by"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final RowMapper rowMapper = new PlayQueueMapper(); public synchronized SavedPlayQueue getPlayQueue(String username) { - SavedPlayQueue playQueue = queryOne("select " + COLUMNS + " from play_queue where username=?", rowMapper, username); + SavedPlayQueue playQueue = queryOne("select " + QUERY_COLUMNS + " from play_queue where username=?", rowMapper, username); if (playQueue == null) { return null; } @@ -48,8 +49,8 @@ public class PlayQueueDao extends AbstractDao { public synchronized void savePlayQueue(SavedPlayQueue playQueue) { update("delete from play_queue where username=?", playQueue.getUsername()); - update("insert into play_queue(" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", - null, playQueue.getUsername(), playQueue.getCurrentMediaFileId(), playQueue.getPositionMillis(), + update("insert into play_queue(" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", + playQueue.getUsername(), playQueue.getCurrentMediaFileId(), playQueue.getPositionMillis(), playQueue.getChanged(), playQueue.getChangedBy()); int id = queryForInt("select max(id) from play_queue", 0); playQueue.setId(id); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java index 4dc8dc2a..0754a493 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java @@ -35,8 +35,9 @@ import java.util.*; public class PlayerDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(PlayerDao.class); - private static final String COLUMNS = "id, name, type, username, ip_address, auto_control_enabled, m3u_bom_enabled, " + - "last_seen, cover_art_scheme, transcode_scheme, dynamic_ip, technology, client_id"; + private static final String INSERT_COLUMNS = "name, type, username, ip_address, auto_control_enabled, m3u_bom_enabled, " + + "last_seen, cover_art_scheme, transcode_scheme, dynamic_ip, technology, client_id"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private PlayerRowMapper rowMapper = new PlayerRowMapper(); private Map playlists = Collections.synchronizedMap(new HashMap()); @@ -47,7 +48,7 @@ public class PlayerDao extends AbstractDao { * @return Possibly empty list of all users. */ public List getAllPlayers() { - String sql = "select " + COLUMNS + " from player"; + String sql = "select " + QUERY_COLUMNS + " from player"; return query(sql, rowMapper); } @@ -61,10 +62,10 @@ public class PlayerDao extends AbstractDao { */ public List getPlayersForUserAndClientId(String username, String clientId) { if (clientId != null) { - String sql = "select " + COLUMNS + " from player where username=? and client_id=?"; + String sql = "select " + QUERY_COLUMNS + " from player where username=? and client_id=?"; return query(sql, rowMapper, username, clientId); } else { - String sql = "select " + COLUMNS + " from player where username=? and client_id is null"; + String sql = "select " + QUERY_COLUMNS + " from player where username=? and client_id is null"; return query(sql, rowMapper, username); } } @@ -76,7 +77,7 @@ public class PlayerDao extends AbstractDao { * @return The player with the given ID, or null if no such player exists. */ public Player getPlayerById(String id) { - String sql = "select " + COLUMNS + " from player where id=?"; + String sql = "select " + QUERY_COLUMNS + " from player where id=?"; return queryOne(sql, rowMapper, id); } @@ -92,7 +93,7 @@ public class PlayerDao extends AbstractDao { } int id = existingMax + 1; player.setId(String.valueOf(id)); - String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; + String sql = "insert into player (" + QUERY_COLUMNS + ") values (" + questionMarks(QUERY_COLUMNS) + ")"; update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(), player.getIpAddress(), player.isAutoControlEnabled(), player.isM3uBomEnabled(), player.getLastSeen(), CoverArtScheme.MEDIUM.name(), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java index e41e3781..e653297b 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java @@ -40,18 +40,19 @@ import java.util.TreeMap; public class PlaylistDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(PlaylistDao.class); - private static final String COLUMNS = "id, username, is_public, name, comment, file_count, duration_seconds, " + - "created, changed, imported_from"; + private static final String INSERT_COLUMNS = "username, is_public, name, comment, file_count, duration_seconds, " + + "created, changed, imported_from"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final RowMapper rowMapper = new PlaylistMapper(); public List getReadablePlaylistsForUser(String username) { List result1 = getWritablePlaylistsForUser(username); - List result2 = query("select " + COLUMNS + " from playlist where is_public", rowMapper); - List result3 = query("select " + prefix(COLUMNS, "playlist") + " from playlist, playlist_user where " + - "playlist.id = playlist_user.playlist_id and " + - "playlist.username != ? and " + - "playlist_user.username = ?", rowMapper, username, username); + List result2 = query("select " + QUERY_COLUMNS + " from playlist where is_public", rowMapper); + List result3 = query("select " + prefix(QUERY_COLUMNS, "playlist") + " from playlist, playlist_user where " + + "playlist.id = playlist_user.playlist_id and " + + "playlist.username != ? and " + + "playlist_user.username = ?", rowMapper, username, username); // Put in sorted map to avoid duplicates. SortedMap map = new TreeMap(); @@ -68,20 +69,20 @@ public class PlaylistDao extends AbstractDao { } public List getWritablePlaylistsForUser(String username) { - return query("select " + COLUMNS + " from playlist where username=?", rowMapper, username); + return query("select " + QUERY_COLUMNS + " from playlist where username=?", rowMapper, username); } public Playlist getPlaylist(int id) { - return queryOne("select " + COLUMNS + " from playlist where id=?", rowMapper, id); + return queryOne("select " + QUERY_COLUMNS + " from playlist where id=?", rowMapper, id); } public List getAllPlaylists() { - return query("select " + COLUMNS + " from playlist", rowMapper); + return query("select " + QUERY_COLUMNS + " from playlist", rowMapper); } public synchronized void createPlaylist(Playlist playlist) { - update("insert into playlist(" + COLUMNS + ") values(" + questionMarks(COLUMNS) + ")", - null, playlist.getUsername(), playlist.isShared(), playlist.getName(), playlist.getComment(), + update("insert into playlist(" + INSERT_COLUMNS + ") values(" + questionMarks(INSERT_COLUMNS) + ")", + playlist.getUsername(), playlist.isShared(), playlist.getName(), playlist.getComment(), 0, 0, playlist.getCreated(), playlist.getChanged(), playlist.getImportedFrom()); int id = queryForInt("select max(id) from playlist", 0); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java index b61d870b..3940435e 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java @@ -36,9 +36,11 @@ import org.libresonic.player.domain.PodcastStatus; */ public class PodcastDao extends AbstractDao { - private static final String CHANNEL_COLUMNS = "id, url, title, description, image_url, status, error_message"; - private static final String EPISODE_COLUMNS = "id, channel_id, url, path, title, description, publish_date, " + - "duration, bytes_total, bytes_downloaded, status, error_message"; + private static final String CHANNEL_INSERT_COLUMNS = "url, title, description, image_url, status, error_message"; + private static final String CHANNEL_QUERY_COLUMNS = "id, " + CHANNEL_INSERT_COLUMNS; + private static final String EPISODE_INSERT_COLUMNS = "channel_id, url, path, title, description, publish_date, " + + "duration, bytes_total, bytes_downloaded, status, error_message"; + private static final String EPISODE_QUERY_COLUMNS = "id, " + EPISODE_INSERT_COLUMNS; private PodcastChannelRowMapper channelRowMapper = new PodcastChannelRowMapper(); private PodcastEpisodeRowMapper episodeRowMapper = new PodcastEpisodeRowMapper(); @@ -50,8 +52,9 @@ public class PodcastDao extends AbstractDao { * @return The ID of the newly created channel. */ public synchronized int createChannel(PodcastChannel channel) { - String sql = "insert into podcast_channel (" + CHANNEL_COLUMNS + ") values (" + questionMarks(CHANNEL_COLUMNS) + ")"; - update(sql, null, channel.getUrl(), channel.getTitle(), channel.getDescription(), channel.getImageUrl(), + String sql = "insert into podcast_channel (" + CHANNEL_INSERT_COLUMNS + ") values (" + questionMarks( + CHANNEL_INSERT_COLUMNS) + ")"; + update(sql, channel.getUrl(), channel.getTitle(), channel.getDescription(), channel.getImageUrl(), channel.getStatus().name(), channel.getErrorMessage()); return getJdbcTemplate().queryForObject("select max(id) from podcast_channel", Integer.class); @@ -63,7 +66,7 @@ public class PodcastDao extends AbstractDao { * @return Possibly empty list of all Podcast channels. */ public List getAllChannels() { - String sql = "select " + CHANNEL_COLUMNS + " from podcast_channel"; + String sql = "select " + CHANNEL_QUERY_COLUMNS + " from podcast_channel"; return query(sql, channelRowMapper); } @@ -71,7 +74,7 @@ public class PodcastDao extends AbstractDao { * Returns a single Podcast channel. */ public PodcastChannel getChannel(int channelId) { - String sql = "select " + CHANNEL_COLUMNS + " from podcast_channel where id=?"; + String sql = "select " + CHANNEL_QUERY_COLUMNS + " from podcast_channel where id=?"; return queryOne(sql, channelRowMapper, channelId); } @@ -102,8 +105,9 @@ public class PodcastDao extends AbstractDao { * @param episode The Podcast episode to create. */ public void createEpisode(PodcastEpisode episode) { - String sql = "insert into podcast_episode (" + EPISODE_COLUMNS + ") values (" + questionMarks(EPISODE_COLUMNS) + ")"; - update(sql, null, episode.getChannelId(), episode.getUrl(), episode.getPath(), + String sql = "insert into podcast_episode (" + EPISODE_INSERT_COLUMNS + ") values (" + questionMarks( + EPISODE_INSERT_COLUMNS) + ")"; + update(sql, episode.getChannelId(), episode.getUrl(), episode.getPath(), episode.getTitle(), episode.getDescription(), episode.getPublishDate(), episode.getDuration(), episode.getBytesTotal(), episode.getBytesDownloaded(), episode.getStatus().name(), episode.getErrorMessage()); @@ -116,7 +120,7 @@ public class PodcastDao extends AbstractDao { * reverse chronological order (newest episode first). */ public List getEpisodes(int channelId) { - String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where channel_id = ? " + + String sql = "select " + EPISODE_QUERY_COLUMNS + " from podcast_episode where channel_id = ? " + "and status != ? order by publish_date desc"; return query(sql, episodeRowMapper, channelId, PodcastStatus.DELETED); } @@ -128,7 +132,8 @@ public class PodcastDao extends AbstractDao { * reverse chronological order (newest episode first). */ public List getNewestEpisodes(int count) { - String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where status = ? and publish_date is not null " + + String sql = "select " + EPISODE_QUERY_COLUMNS + + " from podcast_episode where status = ? and publish_date is not null " + "order by publish_date desc limit ?"; return query(sql, episodeRowMapper, PodcastStatus.COMPLETED, count); } @@ -140,12 +145,12 @@ public class PodcastDao extends AbstractDao { * @return The episode or null if not found. */ public PodcastEpisode getEpisode(int episodeId) { - String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where id=?"; + String sql = "select " + EPISODE_QUERY_COLUMNS + " from podcast_episode where id=?"; return queryOne(sql, episodeRowMapper, episodeId); } public PodcastEpisode getEpisodeByUrl(String url) { - String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where url=?"; + String sql = "select " + EPISODE_QUERY_COLUMNS + " from podcast_episode where url=?"; return queryOne(sql, episodeRowMapper, url); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java index 702e4965..dc5ab836 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java @@ -38,7 +38,8 @@ import org.libresonic.player.domain.Share; */ public class ShareDao extends AbstractDao { - private static final String COLUMNS = "id, name, description, username, created, expires, last_visited, visit_count"; + private static final String INSERT_COLUMNS = "name, description, username, created, expires, last_visited, visit_count"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private ShareRowMapper shareRowMapper = new ShareRowMapper(); private ShareFileRowMapper shareFileRowMapper = new ShareFileRowMapper(); @@ -49,8 +50,8 @@ public class ShareDao extends AbstractDao { * @param share The share to create. The ID of the share will be set by this method. */ public synchronized void createShare(Share share) { - String sql = "insert into share (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; - update(sql, null, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(), + String sql = "insert into share (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")"; + update(sql, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(), share.getExpires(), share.getLastVisited(), share.getVisitCount()); int id = getJdbcTemplate().queryForObject("select max(id) from share", Integer.class); @@ -63,17 +64,17 @@ public class ShareDao extends AbstractDao { * @return Possibly empty list of all shares. */ public List getAllShares() { - String sql = "select " + COLUMNS + " from share"; + String sql = "select " + QUERY_COLUMNS + " from share"; return query(sql, shareRowMapper); } public Share getShareByName(String shareName) { - String sql = "select " + COLUMNS + " from share where name=?"; + String sql = "select " + QUERY_COLUMNS + " from share where name=?"; return queryOne(sql, shareRowMapper, shareName); } public Share getShareById(int id) { - String sql = "select " + COLUMNS + " from share where id=?"; + String sql = "select " + QUERY_COLUMNS + " from share where id=?"; return queryOne(sql, shareRowMapper, id); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java index d3d11720..ad7c43e2 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java @@ -36,7 +36,8 @@ import org.libresonic.player.domain.Transcoding; public class TranscodingDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(TranscodingDao.class); - private static final String COLUMNS = "id, name, source_formats, target_format, step1, step2, step3, default_active"; + private static final String INSERT_COLUMNS = "name, source_formats, target_format, step1, step2, step3, default_active"; + private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private TranscodingRowMapper rowMapper = new TranscodingRowMapper(); /** @@ -45,7 +46,7 @@ public class TranscodingDao extends AbstractDao { * @return Possibly empty list of all transcodings. */ public List getAllTranscodings() { - String sql = "select " + COLUMNS + " from transcoding2"; + String sql = "select " + QUERY_COLUMNS + " from transcoding2"; return query(sql, rowMapper); } @@ -56,9 +57,9 @@ public class TranscodingDao extends AbstractDao { * @return All active transcodings for the player. */ public List getTranscodingsForPlayer(String playerId) { - String sql = "select " + COLUMNS + " from transcoding2, player_transcoding2 " + - "where player_transcoding2.player_id = ? " + - "and player_transcoding2.transcoding_id = transcoding2.id"; + String sql = "select " + QUERY_COLUMNS + " from transcoding2, player_transcoding2 " + + "where player_transcoding2.player_id = ? " + + "and player_transcoding2.transcoding_id = transcoding2.id"; return query(sql, rowMapper, playerId); } @@ -87,7 +88,7 @@ public class TranscodingDao extends AbstractDao { existingMax = 0; } transcoding.setId(existingMax + 1); - String sql = "insert into transcoding2 (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; + String sql = "insert into transcoding2 (" + QUERY_COLUMNS + ") values (" + questionMarks(QUERY_COLUMNS) + ")"; update(sql, transcoding.getId(), transcoding.getName(), transcoding.getSourceFormats(), transcoding.getTargetFormat(), transcoding.getStep1(), transcoding.getStep2(), transcoding.getStep3(), transcoding.isDefaultActive()); diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-db.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-db.xml index cb7109c3..81b5bb36 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-db.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-db.xml @@ -8,15 +8,6 @@ - - - - - - - - - diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBase.java index 9617d227..f612c2b2 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBase.java @@ -43,7 +43,7 @@ public abstract class DaoTestCaseBase extends TestCase { protected DaoTestCaseBase() { DataSource dataSource = createDataSource(); - daoHelper = new GenericDaoHelper(new JdbcTemplate(dataSource), new NamedParameterJdbcTemplate(dataSource)); + daoHelper = new GenericDaoHelper(dataSource); runDatabaseMigration(dataSource); diff --git a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml b/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml index 82b5cf60..167f8bd1 100644 --- a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml +++ b/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml @@ -68,15 +68,6 @@ - - - - - - - - -