package com.pugh.sockso.music;
import com.pugh.sockso.Utils;
import com.pugh.sockso.db.Database;
import com.google.inject.Singleton;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* a class for searching for music
*
*/
@Singleton
public class MusicSearch {
private final Database db;
/**
* constructor
*
* @param db
*
*/
public MusicSearch( final Database db ) {
this.db = db;
}
/**
* searches the database for music matching the specified query
*
* @param query
*
* @return
*
* @throws java.sql.SQLException
*
*/
public List<MusicItem> search( final String query ) throws SQLException {
ResultSet rs = null;
PreparedStatement st = null;
try {
final String sql = createQuery( query );
st = db.prepare( sql );
rs = st.executeQuery();
return createResults( rs );
}
finally {
Utils.close( rs );
Utils.close( st );
}
}
/**
* Create the complete query for finding music
*
* @param query
*
* @return
*
*/
protected String createQuery( final String query ) {
return " select '" + MusicItem.TRACK + "' as type, t.id as id, t.name as name, " +
" ar.id as artist_id, ar.name as artist_name, " +
" al.id as album_id, al.name as album_name, " +
" g.id as genre_id, g.name as genre_name " +
" from tracks t " +
" inner join artists ar " +
" on ar.id = t.artist_id " +
" inner join albums al " +
" on al.id = t.album_id " +
" inner join genres g " +
" on g.id = t.genre_id " +
" where t.name like '%" + db.escape(query) + "%' " +
" union " +
" select '" + MusicItem.ALBUM + "', al.id, al.name, ar.id, ar.name, -1, '', -1, '' " +
" from albums al " +
" inner join artists ar " +
" on ar.id = al.artist_id " +
" where al.name like '%" + db.escape(query) + "%' " +
" union " +
" select '" + MusicItem.ARTIST + "', ar.id, ar.name, -1, '', -1, '', -1, '' " +
" from artists ar " +
" where ar.name like '%" + db.escape(query) + "%' " +
" union " +
" select '" + MusicItem.PLAYLIST + "', p.id, p.name, -1, '', -1, '', -1, '' " +
" from playlists p " +
" where p.name like '%" + db.escape(query) + "%' " +
" order by name asc " +
" limit 15 ";
}
/**
* Create the music item results from the search results
*
* @param rs
*
* @return
*
* @throws SQLException
*
*/
protected List<MusicItem> createResults( final ResultSet rs ) throws SQLException {
final List<MusicItem> items = new ArrayList<MusicItem>();
while ( rs.next() ) {
final String type = rs.getString( "type" );
if ( type.equals(MusicItem.TRACK) ) {
final Album album = new Album.Builder()
.id(rs.getInt("album_id"))
.name(rs.getString("album_name"))
.build();
final Artist artist = new Artist.Builder()
.id(rs.getInt("artist_id"))
.name(rs.getString("artist_name"))
.build();
final Track track = new Track.Builder()
.artist(artist)
.album(album)
.genre( new Genre(rs.getInt("genre_id"), rs.getString("genre_name")) )
.id( rs.getInt("id") )
.name( rs.getString("name") )
.number(-1)
.path("")
.dateAdded(null)
.build();
items.add( track );
}
else if ( type.equals(MusicItem.ALBUM) ) {
final Artist artist = new Artist.Builder()
.id(rs.getInt("artist_id"))
.name(rs.getString("artist_name"))
.build();
final Album album = new Album.Builder()
.artist(artist)
.id(rs.getInt("id"))
.name(rs.getString("name"))
.build();
items.add( album );
}
else if ( type.equals(MusicItem.PLAYLIST) ) {
final Playlist playlist = new Playlist(
rs.getInt("id"),
rs.getString("name")
);
items.add( playlist );
}
else {
items.add( new MusicItem(rs.getString("type"),rs.getInt("id"),rs.getString("name")) );
}
}
return items;
}
}