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

Add request pagination support

All request that could return more than one row (ie. all member function
that used to return an std::vector<std::shared_ptr<T>> will now return a std::unique_ptr<Query<T>>
The query object can return:
- The amount of row represented by that query (->count())
- A subset of the rows (->items(count, offset))
- All rows (->all())
parent 2f6cf433
......@@ -22,7 +22,6 @@
#pragma once
#include <vector>
#include <string>
#include "IMediaLibrary.h"
......@@ -45,23 +44,24 @@ public:
/**
* @brief tracks fetches album tracks from the database
*/
virtual std::vector<MediaPtr> tracks( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> tracks( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
/**
* @brief tracks fetches album tracks, filtered by genre
* @param genre A musical genre. Only tracks of this genre will be returned
* @return
*/
virtual std::vector<MediaPtr> tracks( GenrePtr genre, SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> tracks( GenrePtr genre, SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
/**
* @brief albumArtist Returns the album main artist (generally tagged as album-artist)
*/
virtual ArtistPtr albumArtist() const = 0;
/**
* @brief artists Returns a vector of all additional artists appearing on the album.
* @brief artists Returns a Query object representing all additional
* artists appearing on the album.
* Artists are sorted by name.
* @param desc
*/
virtual std::vector<ArtistPtr> artists( bool desc ) const = 0;
virtual Query<IArtist> artists( bool desc ) const = 0;
/**
* @brief nbTracks Returns the amount of track in this album.
* The value is cached, and doesn't require fetching anything.
......
......@@ -23,7 +23,6 @@
#pragma once
#include <string>
#include <vector>
#include "IMediaLibrary.h"
......@@ -43,8 +42,8 @@ public:
* This will return all albums by this artist, and all album the artist
* appeared on, even if they are not the main artist (or AlbumArtist)
*/
virtual std::vector<AlbumPtr> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual std::vector<MediaPtr> media( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IAlbum> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> media( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual const std::string& artworkMrl() const = 0;
virtual const std::string& musicBrainzId() const = 0;
/**
......
......@@ -24,8 +24,6 @@
#include "IMediaLibrary.h"
#include <vector>
namespace medialibrary
{
......@@ -36,9 +34,9 @@ public:
virtual int64_t id() const = 0;
virtual const std::string& name() const = 0;
virtual uint32_t nbTracks() const = 0;
virtual std::vector<ArtistPtr> artists( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual std::vector<MediaPtr> tracks( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual std::vector<AlbumPtr> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IArtist> artists( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> tracks( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IAlbum> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
};
}
......@@ -38,7 +38,7 @@ class ILabel
virtual int64_t id() const = 0;
virtual const std::string& name() const = 0;
virtual std::vector<MediaPtr> files() = 0;
virtual Query<IMedia> files() = 0;
};
}
......
......@@ -117,9 +117,9 @@ class IMedia
virtual bool addLabel( LabelPtr label ) = 0;
virtual bool removeLabel( LabelPtr label ) = 0;
virtual MoviePtr movie() const = 0;
virtual std::vector<LabelPtr> labels() = 0;
virtual std::vector<VideoTrackPtr> videoTracks() = 0;
virtual std::vector<AudioTrackPtr> audioTracks() = 0;
virtual Query<ILabel> labels() = 0;
virtual Query<IVideoTrack> videoTracks() = 0;
virtual Query<IAudioTrack> audioTracks() = 0;
///
/// \brief thumbnail Returns the path of a thumbnail for this media
/// \return A path, relative to the thumbnailPath configured when initializing
......
......@@ -28,6 +28,7 @@
#include "medialibrary/ILogger.h"
#include "Types.h"
#include "IQuery.h"
namespace medialibrary
{
......@@ -37,19 +38,19 @@ static constexpr auto VariousArtistID = 2u;
struct MediaSearchAggregate
{
std::vector<MediaPtr> episodes;
std::vector<MediaPtr> movies;
std::vector<MediaPtr> others;
std::vector<MediaPtr> tracks;
Query<IMedia> episodes;
Query<IMedia> movies;
Query<IMedia> others;
Query<IMedia> tracks;
};
struct SearchAggregate
{
std::vector<AlbumPtr> albums;
std::vector<ArtistPtr> artists;
std::vector<GenrePtr> genres;
Query<IAlbum> albums;
Query<IArtist> artists;
Query<IGenre> genres;
MediaSearchAggregate media;
std::vector<PlaylistPtr> playlists;
Query<IPlaylist> playlists;
};
enum class SortingCriteria
......@@ -251,10 +252,10 @@ class IMediaLibrary
virtual MediaPtr media( int64_t mediaId ) const = 0;
virtual MediaPtr media( const std::string& mrl ) const = 0;
virtual MediaPtr addMedia( const std::string& mrl ) = 0;
virtual std::vector<MediaPtr> audioFiles( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual std::vector<MediaPtr> videoFiles( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> audioFiles( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IMedia> videoFiles( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual AlbumPtr album( int64_t id ) const = 0;
virtual std::vector<AlbumPtr> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IAlbum> albums( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual ShowPtr show( const std::string& name ) const = 0;
virtual MoviePtr movie( const std::string& title ) const = 0;
virtual ArtistPtr artist( int64_t id ) const = 0;
......@@ -268,7 +269,7 @@ class IMediaLibrary
* @param sort A sorting criteria. So far, this is ignored, and artists are sorted by lexial order
* @param desc If true, the provided sorting criteria will be reversed.
*/
virtual std::vector<ArtistPtr> artists( bool includeAll,
virtual Query<IArtist> artists( bool includeAll,
SortingCriteria sort = SortingCriteria::Default,
bool desc = false ) const = 0;
/**
......@@ -276,13 +277,13 @@ class IMediaLibrary
* @param sort A sorting criteria. So far, this is ignored, and artists are sorted by lexial order
* @param desc If true, the provided sorting criteria will be reversed.
*/
virtual std::vector<GenrePtr> genres( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual Query<IGenre> genres( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) const = 0;
virtual GenrePtr genre( int64_t id ) const = 0;
/***
* Playlists
*/
virtual PlaylistPtr createPlaylist( const std::string& name ) = 0;
virtual std::vector<PlaylistPtr> playlists( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) = 0;
virtual Query<IPlaylist> playlists( SortingCriteria sort = SortingCriteria::Default, bool desc = false ) = 0;
virtual PlaylistPtr playlist( int64_t id ) const = 0;
virtual bool deletePlaylist( int64_t playlistId ) = 0;
......@@ -290,8 +291,8 @@ class IMediaLibrary
* History
*/
virtual bool addToStreamHistory( MediaPtr media ) = 0;
virtual std::vector<HistoryPtr> lastStreamsPlayed() const = 0;
virtual std::vector<MediaPtr> lastMediaPlayed() const = 0;
virtual Query<IHistoryEntry> lastStreamsPlayed() const = 0;
virtual Query<IMedia> lastMediaPlayed() const = 0;
/**
* @brief clearHistory will clear both streams history & media history.
* @return true in case of success, false otherwise. The database will stay untouched in case
......@@ -308,14 +309,14 @@ class IMediaLibrary
virtual MediaSearchAggregate searchMedia( const std::string& pattern,
SortingCriteria sort = SortingCriteria::Default,
bool desc = false ) const = 0;
virtual std::vector<PlaylistPtr> searchPlaylists( const std::string& name,
virtual Query<IPlaylist> searchPlaylists( const std::string& name,
SortingCriteria sort = SortingCriteria::Default,
bool desc = false ) const = 0;
virtual std::vector<AlbumPtr> searchAlbums( const std::string& pattern,
virtual Query<IAlbum> searchAlbums( const std::string& pattern,
SortingCriteria sort = SortingCriteria::Default,
bool desc = false ) const = 0;
virtual std::vector<GenrePtr> searchGenre( const std::string& genre ) const = 0;
virtual std::vector<ArtistPtr> searchArtists( const std::string& name,
virtual Query<IGenre> searchGenre( const std::string& genre ) const = 0;
virtual Query<IArtist> searchArtists( const std::string& name,
SortingCriteria sort = SortingCriteria::Default,
bool desc = false ) const = 0;
virtual SearchAggregate search( const std::string& pattern,
......@@ -331,7 +332,7 @@ class IMediaLibrary
*/
virtual void discover( const std::string& entryPoint ) = 0;
virtual void setDiscoverNetworkEnabled( bool enable ) = 0;
virtual std::vector<FolderPtr> entryPoints() const = 0;
virtual Query<IFolder> entryPoints() const = 0;
virtual FolderPtr folder( const std::string& mrl ) const = 0;
virtual void removeEntryPoint( const std::string& entryPoint ) = 0;
/**
......
......@@ -37,7 +37,7 @@ class IMovie
virtual const std::string& shortSummary() const = 0;
virtual const std::string& artworkMrl() const = 0;
virtual const std::string& imdbId() const = 0;
virtual std::vector<MediaPtr> files() = 0;
virtual Query<IMedia> files() = 0;
};
}
......
......@@ -22,9 +22,8 @@
#pragma once
#include <vector>
#include "Types.h"
#include "IQuery.h"
namespace medialibrary
{
......@@ -38,7 +37,7 @@ public:
virtual bool setName( const std::string& name ) = 0;
virtual unsigned int creationDate() const = 0;
virtual const std::string& artworkMrl() const = 0;
virtual std::vector<MediaPtr> media() const = 0;
virtual Query<IMedia> media() const = 0;
///
/// \brief append Appends a media to a playlist
/// The media will be the last element of a subsequent call to media()
......
......@@ -38,7 +38,7 @@ class IShow
virtual const std::string& shortSummary() const = 0;
virtual const std::string& artworkMrl() const = 0;
virtual const std::string& tvdbId() = 0;
virtual std::vector<ShowEpisodePtr> episodes() = 0;
virtual Query<IShowEpisode> episodes() = 0;
};
}
......
......@@ -41,7 +41,7 @@ class IShowEpisode
virtual const std::string& shortSummary() const = 0;
virtual const std::string& tvdbId() const = 0;
virtual std::shared_ptr<IShow> show() = 0;
virtual std::vector<MediaPtr> files() = 0;
virtual Query<IMedia> files() = 0;
};
}
......
......@@ -34,6 +34,7 @@
#include "Thumbnail.h"
#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"
namespace medialibrary
{
......@@ -246,34 +247,34 @@ std::string Album::orderBy( SortingCriteria sort, bool desc )
return req;
}
std::vector<MediaPtr> Album::tracks( SortingCriteria sort, bool desc ) const
Query<IMedia> Album::tracks( SortingCriteria sort, bool desc ) 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 = "SELECT med.* FROM " + policy::MediaTable::Name + " med "
std::string req = "FROM " + policy::MediaTable::Name + " med "
" INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.media_id = med.id_media "
" WHERE att.album_id = ? AND med.is_present != 0";
req += orderTracksBy( sort, desc );
return Media::fetchAll<IMedia>( m_ml, req, m_id );
return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ), m_id );
}
std::vector<MediaPtr> Album::tracks( GenrePtr genre, SortingCriteria sort, bool desc ) const
Query<IMedia> Album::tracks( GenrePtr genre, SortingCriteria sort, bool desc ) const
{
if ( genre == nullptr )
return {};
std::string req = "SELECT med.* FROM " + policy::MediaTable::Name + " med "
std::string req = "FROM " + policy::MediaTable::Name + " med "
" INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.media_id = med.id_media "
" WHERE att.album_id = ? AND med.is_present != 0"
" AND genre_id = ?";
req += orderTracksBy( sort, desc );
return Media::fetchAll<IMedia>( m_ml, req, m_id, genre->id() );
return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ), m_id, genre->id() );
}
std::vector<MediaPtr> Album::cachedTracks() const
{
auto lock = m_tracks.lock();
if ( m_tracks.isCached() == false )
m_tracks = tracks( SortingCriteria::Default, false );
m_tracks = tracks( SortingCriteria::Default, false )->all();
return m_tracks.get();
}
......@@ -349,14 +350,14 @@ bool Album::setAlbumArtist( std::shared_ptr<Artist> artist )
return true;
}
std::vector<ArtistPtr> Album::artists( bool desc ) const
Query<IArtist> Album::artists( bool desc ) const
{
std::string req = "SELECT art.* FROM " + policy::ArtistTable::Name + " art "
std::string req = "FROM " + policy::ArtistTable::Name + " art "
"INNER JOIN AlbumArtistRelation aar ON aar.artist_id = art.id_artist "
"WHERE aar.album_id = ? ORDER BY art.name";
if ( desc == true )
req += " DESC";
return Artist::fetchAll<IArtist>( m_ml, req, m_id );
return make_query<Artist, IArtist>( m_ml, "art.*", std::move( req ), m_id );
}
bool Album::addArtist( std::shared_ptr<Artist> artist )
......@@ -491,21 +492,21 @@ std::shared_ptr<Album> Album::createUnknownAlbum( MediaLibraryPtr ml, const Arti
return album;
}
std::vector<AlbumPtr> Album::search( MediaLibraryPtr ml, const std::string& pattern,
Query<IAlbum> Album::search( MediaLibraryPtr ml, const std::string& pattern,
SortingCriteria sort, bool desc )
{
std::string req = "SELECT * FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"WHERE id_album IN "
"(SELECT rowid FROM " + policy::AlbumTable::Name + "Fts WHERE " +
policy::AlbumTable::Name + "Fts MATCH '*' || ? || '*')"
"AND is_present != 0";
req += orderBy( sort, desc );
return fetchAll<IAlbum>( ml, req, pattern );
return make_query<Album, IAlbum>( ml, "*", std::move( req ), pattern );
}
std::vector<AlbumPtr> Album::fromArtist( MediaLibraryPtr ml, int64_t artistId, SortingCriteria sort, bool desc )
Query<IAlbum> Album::fromArtist( MediaLibraryPtr ml, int64_t artistId, SortingCriteria sort, bool desc )
{
std::string req = "SELECT * FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att "
"ON att.album_id = alb.id_album "
"WHERE (att.artist_id = ? OR alb.artist_id = ?) "
......@@ -529,34 +530,34 @@ std::vector<AlbumPtr> Album::fromArtist( MediaLibraryPtr ml, int64_t artistId, S
break;
}
return fetchAll<IAlbum>( ml, req, artistId, artistId );
return make_query<Album, IAlbum>( ml, "*", req, artistId, artistId );
}
std::vector<AlbumPtr> Album::fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc)
Query<IAlbum> Album::fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc)
{
std::string req = "SELECT alb.* FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.album_id = alb.id_album "
"WHERE att.genre_id = ? GROUP BY att.album_id";
req += orderBy( sort, desc );
return fetchAll<IAlbum>( ml, req, genreId );
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ), genreId );
}
std::vector<AlbumPtr> Album::listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc )
Query<IAlbum> Album::listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc )
{
if ( sort == SortingCriteria::Artist )
{
std::string req = "SELECT alb.* FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
"INNER JOIN " + policy::ArtistTable::Name + " art ON alb.artist_id = art.id_artist "
"WHERE alb.is_present != 0 "
"ORDER BY art.name ";
if ( desc == true )
req += "DESC ";
req += ", alb.title";
return fetchAll<IAlbum>( ml, req );
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ) );
}
if ( sort == SortingCriteria::PlayCount )
{
std::string req = "SELECT alb.* FROM " + policy::AlbumTable::Name + " alb "
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 "
"WHERE alb.is_present != 0 "
......@@ -565,12 +566,12 @@ std::vector<AlbumPtr> Album::listAll( MediaLibraryPtr ml, SortingCriteria sort,
if ( desc == false )
req += "DESC "; // Most played first by default
req += ", alb.title";
return fetchAll<IAlbum>( ml, req );
return make_query<Album, IAlbum>( ml, "alb.*", std::move( req ) );
}
std::string req = "SELECT * FROM " + policy::AlbumTable::Name + " alb "
std::string req = "FROM " + policy::AlbumTable::Name + " alb "
" WHERE is_present != 0";
req += orderBy( sort, desc );
return fetchAll<IAlbum>( ml, req );
return make_query<Album, IAlbum>( ml, "*", std::move( req ) );
}
}
......@@ -76,8 +76,8 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
virtual const std::string& artworkMrl() const override;
std::shared_ptr<Thumbnail> thumbnail();
bool setArtworkMrl( const std::string& artworkMrl, Thumbnail::Origin origin );
virtual std::vector<MediaPtr> tracks( SortingCriteria sort, bool desc ) const override;
virtual std::vector<MediaPtr> tracks( GenrePtr genre, SortingCriteria sort, bool desc ) const override;
virtual Query<IMedia> tracks( SortingCriteria sort, bool desc ) const override;
virtual Query<IMedia> tracks( GenrePtr genre, SortingCriteria sort, bool desc ) const override;
///
/// \brief cachedTracks Returns a cached list of tracks
/// This has no warranty of ordering, validity, or anything else.
......@@ -96,7 +96,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
virtual ArtistPtr albumArtist() const override;
bool setAlbumArtist( std::shared_ptr<Artist> artist );
virtual std::vector<ArtistPtr> artists(bool desc) const override;
virtual Query<IArtist> artists(bool desc) const override;
bool addArtist( std::shared_ptr<Artist> artist );
bool removeArtist( Artist* artist );
......@@ -109,11 +109,11 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
/// \param pattern A pattern representing the title, or the name of the main artist
/// \return
///
static std::vector<AlbumPtr> search( MediaLibraryPtr ml, const std::string& pattern,
static Query<IAlbum> search( MediaLibraryPtr ml, const std::string& pattern,
SortingCriteria sort, bool desc );
static std::vector<AlbumPtr> fromArtist( MediaLibraryPtr ml, int64_t artistId, SortingCriteria sort, bool desc );
static std::vector<AlbumPtr> fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc );
static std::vector<AlbumPtr> listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc );
static Query<IAlbum> fromArtist( MediaLibraryPtr ml, int64_t artistId, SortingCriteria sort, bool desc );
static Query<IAlbum> fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc );
static Query<IAlbum> listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc );
private:
static std::string orderTracksBy( SortingCriteria sort, bool desc );
......
......@@ -30,6 +30,7 @@
#include "Media.h"
#include "Genre.h"
#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"
#include "logging/Logger.h"
namespace medialibrary
......@@ -148,9 +149,9 @@ AlbumTrackPtr AlbumTrack::fromMedia( MediaLibraryPtr ml, int64_t mediaId )
return fetch( ml, req, mediaId );
}
std::vector<MediaPtr> AlbumTrack::fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc )
Query<IMedia> AlbumTrack::fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc )
{
std::string req = "SELECT m.* FROM " + policy::MediaTable::Name + " m"
std::string req = "FROM " + policy::MediaTable::Name + " m"
" INNER JOIN " + policy::AlbumTrackTable::Name + " t ON m.id_media = t.media_id"
" WHERE t.genre_id = ? AND m.is_present = 1 ORDER BY ";
switch ( sort )
......@@ -177,7 +178,7 @@ std::vector<MediaPtr> AlbumTrack::fromGenre( MediaLibraryPtr ml, int64_t genreId
if ( desc == true )
req += " DESC";
return Media::fetchAll<IMedia>( ml, req, genreId );
return make_query<Media, IMedia>( ml, "m.*", std::move( req ), genreId );
}
GenrePtr AlbumTrack::genre()
......
......@@ -74,7 +74,7 @@ class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack, policy
unsigned int discNumber, int64_t artistId, int64_t genreId,
int64_t duration );
static AlbumTrackPtr fromMedia( MediaLibraryPtr ml, int64_t mediaId );
static std::vector<MediaPtr> fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc );
static Query<IMedia> fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc );
private:
MediaLibraryPtr m_ml;
......
......@@ -30,6 +30,7 @@
#include "Media.h"
#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"
namespace medialibrary
{
......@@ -87,14 +88,14 @@ bool Artist::setShortBio(const std::string& shortBio)
return true;
}
std::vector<AlbumPtr> Artist::albums( SortingCriteria sort, bool desc ) const
Query<IAlbum> Artist::albums( SortingCriteria sort, bool desc ) const
{
return Album::fromArtist( m_ml, m_id, sort, desc );
}
std::vector<MediaPtr> Artist::media( SortingCriteria sort, bool desc ) const
Query<IMedia> Artist::media( SortingCriteria sort, bool desc ) const
{
std::string req = "SELECT med.* FROM " + policy::MediaTable::Name + " med ";
std::string req = "FROM " + policy::MediaTable::Name + " med ";
// Various artist is a special artist that doesn't have tracks per-se.
// Rather, it's a virtual artist for albums with many artist but no declared
......@@ -139,7 +140,7 @@ std::vector<MediaPtr> Artist::media( SortingCriteria sort, bool desc ) const
if ( desc == true )
req += " DESC";
return Media::fetchAll<IMedia>( m_ml, req, m_id );
return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ), m_id );
}
bool Artist::addMedia( Media& media )
......@@ -400,20 +401,20 @@ std::shared_ptr<Artist> Artist::create( MediaLibraryPtr ml, const std::string& n
return artist;
}
std::vector<ArtistPtr> Artist::search( MediaLibraryPtr ml, const std::string& name,
Query<IArtist> Artist::search( MediaLibraryPtr ml, const std::string& name,
SortingCriteria sort, bool desc )
{
std::string req = "SELECT * FROM " + policy::ArtistTable::Name + " WHERE id_artist IN "
std::string req = "FROM " + policy::ArtistTable::Name + " WHERE id_artist IN "
"(SELECT rowid FROM " + policy::ArtistTable::Name + "Fts WHERE name MATCH '*' || ? || '*')"
"AND is_present != 0";
req += sortRequest( sort, desc );
return fetchAll<IArtist>( ml, req, name );
return make_query<Artist, IArtist>( ml, "*", std::move( req ), name );
}
std::vector<ArtistPtr> Artist::listAll( MediaLibraryPtr ml, bool includeAll,
Query<IArtist> Artist::listAll( MediaLibraryPtr ml, bool includeAll,
SortingCriteria sort, bool desc)
{
std::string req = "SELECT * FROM " + policy::ArtistTable::Name + " WHERE ";
std::string req = "FROM " + policy::ArtistTable::Name + " WHERE ";
if ( includeAll == true )
req += "( nb_albums > 0 OR nb_tracks > 0 )";
else
......@@ -421,7 +422,7 @@ std::vector<ArtistPtr> Artist::listAll( MediaLibraryPtr ml, bool includeAll,
req += " AND is_present != 0";
req += sortRequest( sort, desc );
return fetchAll<IArtist>( ml, req );
return make_query<Artist, IArtist>( ml, "*", std::move( req ) );
}
std::string Artist::sortRequest( SortingCriteria sort, bool desc )
......
......@@ -55,8 +55,8 @@ public:
virtual const std::string& name() const override;
virtual const std::string& shortBio() const override;
bool setShortBio( const std::string& shortBio );
virtual std::vector<AlbumPtr> albums( SortingCriteria sort, bool desc ) const override;
virtual std::vector<MediaPtr> media(SortingCriteria sort, bool desc) const override;
virtual Query<IAlbum> albums( SortingCriteria sort, bool desc ) const override;
virtual Query<IMedia> media(SortingCriteria sort, bool desc) const override;
bool addMedia( Media& media );
virtual const std::string& artworkMrl() const override;
std::shared_ptr<Thumbnail> thumbnail();
......@@ -73,9 +73,9 @@ public:
static void createTriggers( sqlite::Connection* dbConnection, uint32_t dbModelVersion );
static bool createDefaultArtists( sqlite::Connection* dbConnection );
static std::shared_ptr<Artist> create( MediaLibraryPtr ml, const std::string& name );
static std::vector<ArtistPtr> search( MediaLibraryPtr ml, const std::string& name,
static Query<IArtist> search( MediaLibraryPtr ml, const std::string& name,
SortingCriteria sort, bool desc );
static std::vector<ArtistPtr> listAll( MediaLibraryPtr ml, bool includeAll,
static Query<IArtist> listAll( MediaLibraryPtr ml, bool includeAll,
SortingCriteria sort, bool desc );
private:
......
......@@ -29,6 +29,7 @@
#include "Album.h"
#include "AlbumTrack.h"
#include "Artist.h"
#include "database/SqliteQuery.h"
namespace medialibrary
{
......@@ -76,23 +77,23 @@ void Genre::updateCachedNbTracks( int increment )
m_nbTracks += increment;
}
std::vector<ArtistPtr> Genre::artists( SortingCriteria, bool desc ) const
Query<IArtist> Genre::artists( SortingCriteria, bool desc ) const
{
std::string req = "SELECT a.* FROM " + policy::ArtistTable::Name + " a "
std::string req = "FROM " + policy::ArtistTable::Name + " a "
"INNER JOIN " + policy::AlbumTrackTable::Name + " att ON att.artist_id = a.id_artist "
"WHERE att.genre_id = ? GROUP BY att.artist_id"
" ORDER BY a.name";
if ( desc == true )
req += " DESC";
return Artist::fetchAll<IArtist>( m_ml, req, m_id );
return make_query<Artist, IArtist>( m_ml, "a.*", std::move( req ), m_id );
}
std::vector<MediaPtr> Genre::tracks( SortingCriteria sort, bool desc ) const
Query<IMedia> Genre::tracks( SortingCriteria sort, bool desc ) const
{
return AlbumTrack::fromGenre( m_ml, m_id, sort, desc );
}
std::vector<AlbumPtr> Genre::albums( SortingCriteria sort, bool desc ) const
Query<IAlbum> Genre::albums( SortingCriteria sort, bool desc ) const
{
return Album::fromGenre( m_ml, m_id, sort, desc );
}
......@@ -170,19 +171,19 @@ std::shared_ptr<Genre> Genre::fromName( MediaLibraryPtr ml, const std::string& n
return fetch( ml, req, name );
}
std::vector<GenrePtr> Genre::search( MediaLibraryPtr ml, const std::string& name )
Query<IGenre> Genre::search( MediaLibraryPtr ml, const std::string& name )
{
static const std::string req = "SELECT * FROM " + policy::GenreTable::Name + " WHERE id_genre IN "
static const std::string req = "FROM " + policy::GenreTable::Name + " WHERE id_genre IN "
"(SELECT rowid FROM " + policy::GenreTable::Name + "Fts WHERE name MATCH '*' || ? || '*')";
return fetchAll<IGenre>( ml, req, name );
return make_query<Genre, IGenre>( ml, "*", req, name );
}
std::vector<GenrePtr> Genre::listAll( MediaLibraryPtr ml, SortingCriteria, bool desc )
Query<IGenre> Genre::listAll( MediaLibraryPtr ml, SortingCriteria, bool desc )
{
std::string req = "SELECT * FROM " + policy::GenreTable::Name + " ORDER BY name";
std::string req = "FROM " + policy::GenreTable::Name + " ORDER BY name";
if ( desc == true )
req += " DESC";
return fetchAll<IGenre>( ml, req );
return make_query<Genre, IGenre>( ml, "*", std::move( req ) );
}
}
......@@ -50,16 +50,16 @@ public:
virtual const std::string& name() const override;
virtual uint32_t nbTracks() const override;
void updateCachedNbTracks( int increment );
virtual std::vector<ArtistPtr> artists( SortingCriteria sort, bool desc ) const override;
virtual std::vector<MediaPtr> tracks(SortingCriteria sort, bool desc) const override;
virtual std::vector<AlbumPtr> albums( SortingCriteria sort, bool desc ) const override;
virtual Query<IArtist> artists( SortingCriteria sort, bool desc ) const override;
virtual Query<IMedia> tracks(SortingCriteria sort, bool desc) const override;
virtual Query<IAlbum> albums( SortingCriteria sort, bool desc ) const override;
static void createTable( sqlite::Connection* dbConn );
static void createTriggers( sqlite::Connection* dbConn );
static std::shared_ptr<Genre> create( MediaLibraryPtr ml, const std::string& name );
static std::shared_ptr<Genre> fromName( MediaLibraryPtr ml, const std::string& name );
static std::vector<GenrePtr> search( MediaLibraryPtr ml, const std::string& name );
static std::vector<GenrePtr> listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc );
static Query<IGenre> search( MediaLibraryPtr ml, const std::string& name );
static Query<IGenre> listAll( MediaLibraryPtr ml, SortingCriteria sort, bool desc );
private:
MediaLibraryPtr m_ml;
......