Commit 8d7c2df2 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

IAlbum: Allow tracks of a specific album to be searched

parent b43ea8bd
......@@ -68,6 +68,9 @@ public:
*/
virtual uint32_t nbTracks() const = 0;
virtual unsigned int duration() const = 0;
virtual Query<IMedia> searchTracks( const std::string& pattern,
const QueryParameters* params = nullptr ) const = 0;
};
}
......@@ -282,6 +282,12 @@ std::vector<MediaPtr> Album::cachedTracks() const
return m_tracks.get();
}
Query<IMedia> Album::searchTracks( const std::string& pattern,
const QueryParameters* params ) const
{
return Media::searchAlbumTracks( m_ml, pattern, m_id, params );
}
std::shared_ptr<AlbumTrack> Album::addTrack( std::shared_ptr<Media> media, unsigned int trackNb,
unsigned int discNumber, int64_t artistId, Genre* genre )
{
......
......@@ -100,6 +100,9 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
bool addArtist( std::shared_ptr<Artist> artist );
bool removeArtist( Artist* artist );
virtual Query<IMedia> searchTracks( const std::string& pattern,
const QueryParameters* params = nullptr ) const override;
static void createTable( sqlite::Connection* dbConnection );
static void createTriggers( sqlite::Connection* dbConnection );
static std::shared_ptr<Album> create( MediaLibraryPtr ml, const std::string& title, int64_t thumbnailId );
......
......@@ -707,6 +707,23 @@ Query<IMedia> Media::search( MediaLibraryPtr ml, const std::string& title,
return make_query<Media, IMedia>( ml, "m.*", req, title, File::Type::Main, type );
}
Query<IMedia> Media::searchAlbumTracks(MediaLibraryPtr ml, const std::string& pattern, int64_t albumId, const QueryParameters* params)
{
std::string req = "FROM " + policy::MediaTable::Name + " m "
" INNER JOIN " + policy::FileTable::Name + " f ON m.id_media = f.media_id"
" INNER JOIN " + policy::AlbumTrackTable::Name + " tra ON tra.media_id = m.id_media "
" WHERE"
" m.id_media IN (SELECT rowid FROM " + policy::MediaTable::Name + "Fts"
" WHERE " + policy::MediaTable::Name + "Fts MATCH '*' || ? || '*')"
" AND tra.album_id = ?"
" AND f.is_present = 1"
" AND f.type = ?"
" AND m.subtype = ?";
req += sortRequest( params );
return make_query<Media, IMedia>( ml, "m.*", req, pattern, albumId,
File::Type::Main, Media::SubType::AlbumTrack );
}
Query<IMedia> Media::fetchHistory( MediaLibraryPtr ml )
{
static const std::string req = "FROM " + policy::MediaTable::Name + " WHERE last_played_date IS NOT NULL"
......
......@@ -129,6 +129,8 @@ class Media : public IMedia, public DatabaseHelpers<Media, policy::MediaTable>
const QueryParameters* params );
static Query<IMedia> search(MediaLibraryPtr ml, const std::string& title,
Media::Type subType, const QueryParameters* params );
static Query<IMedia> searchAlbumTracks( MediaLibraryPtr ml, const std::string& pattern,
int64_t albumId, const QueryParameters* params );
static Query<IMedia> fetchHistory( MediaLibraryPtr ml );
static void clearHistory( MediaLibraryPtr ml );
......
......@@ -604,3 +604,31 @@ TEST_F( Albums, SearchAndSort )
ASSERT_EQ( albs[0]->id(), alb2->id() );
ASSERT_EQ( albs[1]->id(), alb1->id() );
}
TEST_F( Albums, SearchTracks )
{
auto alb = ml->createAlbum( "Mustelidae" );
auto m1 = std::static_pointer_cast<Media>( ml->addMedia( "track1.mp3" ) );
m1->setTitleBuffered( "otter otter run run" );
m1->setType( IMedia::Type::Audio );
alb->addTrack( m1, 1, 1, 0, nullptr );
m1->save();
auto m2 = std::static_pointer_cast<Media>( ml->addMedia( "track2.mp3" ) );
m2->setTitleBuffered( "weasel weasel" );
m2->setType( IMedia::Type::Audio );
alb->addTrack( m2, 1, 1, 0, nullptr );
m2->save();
auto m3 = std::static_pointer_cast<Media>( ml->addMedia( "random media.aac" ) );
m3->setTitleBuffered( "otters are cute but not on this album" );
m3->setType( IMedia::Type::Audio );
m3->save();
auto allMedia = ml->searchMedia( "otter", nullptr )->all();
ASSERT_EQ( 2u, allMedia.size() );
auto albumTracksSearch = alb->searchTracks( "otter", nullptr )->all();
ASSERT_EQ( 1u, albumTracksSearch.size() );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment