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

Album: Expose a duration

Fix #6
parent 393002bc
......@@ -64,4 +64,5 @@ public:
* The value is cached, and doesn't require fetching anything.
*/
virtual uint32_t nbTracks() const = 0;
virtual unsigned int duration() const = 0;
};
......@@ -44,6 +44,7 @@ Album::Album(MediaLibraryPtr ml, sqlite::Row& row)
>> m_shortSummary
>> m_artworkMrl
>> m_nbTracks
>> m_duration
>> m_isPresent;
}
......@@ -54,6 +55,7 @@ Album::Album( MediaLibraryPtr ml, const std::string& title )
, m_artistId( 0 )
, m_releaseYear( ~0u )
, m_nbTracks( 0 )
, m_duration( 0 )
, m_isPresent( true )
{
}
......@@ -64,6 +66,7 @@ Album::Album( MediaLibraryPtr ml, const Artist* artist )
, m_artistId( artist->id() )
, m_releaseYear( ~0u )
, m_nbTracks( 0 )
, m_duration( 0 )
, m_isPresent( true )
{
}
......@@ -229,6 +232,7 @@ std::shared_ptr<AlbumTrack> Album::addTrack( std::shared_ptr<Media> media, unsig
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, m_id ) == false )
return nullptr;
m_nbTracks++;
m_duration += media->duration();
t->commit();
auto lock = m_tracks.lock();
// Don't assume we have always have a valid value in m_tracks.
......@@ -248,6 +252,11 @@ unsigned int Album::nbTracks() const
return m_nbTracks;
}
unsigned int Album::duration() const
{
return m_duration;
}
ArtistPtr Album::albumArtist() const
{
if ( m_artistId == 0 )
......@@ -323,6 +332,7 @@ bool Album::createTable(DBConnection dbConnection )
"short_summary TEXT,"
"artwork_mrl TEXT,"
"nb_tracks UNSIGNED INTEGER DEFAULT 0,"
"duration UNSIGNED INTEGER NOT NULL DEFAULT 0,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"FOREIGN KEY( artist_id ) REFERENCES " + policy::ArtistTable::Name
+ "(id_artist) ON DELETE CASCADE"
......@@ -362,6 +372,13 @@ bool Album::createTriggers(DBConnection dbConnection)
" WHERE id_album=old.album_id AND "
"(SELECT COUNT(id_track) FROM " + policy::AlbumTrackTable::Name + " WHERE album_id=old.album_id) = 0;"
" END";
static const std::string updateDurationTriggerReq = "CREATE TRIGGER IF NOT EXISTS update_album_duration"
" AFTER INSERT ON " + policy::AlbumTrackTable::Name +
" BEGIN"
" UPDATE " + policy::AlbumTable::Name +
" SET duration = duration + (SELECT duration FROM " + policy::MediaTable::Name + " WHERE id_media=new.media_id)"
" WHERE id_album = new.album_id;"
" END";
static const std::string vtriggerInsert = "CREATE TRIGGER IF NOT EXISTS insert_album_fts AFTER INSERT ON "
+ policy::AlbumTable::Name +
// Skip unknown albums
......@@ -378,6 +395,7 @@ bool Album::createTriggers(DBConnection dbConnection)
" END";
return sqlite::Tools::executeRequest( dbConnection, triggerReq ) &&
sqlite::Tools::executeRequest( dbConnection, deleteTriggerReq ) &&
sqlite::Tools::executeRequest( dbConnection, updateDurationTriggerReq ) &&
sqlite::Tools::executeRequest( dbConnection, vtriggerInsert ) &&
sqlite::Tools::executeRequest( dbConnection, vtriggerDelete );
}
......
......@@ -87,6 +87,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
///
std::shared_ptr<AlbumTrack> addTrack( std::shared_ptr<Media> media, unsigned int trackNb, unsigned int discNumber);
unsigned int nbTracks() const override;
unsigned int duration() const override;
virtual ArtistPtr albumArtist() const override;
bool setAlbumArtist( std::shared_ptr<Artist> artist );
......@@ -120,6 +121,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
std::string m_shortSummary;
std::string m_artworkMrl;
unsigned int m_nbTracks;
unsigned int m_duration;
bool m_isPresent;
mutable Cache<std::vector<MediaPtr>> m_tracks;
......
......@@ -404,3 +404,26 @@ TEST_F( Albums, Sort )
ASSERT_EQ( a2->id(), albums[1]->id() );
ASSERT_EQ( a1->id(), albums[2]->id() );
}
TEST_F( Albums, Duration )
{
auto a = ml->createAlbum( "album" );
ASSERT_EQ( 0u, a->duration() );
auto m = ml->addFile( "track.mp3" );
m->setDuration( 100 );
m->save();
a->addTrack( m, 1, 1 );
ASSERT_EQ( 100u, a->duration() );
auto m2 = ml->addFile( "track2.mp3" );
m2->setDuration( 200 );
m2->save();
a->addTrack( m2, 1, 1 );
ASSERT_EQ( 300u, a->duration() );
Reload();
auto a2 = ml->album( a->id() );
ASSERT_EQ( 300u, a2->duration() );
}
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