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

Show: Implement search

parent c1dcb73f
......@@ -259,6 +259,8 @@ class IMediaLibrary
virtual MoviePtr movie( int64_t id ) const = 0;
virtual ArtistPtr artist( int64_t id ) const = 0;
virtual Query<IShow> shows( const QueryParameters* params = nullptr ) const = 0;
virtual Query<IShow> searchShows( const std::string& pattern,
const QueryParameters* params = nullptr ) const = 0;
/**
* @brief artists List all artists that have at least an album.
* Artists that only appear on albums as guests won't be listed from here, but will be
......
......@@ -186,6 +186,7 @@ void MediaLibrary::createAllTriggers()
Playlist::createTriggers( m_dbConnection.get() );
History::createTriggers( m_dbConnection.get() );
Label::createTriggers( m_dbConnection.get() );
Show::createTriggers( m_dbConnection.get() );
}
template <typename T>
......@@ -760,6 +761,12 @@ Query<IArtist> MediaLibrary::searchArtists( const std::string& name,
return Artist::search( this, name, params );
}
Query<IShow> MediaLibrary::searchShows( const std::string& pattern,
const QueryParameters* params ) const
{
return Show::search( this, pattern, params );
}
SearchAggregate MediaLibrary::search( const std::string& pattern,
const QueryParameters* params ) const
{
......
......@@ -130,6 +130,8 @@ class MediaLibrary : public IMediaLibrary, public IDeviceListerCb
const QueryParameters* params ) const override;
virtual Query<IArtist> searchArtists( const std::string& name,
const QueryParameters* params ) const override;
virtual Query<IShow> searchShows( const std::string& pattern,
const QueryParameters* params = nullptr ) const override;
virtual SearchAggregate search( const std::string& pattern,
const QueryParameters* params ) const override;
......
......@@ -188,7 +188,29 @@ void Show::createTable( sqlite::Connection* dbConnection )
"artwork_mrl TEXT,"
"tvdb_id TEXT"
")";
const std::string reqFts = "CREATE VIRTUAL TABLE IF NOT EXISTS " +
policy::ShowTable::Name + "Fts USING FTS3"
"("
"title"
")";
sqlite::Tools::executeRequest( dbConnection, req );
sqlite::Tools::executeRequest( dbConnection, reqFts );
}
void Show::createTriggers( sqlite::Connection* dbConnection )
{
const std::string insertTrigger = "CREATE TRIGGER IF NOT EXISTS insert_show_fts"
" AFTER INSERT ON " + policy::ShowTable::Name +
" BEGIN"
" INSERT INTO " + policy::ShowTable::Name + "Fts(rowid,title) VALUES(new.id_show, new.title);"
" END";
const std::string deleteTrigger = "CREATE TRIGGER IF NOT EXISTS delete_show_fts"
" BEFORE DELETE ON " + policy::ShowTable::Name +
" BEGIN"
" DELETE FROM " + policy::ShowTable::Name + "Fts WHERE rowid = old.id_show;"
" END";
sqlite::Tools::executeRequest( dbConnection, insertTrigger );
sqlite::Tools::executeRequest( dbConnection, deleteTrigger );
}
std::shared_ptr<Show> Show::create( MediaLibraryPtr ml, const std::string& name )
......@@ -229,4 +251,14 @@ std::string Show::orderBy( const QueryParameters* params )
return req;
}
Query<IShow> Show::search( MediaLibraryPtr ml, const std::string& pattern,
const QueryParameters* params )
{
std::string req = "FROM " + policy::ShowTable::Name + " WHERE id_show IN"
"(SELECT rowid FROM " + policy::ShowTable::Name + "Fts WHERE " +
policy::ShowTable::Name + "Fts MATCH '*' || ? || '*')";
req += orderBy( params );
return make_query<Show, IShow>( ml, "*", req, pattern );
}
}
......@@ -70,9 +70,12 @@ class Show : public IShow, public DatabaseHelpers<Show, policy::ShowTable>
virtual uint32_t nbEpisodes() const override;
static void createTable( sqlite::Connection* dbConnection );
static void createTriggers( sqlite::Connection* dbConnection );
static std::shared_ptr<Show> create( MediaLibraryPtr ml, const std::string& title );
static Query<IShow> listAll( MediaLibraryPtr ml, const QueryParameters* params );
static Query<IShow> search( MediaLibraryPtr ml, const std::string& pattern,
const QueryParameters* params );
private:
static std::string orderBy( const QueryParameters* params );
......
......@@ -34,6 +34,7 @@
#include "Genre.h"
#include "Media.h"
#include "Folder.h"
#include "Show.h"
#include "mocks/FileSystem.h"
......@@ -138,6 +139,11 @@ void MediaLibraryTester::deleteArtist( int64_t artistId )
Artist::destroy( this, artistId );
}
void MediaLibraryTester::deleteShow( int64_t showId )
{
Show::destroy( this, showId );
}
std::shared_ptr<Device> MediaLibraryTester::addDevice( const std::string& uuid, bool isRemovable )
{
return Device::create( this, uuid, "file://", isRemovable );
......
......@@ -53,6 +53,7 @@ public:
std::shared_ptr<Genre> createGenre( const std::string& name );
void deleteGenre( int64_t genreId );
void deleteArtist( int64_t artistId );
void deleteShow( int64_t showId );
std::shared_ptr<Device> addDevice( const std::string& uuid, bool isRemovable );
void setFsFactory( std::shared_ptr<fs::IFileSystemFactory> fsFactory );
void deleteTrack( int64_t trackId );
......
......@@ -172,7 +172,7 @@ TEST_F( DbModel, Upgrade12to13 )
// We can't check for the number of albums anymore since they are deleted
// as part of 13 -> 14 migration
CheckNbTriggers( 31 );
CheckNbTriggers( 33 );
}
TEST_F( DbModel, Upgrade13to14 )
......@@ -190,5 +190,5 @@ TEST_F( DbModel, Upgrade13to14 )
ASSERT_EQ( m->thumbnail(), "" );
ASSERT_FALSE( m->isThumbnailGenerated() );
CheckNbTriggers( 31 );
CheckNbTriggers( 33 );
}
......@@ -259,6 +259,37 @@ TEST_F( Shows, ListEpisodes )
ASSERT_EQ( s01e01->id(), episodes[2]->id() );
}
TEST_F( Shows, Search )
{
auto show1 = ml->createShow( "Cute fluffy sea otters" );
show1->setReleaseDate( 10 );
auto show2 = ml->createShow( "Less cute less fluffy naked mole rats" );
show2->setReleaseDate( 100 );
auto shows = ml->searchShows( "otters" )->all();
ASSERT_EQ( 1u, shows.size() );
ASSERT_EQ( show1->id(), shows[0]->id() );
QueryParameters params = { SortingCriteria::ReleaseDate, true };
shows = ml->searchShows( "fluffy", &params )->all();
ASSERT_EQ( 2u, shows.size() );
ASSERT_EQ( show2->id(), shows[0]->id() );
ASSERT_EQ( show1->id(), shows[1]->id() );
}
TEST_F( Shows, RemoveFromFts )
{
auto show1 = ml->createShow( "The otters show" );
auto shows = ml->searchShows( "otters" )->all();
ASSERT_EQ( 1u, shows.size() );
ml->deleteShow( show1->id() );
shows = ml->searchShows( "otters" )->all();
ASSERT_EQ( 0u, shows.size() );
}
////////////////////////////////////////////////////
// Files links:
////////////////////////////////////////////////////
......
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