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

Rename table classes: policy::XXXTable -> XXX::Table

parent 52e7e4ec
......@@ -39,9 +39,9 @@
namespace medialibrary
{
const std::string policy::AlbumTable::Name = "Album";
const std::string policy::AlbumTable::PrimaryKeyColumn = "id_album";
int64_t Album::* const policy::AlbumTable::PrimaryKey = &Album::m_id;
const std::string Album::Table::Name = "Album";
const std::string Album::Table::PrimaryKeyColumn = "id_album";
int64_t Album::* const Album::Table::PrimaryKey = &Album::m_id;
Album::Album(MediaLibraryPtr ml, sqlite::Row& row)
: m_ml( ml )
......@@ -113,7 +113,7 @@ bool Album::setReleaseYear( unsigned int date, bool force )
date = 0;
}
}
static const std::string req = "UPDATE " + policy::AlbumTable::Name
static const std::string req = "UPDATE " + Album::Table::Name
+ " SET release_year = ? WHERE id_album = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, date, m_id ) == false )
return false;
......@@ -128,7 +128,7 @@ const std::string& Album::shortSummary() const
bool Album::setShortSummary( const std::string& summary )
{
static const std::string req = "UPDATE " + policy::AlbumTable::Name
static const std::string req = "UPDATE " + Album::Table::Name
+ " SET short_summary = ? WHERE id_album = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, summary, m_id ) == false )
return false;
......@@ -180,7 +180,7 @@ bool Album::setArtworkMrl( const std::string& artworkMrl, Thumbnail::Origin orig
m_thumbnail = Thumbnail::create( m_ml, artworkMrl, Thumbnail::Origin::Album );
if ( m_thumbnail.get() == nullptr )
return false;
static const std::string req = "UPDATE " + policy::AlbumTable::Name
static const std::string req = "UPDATE " + Album::Table::Name
+ " SET thumbnail_id = ? WHERE id_album = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, m_thumbnail.get()->id(), m_id ) == false )
return false;
......@@ -255,8 +255,8 @@ Query<IMedia> Album::tracks( const QueryParameters* params ) const
{
// This doesn't return the cached version, because it would be fairly complicated, if not impossible or
// counter productive, to maintain a cache that respects all orderings.
std::string req = "FROM " + policy::MediaTable::Name + " med "
" INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.media_id = med.id_media "
std::string req = "FROM " + Media::Table::Name + " med "
" INNER JOIN " + AlbumTrack::Table::Name + " att ON att.media_id = med.id_media "
" WHERE att.album_id = ? AND med.is_present != 0";
return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ),
orderTracksBy( params ), m_id );
......@@ -266,8 +266,8 @@ Query<IMedia> Album::tracks( GenrePtr genre, const QueryParameters* params ) con
{
if ( genre == nullptr )
return {};
std::string req = "FROM " + policy::MediaTable::Name + " med "
" INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.media_id = med.id_media "
std::string req = "FROM " + Media::Table::Name + " med "
" INNER JOIN " + AlbumTrack::Table::Name + " att ON att.media_id = med.id_media "
" WHERE att.album_id = ? AND med.is_present != 0"
" AND genre_id = ?";
return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ),
......@@ -341,7 +341,7 @@ bool Album::setAlbumArtist( std::shared_ptr<Artist> artist )
return true;
if ( artist->id() == 0 )
return false;
static const std::string req = "UPDATE " + policy::AlbumTable::Name + " SET "
static const std::string req = "UPDATE " + Table::Name + " SET "
"artist_id = ? WHERE id_album = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, artist->id(), m_id ) == false )
return false;
......@@ -354,7 +354,7 @@ bool Album::setAlbumArtist( std::shared_ptr<Artist> artist )
m_artistId = artist->id();
m_albumArtist = artist;
artist->updateNbAlbum( 1 );
static const std::string ftsReq = "UPDATE " + policy::AlbumTable::Name + "Fts SET "
static const std::string ftsReq = "UPDATE " + Table::Name + "Fts SET "
" artist = ? WHERE rowid = ?";
sqlite::Tools::executeUpdate( m_ml->getConn(), ftsReq, artist->name(), m_id );
return true;
......@@ -362,7 +362,7 @@ bool Album::setAlbumArtist( std::shared_ptr<Artist> artist )
Query<IArtist> Album::artists( const QueryParameters* params ) const
{
std::string req = "FROM " + policy::ArtistTable::Name + " art "
std::string req = "FROM " + Artist::Table::Name + " art "
"INNER JOIN AlbumArtistRelation aar ON aar.artist_id = art.id_artist "
"WHERE aar.album_id = ?";
std::string orderBy = "ORDER BY art.name";
......@@ -393,7 +393,7 @@ bool Album::removeArtist(Artist* artist)
void Album::createTable( sqlite::Connection* dbConnection )
{
const std::string req = "CREATE TABLE IF NOT EXISTS " +
policy::AlbumTable::Name +
Table::Name +
"("
"id_album INTEGER PRIMARY KEY AUTOINCREMENT,"
"title TEXT COLLATE NOCASE,"
......@@ -404,22 +404,22 @@ void Album::createTable( sqlite::Connection* dbConnection )
"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
"FOREIGN KEY( artist_id ) REFERENCES " + Artist::Table::Name
+ "(id_artist) ON DELETE CASCADE,"
"FOREIGN KEY(thumbnail_id) REFERENCES " + policy::ThumbnailTable::Name
"FOREIGN KEY(thumbnail_id) REFERENCES " + Thumbnail::Table::Name
+ "(id_thumbnail)"
")";
const std::string reqRel = "CREATE TABLE IF NOT EXISTS AlbumArtistRelation("
"album_id INTEGER,"
"artist_id INTEGER,"
"PRIMARY KEY (album_id, artist_id),"
"FOREIGN KEY(album_id) REFERENCES " + policy::AlbumTable::Name + "("
+ policy::AlbumTable::PrimaryKeyColumn + ") ON DELETE CASCADE,"
"FOREIGN KEY(artist_id) REFERENCES " + policy::ArtistTable::Name + "("
+ policy::ArtistTable::PrimaryKeyColumn + ") ON DELETE CASCADE"
"FOREIGN KEY(album_id) REFERENCES " + Table::Name + "("
+ Table::PrimaryKeyColumn + ") ON DELETE CASCADE,"
"FOREIGN KEY(artist_id) REFERENCES " + Artist::Table::Name + "("
+ Artist::Table::PrimaryKeyColumn + ") ON DELETE CASCADE"
")";
const std::string vtableReq = "CREATE VIRTUAL TABLE IF NOT EXISTS "
+ policy::AlbumTable::Name + "Fts USING FTS3("
+ Table::Name + "Fts USING FTS3("
"title,"
"artist"
")";
......@@ -432,49 +432,49 @@ void Album::createTable( sqlite::Connection* dbConnection )
void Album::createTriggers( sqlite::Connection* dbConnection )
{
const std::string indexReq = "CREATE INDEX IF NOT EXISTS album_artist_id_idx ON " +
policy::AlbumTable::Name + "(artist_id)";
Table::Name + "(artist_id)";
static const std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS is_album_present AFTER UPDATE OF "
"is_present ON " + policy::AlbumTrackTable::Name +
"is_present ON " + AlbumTrack::Table::Name +
" BEGIN "
" UPDATE " + policy::AlbumTable::Name + " SET is_present="
" UPDATE " + Table::Name + " SET is_present="
"(SELECT EXISTS("
"SELECT id_track FROM " + policy::AlbumTrackTable::Name +
"SELECT id_track FROM " + AlbumTrack::Table::Name +
" WHERE album_id=new.album_id AND is_present != 0 LIMIT 1"
") )"
"WHERE id_album=new.album_id;"
" END";
static const std::string deleteTriggerReq = "CREATE TRIGGER IF NOT EXISTS delete_album_track AFTER DELETE ON "
+ policy::AlbumTrackTable::Name +
+ AlbumTrack::Table::Name +
" BEGIN "
" UPDATE " + policy::AlbumTable::Name +
" UPDATE " + Table::Name +
" SET"
" nb_tracks = nb_tracks - 1,"
" duration = duration - old.duration"
" WHERE id_album = old.album_id;"
" DELETE FROM " + policy::AlbumTable::Name +
" DELETE FROM " + Table::Name +
" WHERE id_album=old.album_id AND nb_tracks = 0;"
" END";
static const std::string updateAddTrackTriggerReq = "CREATE TRIGGER IF NOT EXISTS add_album_track"
" AFTER INSERT ON " + policy::AlbumTrackTable::Name +
" AFTER INSERT ON " + AlbumTrack::Table::Name +
" BEGIN"
" UPDATE " + policy::AlbumTable::Name +
" UPDATE " + Table::Name +
" SET duration = duration + new.duration,"
" nb_tracks = nb_tracks + 1"
" 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 +
+ Table::Name +
// Skip unknown albums
" WHEN new.title IS NOT NULL"
" BEGIN"
" INSERT INTO " + policy::AlbumTable::Name + "Fts(rowid, title) VALUES(new.id_album, new.title);"
" INSERT INTO " + Table::Name + "Fts(rowid, title) VALUES(new.id_album, new.title);"
" END";
static const std::string vtriggerDelete = "CREATE TRIGGER IF NOT EXISTS delete_album_fts BEFORE DELETE ON "
+ policy::AlbumTable::Name +
+ Table::Name +
// Unknown album probably won't be deleted, but better safe than sorry
" WHEN old.title IS NOT NULL"
" BEGIN"
" DELETE FROM " + policy::AlbumTable::Name + "Fts WHERE rowid = old.id_album;"
" DELETE FROM " + Table::Name + "Fts WHERE rowid = old.id_album;"
" END";
sqlite::Tools::executeRequest( dbConnection, indexReq );
sqlite::Tools::executeRequest( dbConnection, triggerReq );
......@@ -487,7 +487,7 @@ void Album::createTriggers( sqlite::Connection* dbConnection )
std::shared_ptr<Album> Album::create( MediaLibraryPtr ml, const std::string& title, int64_t thumbnailId )
{
auto album = std::make_shared<Album>( ml, title, thumbnailId );
static const std::string req = "INSERT INTO " + policy::AlbumTable::Name +
static const std::string req = "INSERT INTO " + Table::Name +
"(id_album, title, thumbnail_id) VALUES(NULL, ?, ?)";
if ( insert( ml, album, req, title, sqlite::ForeignKey( thumbnailId ) ) == false )
return nullptr;
......@@ -497,7 +497,7 @@ std::shared_ptr<Album> Album::create( MediaLibraryPtr ml, const std::string& tit
std::shared_ptr<Album> Album::createUnknownAlbum( MediaLibraryPtr ml, const Artist* artist )
{
auto album = std::make_shared<Album>( ml, artist );
static const std::string req = "INSERT INTO " + policy::AlbumTable::Name +
static const std::string req = "INSERT INTO " + Table::Name +
"(id_album, artist_id) VALUES(NULL, ?)";
if ( insert( ml, album, req, artist->id() ) == false )
return nullptr;
......@@ -507,10 +507,10 @@ std::shared_ptr<Album> Album::createUnknownAlbum( MediaLibraryPtr ml, const Arti
Query<IAlbum> Album::search( MediaLibraryPtr ml, const std::string& pattern,
const QueryParameters* params )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + Table::Name + " alb "
"WHERE id_album IN "
"(SELECT rowid FROM " + policy::AlbumTable::Name + "Fts WHERE " +
policy::AlbumTable::Name + "Fts MATCH '*' || ? || '*')"
"(SELECT rowid FROM " + Table::Name + "Fts WHERE " +
Table::Name + "Fts MATCH '*' || ? || '*')"
"AND is_present != 0";
return make_query<Album, IAlbum>( ml, "*", std::move( req ),
orderBy( params ), pattern );
......@@ -519,10 +519,10 @@ Query<IAlbum> Album::search( MediaLibraryPtr ml, const std::string& pattern,
Query<IAlbum> Album::searchFromArtist( MediaLibraryPtr ml, const std::string& pattern,
int64_t artistId, const QueryParameters* params )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + Table::Name + " alb "
"WHERE id_album IN "
"(SELECT rowid FROM " + policy::AlbumTable::Name + "Fts WHERE " +
policy::AlbumTable::Name + "Fts MATCH '*' || ? || '*')"
"(SELECT rowid FROM " + Table::Name + "Fts WHERE " +
Table::Name + "Fts MATCH '*' || ? || '*')"
"AND is_present != 0 "
"AND artist_id = ?";
return make_query<Album, IAlbum>( ml, "*", std::move( req ),
......@@ -531,8 +531,8 @@ Query<IAlbum> Album::searchFromArtist( MediaLibraryPtr ml, const std::string& pa
Query<IAlbum> Album::fromArtist( MediaLibraryPtr ml, int64_t artistId, const QueryParameters* params )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att "
std::string req = "FROM " + Table::Name + " alb "
"INNER JOIN " + AlbumTrack::Table::Name + " att "
"ON att.album_id = alb.id_album "
"WHERE (att.artist_id = ? OR alb.artist_id = ?) "
"AND att.is_present != 0 ";
......@@ -564,8 +564,8 @@ Query<IAlbum> Album::fromArtist( MediaLibraryPtr ml, int64_t artistId, const Que
Query<IAlbum> Album::fromGenre( MediaLibraryPtr ml, int64_t genreId, const QueryParameters* params )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.album_id = alb.id_album "
std::string req = "FROM " + Table::Name + " alb "
"INNER JOIN " + AlbumTrack::Table::Name + " att ON att.album_id = alb.id_album "
"WHERE att.genre_id = ? GROUP BY att.album_id";
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ),
orderBy( params ), genreId );
......@@ -574,11 +574,11 @@ Query<IAlbum> Album::fromGenre( MediaLibraryPtr ml, int64_t genreId, const Query
Query<IAlbum> Album::searchFromGenre( MediaLibraryPtr ml, const std::string& pattern,
int64_t genreId, const QueryParameters* params )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.album_id = alb.id_album "
std::string req = "FROM " + Table::Name + " alb "
"INNER JOIN " + AlbumTrack::Table::Name + " att ON att.album_id = alb.id_album "
"WHERE id_album IN "
"(SELECT rowid FROM " + policy::AlbumTable::Name + "Fts WHERE " +
policy::AlbumTable::Name + "Fts MATCH '*' || ? || '*')"
"(SELECT rowid FROM " + Table::Name + "Fts WHERE " +
Table::Name + "Fts MATCH '*' || ? || '*')"
"AND att.genre_id = ? GROUP BY att.album_id";
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ),
orderBy( params ), pattern, genreId );
......@@ -590,8 +590,8 @@ Query<IAlbum> Album::listAll( MediaLibraryPtr ml, const QueryParameters* params
auto desc = params != nullptr ? params->desc : false;
if ( sort == SortingCriteria::Artist )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::ArtistTable::Name + " art ON alb.artist_id = art.id_artist "
std::string req = "FROM " + Table::Name + " alb "
"INNER JOIN " + Artist::Table::Name + " art ON alb.artist_id = art.id_artist "
"WHERE alb.is_present != 0 ";
std::string orderBy = "ORDER BY art.name ";
if ( desc == true )
......@@ -602,9 +602,9 @@ Query<IAlbum> Album::listAll( MediaLibraryPtr ml, const QueryParameters* params
}
if ( sort == SortingCriteria::PlayCount )
{
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " t ON alb.id_album = t.album_id "
"INNER JOIN " + policy::MediaTable::Name + " m ON t.media_id = m.id_media "
std::string req = "FROM " + Table::Name + " alb "
"INNER JOIN " + AlbumTrack::Table::Name + " t ON alb.id_album = t.album_id "
"INNER JOIN " + Media::Table::Name + " m ON t.media_id = m.id_media "
"WHERE alb.is_present != 0 ";
std::string groupBy = "GROUP BY id_album "
"ORDER BY SUM(m.play_count) ";
......@@ -614,7 +614,7 @@ Query<IAlbum> Album::listAll( MediaLibraryPtr ml, const QueryParameters* params
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ),
std::move( groupBy ) );
}
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + Table::Name + " alb "
" WHERE is_present != 0";
return make_query<Album, IAlbum>( ml, "*", std::move( req ),
orderBy( params ) );
......
......@@ -41,19 +41,15 @@ class AlbumTrack;
class Artist;
class Media;
namespace policy
{
struct AlbumTable
{
static const std::string Name;
static const std::string PrimaryKeyColumn;
static int64_t Album::*const PrimaryKey;
};
}
class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
class Album : public IAlbum, public DatabaseHelpers<Album>
{
public:
struct Table
{
static const std::string Name;
static const std::string PrimaryKeyColumn;
static int64_t Album::*const PrimaryKey;
};
Album( MediaLibraryPtr ml, sqlite::Row& row );
Album( MediaLibraryPtr ml, const std::string& title, int64_t thumbnailId );
Album( MediaLibraryPtr ml, const Artist* artist );
......@@ -140,8 +136,6 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
mutable Cache<std::vector<MediaPtr>> m_tracks;
mutable Cache<std::shared_ptr<Artist>> m_albumArtist;
mutable Cache<std::shared_ptr<Thumbnail>> m_thumbnail;
friend struct policy::AlbumTable;
};
}
......
......@@ -36,9 +36,9 @@
namespace medialibrary
{
const std::string policy::AlbumTrackTable::Name = "AlbumTrack";
const std::string policy::AlbumTrackTable::PrimaryKeyColumn = "id_track";
int64_t AlbumTrack::* const policy::AlbumTrackTable::PrimaryKey = &AlbumTrack::m_id;
const std::string AlbumTrack::Table::Name = "AlbumTrack";
const std::string AlbumTrack::Table::PrimaryKeyColumn = "id_track";
int64_t AlbumTrack::* const AlbumTrack::Table::PrimaryKey = &AlbumTrack::m_id;
AlbumTrack::AlbumTrack( MediaLibraryPtr ml, sqlite::Row& row )
: m_ml( ml )
......@@ -93,7 +93,7 @@ int64_t AlbumTrack::artistId() const
void AlbumTrack::createTable( sqlite::Connection* dbConnection )
{
const std::string req = "CREATE TABLE IF NOT EXISTS " + policy::AlbumTrackTable::Name + "("
const std::string req = "CREATE TABLE IF NOT EXISTS " + AlbumTrack::Table::Name + "("
"id_track INTEGER PRIMARY KEY AUTOINCREMENT,"
"media_id INTEGER UNIQUE,"
"duration INTEGER NOT NULL,"
......@@ -103,16 +103,16 @@ void AlbumTrack::createTable( sqlite::Connection* dbConnection )
"album_id UNSIGNED INTEGER NOT NULL,"
"disc_number UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"FOREIGN KEY (media_id) REFERENCES " + policy::MediaTable::Name + "(id_media)"
"FOREIGN KEY (media_id) REFERENCES " + Media::Table::Name + "(id_media)"
" ON DELETE CASCADE,"
"FOREIGN KEY (artist_id) REFERENCES " + policy::ArtistTable::Name + "(id_artist)"
"FOREIGN KEY (artist_id) REFERENCES " + Artist::Table::Name + "(id_artist)"
" ON DELETE CASCADE,"
"FOREIGN KEY (genre_id) REFERENCES " + policy::GenreTable::Name + "(id_genre),"
"FOREIGN KEY (genre_id) REFERENCES " + Genre::Table::Name + "(id_genre),"
"FOREIGN KEY (album_id) REFERENCES Album(id_album) "
" ON DELETE CASCADE"
")";
const std::string indexAlbumIdReq = "CREATE INDEX IF NOT EXISTS album_track_album_genre_artist_ids "
"ON " + policy::AlbumTrackTable::Name + "(album_id, genre_id, artist_id)";
"ON " + AlbumTrack::Table::Name + "(album_id, genre_id, artist_id)";
sqlite::Tools::executeRequest( dbConnection, req );
sqlite::Tools::executeRequest( dbConnection, indexAlbumIdReq );
}
......@@ -121,14 +121,14 @@ void AlbumTrack::createTriggers(sqlite::Connection* dbConnection)
{
const std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS is_track_present "
"AFTER UPDATE OF is_present "
"ON " + policy::MediaTable::Name + " "
"ON " + Media::Table::Name + " "
"BEGIN "
"UPDATE " + policy::AlbumTrackTable::Name + " "
"UPDATE " + AlbumTrack::Table::Name + " "
"SET is_present = new.is_present WHERE media_id = new.id_media;"
"END";
const std::string indexReq = "CREATE INDEX IF NOT EXISTS "
"album_media_artist_genre_album_idx ON " +
policy::AlbumTrackTable::Name +
AlbumTrack::Table::Name +
"(media_id, artist_id, genre_id, album_id)";
sqlite::Tools::executeRequest( dbConnection, triggerReq );
sqlite::Tools::executeRequest( dbConnection, indexReq );
......@@ -140,7 +140,7 @@ std::shared_ptr<AlbumTrack> AlbumTrack::create( MediaLibraryPtr ml, int64_t albu
int64_t duration )
{
auto self = std::make_shared<AlbumTrack>( ml, media->id(), artistId, genreId, trackNb, albumId, discNumber );
static const std::string req = "INSERT INTO " + policy::AlbumTrackTable::Name
static const std::string req = "INSERT INTO " + AlbumTrack::Table::Name
+ "(media_id, duration, artist_id, genre_id, track_number, album_id, disc_number) VALUES(?, ?, ?, ?, ?, ?, ?)";
if ( insert( ml, self, req, media->id(), duration >= 0 ? duration : 0, sqlite::ForeignKey( artistId ),
sqlite::ForeignKey( genreId ), trackNb, albumId, discNumber ) == false )
......@@ -150,15 +150,15 @@ std::shared_ptr<AlbumTrack> AlbumTrack::create( MediaLibraryPtr ml, int64_t albu
AlbumTrackPtr AlbumTrack::fromMedia( MediaLibraryPtr ml, int64_t mediaId )
{
static const std::string req = "SELECT * FROM " + policy::AlbumTrackTable::Name +
static const std::string req = "SELECT * FROM " + AlbumTrack::Table::Name +
" WHERE media_id = ?";
return fetch( ml, req, mediaId );
}
Query<IMedia> AlbumTrack::fromGenre( MediaLibraryPtr ml, int64_t genreId, const QueryParameters* params )
{
std::string req = "FROM " + policy::MediaTable::Name + " m"
" INNER JOIN " + policy::AlbumTrackTable::Name + " t ON m.id_media = t.media_id"
std::string req = "FROM " + Media::Table::Name + " m"
" INNER JOIN " + AlbumTrack::Table::Name + " t ON m.id_media = t.media_id"
" WHERE t.genre_id = ? AND m.is_present = 1";
std::string orderBy = "ORDER BY ";
auto sort = params != nullptr ? params->sort : SortingCriteria::Default;
......@@ -216,7 +216,7 @@ bool AlbumTrack::setGenre( std::shared_ptr<Genre> genre )
if ( m_genre.isCached() == false )
m_genre = Genre::fetch( m_ml, m_genreId );
}
static const std::string req = "UPDATE " + policy::AlbumTrackTable::Name
static const std::string req = "UPDATE " + AlbumTrack::Table::Name
+ " SET genre_id = ? WHERE id_track = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req,
sqlite::ForeignKey( genre != nullptr ? genre->id() : 0 ),
......
......@@ -41,19 +41,15 @@ class Artist;
class Media;
class Genre;
namespace policy
{
struct AlbumTrackTable
{
static const std::string Name;
static const std::string PrimaryKeyColumn;
static int64_t AlbumTrack::*const PrimaryKey;
};
}
class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack, policy::AlbumTrackTable>
class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack>
{
public:
struct Table
{
static const std::string Name;
static const std::string PrimaryKeyColumn;
static int64_t AlbumTrack::*const PrimaryKey;
};
AlbumTrack( MediaLibraryPtr ml, sqlite::Row& row );
AlbumTrack( MediaLibraryPtr ml, int64_t mediaId, int64_t artistId, int64_t genreId,
unsigned int trackNumber, int64_t albumId, unsigned int discNumber );
......@@ -93,7 +89,7 @@ class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack, policy
mutable Cache<std::shared_ptr<Artist>> m_artist;
mutable Cache<std::shared_ptr<Genre>> m_genre;
friend struct policy::AlbumTrackTable;
friend struct AlbumTrack::Table;
};
}
......
......@@ -35,9 +35,9 @@
namespace medialibrary
{
const std::string policy::ArtistTable::Name = "Artist";
const std::string policy::ArtistTable::PrimaryKeyColumn = "id_artist";
int64_t Artist::*const policy::ArtistTable::PrimaryKey = &Artist::m_id;
const std::string Artist::Table::Name = "Artist";
const std::string Artist::Table::PrimaryKeyColumn = "id_artist";
int64_t Artist::*const Artist::Table::PrimaryKey = &Artist::m_id;
Artist::Artist( MediaLibraryPtr ml, sqlite::Row& row )
: m_ml( ml )
......@@ -80,7 +80,7 @@ const std::string& Artist::shortBio() const
bool Artist::setShortBio(const std::string& shortBio)
{
static const std::string req = "UPDATE " + policy::ArtistTable::Name
static const std::string req = "UPDATE " + Artist::Table::Name
+ " SET shortbio = ? WHERE id_artist = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, shortBio, m_id ) == false )
return false;
......@@ -101,7 +101,7 @@ Query<IAlbum> Artist::searchAlbums( const std::string& pattern,
Query<IMedia> Artist::tracks( const QueryParameters* params ) const
{
std::string req = "FROM " + policy::MediaTable::Name + " med ";
std::string req = "FROM " + Media::Table::Name + " med ";
SortingCriteria sort = params != nullptr ? params->sort : SortingCriteria::Default;
bool desc = params != nullptr ? params->desc : false;
......@@ -210,7 +210,7 @@ bool Artist::setArtworkMrl( const std::string& artworkMrl, Thumbnail::Origin ori
m_thumbnail = Thumbnail::create( m_ml, artworkMrl, Thumbnail::Origin::Artist );
if ( m_thumbnail.get() == nullptr )
return false;
static const std::string req = "UPDATE " + policy::ArtistTable::Name +
static const std::string req = "UPDATE " + Artist::Table::Name +
" SET thumbnail_id = ? WHERE id_artist = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, m_thumbnail.get()->id(), m_id ) == false )
return false;
......@@ -225,7 +225,7 @@ bool Artist::updateNbAlbum( int increment )
assert( increment != 0 );
assert( increment > 0 || ( increment < 0 && m_nbAlbums >= 1 ) );
static const std::string req = "UPDATE " + policy::ArtistTable::Name +
static const std::string req = "UPDATE " + Artist::Table::Name +
" SET nb_albums = nb_albums + ? WHERE id_artist = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, increment, m_id ) == false )
return false;
......@@ -237,7 +237,7 @@ bool Artist::updateNbTrack(int increment)
{
assert( increment != 0 );
assert( increment > 0 || ( increment < 0 && m_nbTracks >= 1 ) );
static const std::string req = "UPDATE " + policy::ArtistTable::Name +
static const std::string req = "UPDATE " + Artist::Table::Name +
" SET nb_tracks = nb_tracks + ? WHERE id_artist = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, increment, m_id ) == false )
return false;
......@@ -247,7 +247,7 @@ bool Artist::updateNbTrack(int increment)
std::shared_ptr<Album> Artist::unknownAlbum()
{
static const std::string req = "SELECT * FROM " + policy::AlbumTable::Name +
static const std::string req = "SELECT * FROM " + Album::Table::Name +
" WHERE artist_id = ? AND title IS NULL";
auto album = Album::fetch( m_ml, req, m_id );
if ( album == nullptr )
......@@ -271,7 +271,7 @@ const std::string& Artist::musicBrainzId() const
bool Artist::setMusicBrainzId( const std::string& mbId )
{
static const std::string req = "UPDATE " + policy::ArtistTable::Name
static const std::string req = "UPDATE " + Artist::Table::Name
+ " SET mb_id = ? WHERE id_artist = ?";
if ( mbId == m_mbId )
return true;
......@@ -294,7 +294,7 @@ unsigned int Artist::nbTracks() const
void Artist::createTable( sqlite::Connection* dbConnection )
{
const std::string req = "CREATE TABLE IF NOT EXISTS " +
policy::ArtistTable::Name +
Artist::Table::Name +
"("
"id_artist INTEGER PRIMARY KEY AUTOINCREMENT,"
"name TEXT COLLATE NOCASE UNIQUE ON CONFLICT FAIL,"
......@@ -304,20 +304,20 @@ void Artist::createTable( sqlite::Connection* dbConnection )
"nb_tracks UNSIGNED INT DEFAULT 0,"
"mb_id TEXT,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"FOREIGN KEY(thumbnail_id) REFERENCES " + policy::ThumbnailTable::Name
"FOREIGN KEY(thumbnail_id) REFERENCES " + Thumbnail::Table::Name
+ "(id_thumbnail)"
")";
const std::string reqRel = "CREATE TABLE IF NOT EXISTS MediaArtistRelation("
"media_id INTEGER NOT NULL,"
"artist_id INTEGER,"
"PRIMARY KEY (media_id, artist_id),"
"FOREIGN KEY(media_id) REFERENCES " + policy::MediaTable::Name +
"FOREIGN KEY(media_id) REFERENCES " + Media::Table::Name +
"(id_media) ON DELETE CASCADE,"
"FOREIGN KEY(artist_id) REFERENCES " + policy::ArtistTable::Name + "("
+ policy::ArtistTable::PrimaryKeyColumn + ") ON DELETE CASCADE"
"FOREIGN KEY(artist_id) REFERENCES " + Artist::Table::Name + "("
+ Artist::Table::PrimaryKeyColumn + ") ON DELETE CASCADE"
")";
const std::string reqFts = "CREATE VIRTUAL TABLE IF NOT EXISTS " +
policy::ArtistTable::Name + "Fts USING FTS3("
Artist::Table::Name + "Fts USING FTS3("
"name"
")";
sqlite::Tools::executeRequest( dbConnection, req );
......@@ -328,11 +328,11 @@ void Artist::createTable( sqlite::Connection* dbConnection )
void Artist::createTriggers( sqlite::Connection* dbConnection, uint32_t dbModelVersion )
{
static const std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS has_album_present AFTER UPDATE OF "
"is_present ON " + policy::AlbumTable::Name +
"is_present ON " + Album::Table::Name +
" BEGIN "
" UPDATE " + policy::ArtistTable::Name + " SET is_present="
" UPDATE " + Artist::Table::Name + " SET is_present="
"(SELECT EXISTS("
"SELECT id_album FROM " + policy::AlbumTable::Name +
"SELECT id_album FROM " + Album::Table::Name +
" WHERE artist_id=new.artist_id AND is_present != 0 LIMIT 1"
") )"
"WHERE id_artist=new.artist_id;"
......@@ -343,10 +343,10 @@ void Artist::createTriggers( sqlite::Connection* dbConnection, uint32_t dbModelV
// The alternative would be to always check the special artists for existence, which would be much
// slower when inserting an unknown artist album
static const std::string autoDeleteAlbumTriggerReq = "CREATE TRIGGER IF NOT EXISTS has_album_remaining"
" AFTER DELETE ON " + policy::AlbumTable::Name +
" AFTER DELETE ON " + Album::Table::Name +
" BEGIN"
" UPDATE " + policy::ArtistTable::Name + " SET nb_albums = nb_albums - 1 WHERE id_artist = old.artist_id;"
" DELETE FROM " + policy::ArtistTable::Name + " WHERE id_artist = old.artist_id "
" UPDATE " + Artist::Table::Name + " SET nb_albums = nb_albums - 1 WHERE id_artist = old.artist_id;"
" DELETE FROM " + Artist::Table::Name + " WHERE id_artist = old.artist_id "
" AND nb_albums = 0 "
" AND nb_tracks = 0 "
" AND old.artist_id != " + std::to_string( UnknownArtistID ) +
......@@ -354,10 +354,10 @@ void Artist::createTriggers( sqlite::Connection* dbConnection, uint32_t dbModelV
" END";
static const std::string autoDeleteTrackTriggerReq = "CREATE TRIGGER IF NOT EXISTS has_track_remaining"
" AFTER DELETE ON " + policy::AlbumTrackTable::Name +
" AFTER DELETE ON " + AlbumTrack::Table::Name +
" BEGIN"
" UPDATE " + policy::ArtistTable::Name + " SET nb_tracks = nb_tracks - 1 WHERE id_artist = old.artist_id;"
" DELETE FROM " + policy::ArtistTable::Name + " WHERE id_artist = old.artist_id "
" UPDATE " + Artist::Table::Name + " SET nb_tracks = nb_tracks - 1 WHERE id_artist = old.artist_id;"
" DELETE FROM " + Artist::Table::Name + " WHERE id_artist = old.artist_id "
" AND nb_albums = 0 "
" AND nb_tracks = 0 "
" AND old.artist_id != " + std::to_string( UnknownArtistID ) +
......@@ -365,16 +365,16 @@ void Artist::createTriggers( sqlite::Connection* dbConnection, uint32_t dbModelV
" END";
static const std::string ftsInsertTrigger = "CREATE TRIGGER IF NOT EXISTS insert_artist_fts"
" AFTER INSERT ON " + policy::ArtistTable::Name +
" AFTER INSERT ON " + Artist::Table::Name +
" WHEN new.name IS NOT NULL"
" BEGIN"
" INSERT INTO " + policy::ArtistTable::Name + "Fts(rowid,name) VALUES(new.id_artist, new.name);"
" INSERT INTO " + Artist::Table::Name + "Fts(rowid,name) VALUES(new.id_artist, new.name);"
" END";
static const std::string ftsDeleteTrigger = "CREATE TRIGGER IF NOT EXISTS delete_artist_fts"
" BEFORE DELETE ON " + policy::ArtistTable::Name +
" BEFORE DELETE ON " + Artist::Table::Name +
" WHEN old.name IS NOT NULL"
" BEGIN"
" DELETE FROM " + policy::ArtistTable::Name + "Fts WHERE rowid=old.id_artist;"
" DELETE FROM " + Artist::Table::Name + "Fts WHERE rowid=old.id_artist;"
" END";
sqlite::Tools::executeRequest( dbConnection, triggerReq );
sqlite::Tools::executeRequest( dbConnection, autoDeleteAlbumTriggerReq );
......@@ -397,7 +397,7 @@ bool Artist::createDefaultArtists( sqlite::Connection* dbConnection )
{
// Don't rely on Artist::create, since we want to insert or do nothing here.
// This will skip the cache for those new entities, but they will be inserted soon enough anyway.
static const std::string req = "INSERT OR IGNORE INTO " + policy::ArtistTable::Name +
static const std::string req = "INSERT OR IGNORE INTO " + Artist::Table::Name +
"(id_artist) VALUES(?),(?)";
sqlite::Tools::executeInsert( dbConnection, req, UnknownArtistID,
VariousArtistID );
......@@ -409,7 +409,7 @@ bool Artist::createDefaultArtists( sqlite::Connection* dbConnection )
std::shared_ptr<Artist> Artist::create( MediaLibraryPtr ml, const std::string& name )
{
auto artist = std::make_shared<Artist>( ml, name );
static const std::string req = "INSERT INTO " + policy::ArtistTable::Name +
static const std::string req = "INSERT INTO " + Artist::Table::Name +
"(id_artist, name) VALUES(NULL, ?)";
if ( insert( ml, artist, req, name ) == false )
return nullptr;
......@@ -419,8 +419,8 @@ std::shared_ptr<Artist> Artist::create( MediaLibraryPtr ml, const std::string& n
Query<IArtist> Artist::search( MediaLibraryPtr ml, const std::string& name,
const QueryParameters* params )
{
std::string req = "FROM " + policy::ArtistTable::Name + " WHERE id_artist IN "
"(SELECT rowid FROM " + policy::ArtistTable::Name + "Fts WHERE name MATCH '*' || ? || '*')"
std::string req = "FROM " + Artist::Table::Name + " WHERE id_artist IN "
"(SELECT rowid FROM " + Artist::Table::Name + "Fts WHERE name MATCH '*' || ? || '*')"
"AND is_present != 0";
return make_query<Artist, IArtist>( ml, "*", std::move( req ),
sortRequest( params ), name );
......@@ -429,7 +429,7 @@ Query<IArtist> Artist::search( MediaLibraryPtr ml, const std::string& name,
Query<IArtist> Artist::listAll( MediaLibraryPtr ml, bool includeAll,
const QueryParameters* params )
{
std::string req = "FROM " + policy::ArtistTable::Name + " WHERE ";
std::string req = "FROM " + Artist::Table::Name + " WHERE ";
if ( includeAll == true )
req += "( nb_albums > 0 OR nb_tracks > 0 )";
else
......@@ -443,10 +443,10 @@ Query<IArtist> Artist::listAll( MediaLibraryPtr ml, bool includeAll,
Query<IArtist> Artist::searchByGenre( MediaLibraryPtr ml, const std::string& pattern,
const QueryParameters* params, int64_t genreId )
{
std::string req = "FROM " + policy::ArtistTable::Name + " a "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.artist_id = a.id_artist "
std::string req = "FROM " + Artist::Table::Name + " a "
"INNER JOIN " + AlbumTrack::Table::Name + " att ON att.artist_id = a.id_artist "
"WHERE id_artist IN "
"(SELECT rowid FROM " + policy::ArtistTable::Name + "Fts WHERE name MATCH '*' || ? || '*')"
"(SELECT rowid FROM " + Artist::Table::Name + "Fts WHERE name MATCH '*' || ? || '*')"
"AND att.genre_id = ? ";
std::string groupBy = "GROUP BY att.artist_id "
......
......@@ -35,19 +35,15 @@ class Artist;
class Album;
class Media;
namespace policy
{