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

Create a relationship between albums & artists

parent 9c265fe4
......@@ -19,6 +19,8 @@ class IAlbum
virtual bool setArtworkUrl( const std::string& artworkUrl ) = 0;
virtual std::vector<std::shared_ptr<IAlbumTrack>> tracks() const = 0;
virtual AlbumTrackPtr addTrack( const std::string& title, unsigned int trackId ) = 0;
virtual std::vector<ArtistPtr> artists() const = 0;
virtual bool addArtist( ArtistPtr artist ) = 0;
virtual bool destroy() = 0;
};
......
#include "Album.h"
#include "AlbumTrack.h"
#include "Artist.h"
#include "database/SqliteTools.h"
......@@ -98,6 +99,25 @@ AlbumTrackPtr Album::addTrack( const std::string& title, unsigned int trackNb )
return AlbumTrack::create( m_dbConnection, m_id, title, trackNb );
}
std::vector<ArtistPtr> Album::artists() const
{
static const std::string req = "SELECT art.* FROM " + policy::ArtistTable::Name + " art "
"LEFT JOIN AlbumArtistRelation aar ON aar.id_artist = art.id_artist "
"WHERE aar.id_album = ?";
return sqlite::Tools::fetchAll<Artist, IArtist>( m_dbConnection, req, m_id );
}
bool Album::addArtist( ArtistPtr artist )
{
static const std::string req = "INSERT INTO AlbumArtistRelation VALUES(?, ?)";
if ( m_id == 0 || artist->id() == 0 )
{
LOG_ERROR("Both artist * album need to be inserted in database before being linked together" );
return false;
}
return sqlite::Tools::executeRequest( m_dbConnection, req, m_id, artist->id() );
}
bool Album::destroy()
{
auto ts = tracks();
......@@ -121,7 +141,17 @@ bool Album::createTable(DBConnection dbConnection )
"artwork_url TEXT,"
"UNSIGNED INTEGER last_sync_date"
")";
return sqlite::Tools::executeRequest( dbConnection, req );
static const std::string reqRel = "CREATE TABLE IF NOT EXISTS AlbumArtistRelation("
"id_album INTEGER,"
"id_artist INTEGER,"
"PRIMARY KEY (id_album, id_artist),"
"FOREIGN KEY(id_album) REFERENCES " + policy::AlbumTable::Name + "("
+ policy::AlbumTable::CacheColumn + ") ON DELETE CASCADE,"
"FOREIGN KEY(id_artist) REFERENCES " + policy::ArtistTable::Name + "("
+ policy::ArtistTable::CacheColumn + ") ON DELETE CASCADE"
")";
return sqlite::Tools::executeRequest( dbConnection, req ) &&
sqlite::Tools::executeRequest( dbConnection, reqRel );
}
AlbumPtr Album::create(DBConnection dbConnection, const std::string& title )
......
......@@ -40,6 +40,10 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable>
virtual time_t lastSyncDate() const;
virtual std::vector<std::shared_ptr<IAlbumTrack> > tracks() const;
virtual AlbumTrackPtr addTrack( const std::string& title, unsigned int trackNb );
virtual std::vector<ArtistPtr> artists() const override;
virtual bool addArtist( ArtistPtr artist ) override;
virtual bool destroy();
static bool createTable( DBConnection dbConnection );
......
#include "Artist.h"
#include "Album.h"
#include "database/SqliteTools.h"
......@@ -48,7 +49,10 @@ bool Artist::setShortBio(const std::string &shortBio)
std::vector<AlbumPtr> Artist::albums() const
{
//FIXME
static const std::string req = "SELECT alb.* FROM " + policy::AlbumTable::Name + " alb "
"LEFT JOIN AlbumArtistRelation aar ON aar.id_album = alb.id_album "
"WHERE aar.id_artist = ?";
return sqlite::Tools::fetchAll<Album, IAlbum>( m_dbConnection, req, m_id );
}
bool Artist::createTable( DBConnection dbConnection )
......
......@@ -186,3 +186,29 @@ TEST_F( Albums, DestroyAlbum )
f = ml->file( "file.avi" );
ASSERT_EQ( f, nullptr );
}
TEST_F( Albums, Artists )
{
auto album = ml->createAlbum( "album" );
auto artist1 = ml->createArtist( "john" );
auto artist2 = ml->createArtist( "doe" );
ASSERT_NE( album, nullptr );
ASSERT_NE( artist1, nullptr );
ASSERT_NE( artist2, nullptr );
auto res = album->addArtist( artist1 );
ASSERT_EQ( res, true );
res = album->addArtist( artist2 );
ASSERT_EQ( res, true );
auto artists = album->artists();
ASSERT_EQ( artists.size(), 2u );
Reload();
album = ml->album( "album" );
artists = album->artists();
ASSERT_EQ( artists.size(), 2u );
}
#include "Tests.h"
#include "IArtist.h"
#include "IAlbum.h"
class Artists : public Tests
{
......@@ -35,3 +36,26 @@ TEST_F( Artists, ShortBio )
ASSERT_NE( a, nullptr );
ASSERT_EQ( a->shortBio(), bio );
}
TEST_F( Artists, Albums )
{
auto artist = ml->createArtist( "Cannibal Otters" );
auto album1 = ml->createAlbum( "album1" );
auto album2 = ml->createAlbum( "album2" );
ASSERT_NE( artist, nullptr );
ASSERT_NE( album1, nullptr );
ASSERT_NE( album2, nullptr );
album1->addArtist( artist );
album2->addArtist( artist );
auto albums = artist->albums();
ASSERT_EQ( albums.size(), 2u );
Reload();
artist = ml->artist( "Cannibal Otters" );
albums = artist->albums();
ASSERT_EQ( albums.size(), 2u );
}
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