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

IAlbum: Expose total number of discs

Fix #50
parent 8900847c
......@@ -69,6 +69,11 @@ public:
* The value is cached, and doesn't require fetching anything.
*/
virtual uint32_t nbTracks() const = 0;
/**
* @brief nbDiscs Returns the total number of discs for this album.
* Defaults to 1
*/
virtual uint32_t nbDiscs() const = 0;
virtual unsigned int duration() const = 0;
virtual Query<IMedia> searchTracks( const std::string& pattern,
......
......@@ -53,7 +53,8 @@ Album::Album(MediaLibraryPtr ml, sqlite::Row& row)
, m_thumbnailId( row.load<decltype(m_thumbnailId)>( 5 ) )
, m_nbTracks( row.load<decltype(m_nbTracks)>( 6 ) )
, m_duration( row.load<decltype(m_duration)>( 7 ) )
, m_isPresent( row.load<decltype(m_isPresent)>( 8 ) )
, m_nbDiscs( row.load<decltype(m_nbDiscs)>( 8 ) )
, m_isPresent( row.load<decltype(m_isPresent)>( 9 ) )
{
}
......@@ -66,6 +67,7 @@ Album::Album( MediaLibraryPtr ml, const std::string& title, int64_t thumbnailId
, m_thumbnailId( thumbnailId )
, m_nbTracks( 0 )
, m_duration( 0 )
, m_nbDiscs( 1 )
, m_isPresent( true )
{
}
......@@ -78,6 +80,7 @@ Album::Album( MediaLibraryPtr ml, const Artist* artist )
, m_thumbnailId( 0 )
, m_nbTracks( 0 )
, m_duration( 0 )
, m_nbDiscs( 1 )
, m_isPresent( true )
{
}
......@@ -338,6 +341,21 @@ unsigned int Album::nbTracks() const
return m_nbTracks;
}
uint32_t Album::nbDiscs() const
{
return m_nbDiscs;
}
bool Album::setNbDiscs( uint32_t nbDiscs )
{
static const std::string req = "UPDATE " + Album::Table::Name
+ " SET nb_discs = ? WHERE id_album = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, nbDiscs, m_id ) == false )
return false;
m_nbDiscs = nbDiscs;
return true;
}
unsigned int Album::duration() const
{
return m_duration;
......@@ -406,6 +424,7 @@ void Album::createTable( sqlite::Connection* dbConnection )
"thumbnail_id UNSIGNED INT,"
"nb_tracks UNSIGNED INTEGER DEFAULT 0,"
"duration UNSIGNED INTEGER NOT NULL DEFAULT 0,"
"nb_discs UNSIGNED INTEGER NOT NULL DEFAULT 1,"
"is_present UNSIGNED INTEGER NOT NULL DEFAULT 0,"
"FOREIGN KEY( artist_id ) REFERENCES " + Artist::Table::Name
+ "(id_artist) ON DELETE CASCADE,"
......
......@@ -89,6 +89,8 @@ class Album : public IAlbum, public DatabaseHelpers<Album>
unsigned int discNumber, int64_t artistId, Genre* genre );
bool removeTrack( Media& media, AlbumTrack& albumTrack );
unsigned int nbTracks() const override;
virtual uint32_t nbDiscs() const override;
bool setNbDiscs( uint32_t nbDiscs );
unsigned int duration() const override;
virtual ArtistPtr albumArtist() const override;
......@@ -130,6 +132,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album>
int64_t m_thumbnailId;
unsigned int m_nbTracks;
unsigned int m_duration;
uint32_t m_nbDiscs;
bool m_isPresent;
mutable std::vector<MediaPtr> m_tracks;
......
......@@ -627,7 +627,7 @@ bool MetadataAnalyzer::parseAudioFile( IItem& item )
auto track = handleTrack( album, item, artists.second ? artists.second : artists.first,
genre.get() );
auto res = link( *media, *album, artists.first, artists.second );
auto res = link( item, *album, artists.first, artists.second );
media->save();
t->commit();
m_notifier->notifyAlbumModification( album );
......@@ -923,9 +923,11 @@ std::shared_ptr<AlbumTrack> MetadataAnalyzer::handleTrack( std::shared_ptr<Album
/* Misc */
bool MetadataAnalyzer::link( Media& media, Album& album,
bool MetadataAnalyzer::link( IItem& item, Album& album,
std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> artist )
{
Media& media = static_cast<Media&>( *item.media() );
if ( albumArtist == nullptr )
{
assert( artist != nullptr );
......@@ -1019,6 +1021,16 @@ bool MetadataAnalyzer::link( Media& media, Album& album,
albumArtist->updateNbTrack( 1 );
}
const auto discTotal = toInt( item, IItem::Metadata::DiscTotal );
const auto discNumber = toInt( item, IItem::Metadata::DiscNumber );
if ( ( discTotal != 0 && discTotal > 0 &&
static_cast<uint32_t>( discTotal ) > album.nbDiscs() ) ||
( discNumber != 0 && discNumber > 0 &&
static_cast<uint32_t>( discNumber ) > album.nbDiscs() ) )
{
album.setNbDiscs( std::max( discTotal, discNumber ) );
}
return true;
}
......
......@@ -59,7 +59,7 @@ protected:
std::pair<std::shared_ptr<Artist>, std::shared_ptr<Artist>> findOrCreateArtist( IItem& item ) const;
std::shared_ptr<AlbumTrack> handleTrack( std::shared_ptr<Album> album, IItem& item,
std::shared_ptr<Artist> artist, Genre* genre ) const;
bool link( Media& media, Album& album, std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> artist );
bool link(IItem& item, Album& album, std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> artist );
std::shared_ptr<Album> findAlbum( IItem& item, std::shared_ptr<Artist> albumArtist,
std::shared_ptr<Artist> artist );
std::shared_ptr<Genre> handleGenre( IItem& item ) const;
......
......@@ -448,6 +448,12 @@ void Tests::checkAlbums( const rapidjson::Value& expectedAlbums, std::vector<Alb
|| a->artworkMrl().compare(0, 13, "attachment://") == 0 )
return false;
}
if ( expectedAlbum.HasMember( "nbDiscs" ) )
{
const auto nbDiscs = expectedAlbum["nbDiscs"].GetUint();
if ( a->nbDiscs() != nbDiscs )
return false;
}
return true;
});
ASSERT_NE( end( albums ), it );
......
......@@ -8,6 +8,7 @@
"albums": [{
"title": "Album",
"nbTracks": 3,
"nbDiscs": 3,
"tracks": [{
"title": "Track 1",
"cd": 1
......
......@@ -658,3 +658,18 @@ TEST_F( Albums, SearchTracks )
auto albumTracksSearch = alb->searchTracks( "otter", nullptr )->all();
ASSERT_EQ( 1u, albumTracksSearch.size() );
}
TEST_F( Albums, NbDiscs )
{
auto alb = ml->createAlbum( "disc" );
ASSERT_EQ( 1u, alb->nbDiscs() );
auto res = alb->setNbDiscs( 123 );
ASSERT_TRUE( res );
ASSERT_EQ( 123u, alb->nbDiscs() );
Reload();
alb = std::static_pointer_cast<Album>( ml->album( alb->id() ) );
ASSERT_EQ( 123u, alb->nbDiscs() );
}
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