Now prefer 'disc' artworks for tracks, ref #604
This commit is contained in:
@@ -35,7 +35,7 @@ namespace lms::db
|
||||
{
|
||||
namespace
|
||||
{
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 91 };
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 92 };
|
||||
}
|
||||
|
||||
VersionInfo::VersionInfo()
|
||||
@@ -1213,6 +1213,11 @@ FROM tracklist)");
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET artist_info_scan_version = artist_info_scan_version + 1");
|
||||
}
|
||||
|
||||
void migrateFromV91(Session& session)
|
||||
{
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track_embedded_image_link DROP COLUMN is_preferred");
|
||||
}
|
||||
|
||||
bool doDbMigration(Session& session)
|
||||
{
|
||||
constexpr std::string_view outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
|
||||
@@ -1280,6 +1285,7 @@ FROM tracklist)");
|
||||
{ 88, migrateFromV88 },
|
||||
{ 89, migrateFromV89 },
|
||||
{ 90, migrateFromV90 },
|
||||
{ 91, migrateFromV91 }
|
||||
};
|
||||
|
||||
bool migrationPerformed{};
|
||||
|
||||
@@ -229,7 +229,6 @@ namespace lms::db
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_id_idx ON track_embedded_image_link(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_id_idx ON track_embedded_image_link(track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_embedded_image_id_track_id_idx ON track_embedded_image_link(track_embedded_image_id, track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_is_preferred_track_id_track_embedded_image_id_idx ON track_embedded_image_link(is_preferred, track_id, track_embedded_image_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_id_idx ON image(id)");
|
||||
|
||||
@@ -38,17 +38,14 @@ namespace lms::db
|
||||
|
||||
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<TrackEmbeddedImage>>("SELECT t_e_i FROM track_embedded_image t_e_i") };
|
||||
|
||||
if (params.isPreferred
|
||||
|| params.track.isValid()
|
||||
if (params.track.isValid()
|
||||
|| params.release.isValid()
|
||||
|| params.trackList.isValid()
|
||||
|| params.sortMethod == TrackEmbeddedImageSortMethod::FrontCoverAndSize)
|
||||
|| params.sortMethod == TrackEmbeddedImageSortMethod::MediaTypeThenFrontTypeThenSize
|
||||
|| params.sortMethod == TrackEmbeddedImageSortMethod::FrontTypeThenSize)
|
||||
{
|
||||
query.join("track_embedded_image_link t_e_i_l ON t_e_i_l.track_embedded_image_id = t_e_i.id");
|
||||
|
||||
if (params.isPreferred)
|
||||
query.where("t_e_i_l.is_preferred = ?").bind(params.isPreferred.value());
|
||||
|
||||
if (params.track.isValid())
|
||||
query.where("t_e_i_l.track_id = ?").bind(params.track);
|
||||
|
||||
@@ -69,8 +66,11 @@ namespace lms::db
|
||||
{
|
||||
case TrackEmbeddedImageSortMethod::None:
|
||||
break;
|
||||
case TrackEmbeddedImageSortMethod::FrontCoverAndSize:
|
||||
query.orderBy("CASE WHEN t_e_i_l.type = ? THEN 0 ELSE 1 END, t_e_i.size").bind(ImageType::FrontCover);
|
||||
case TrackEmbeddedImageSortMethod::MediaTypeThenFrontTypeThenSize:
|
||||
query.orderBy("CASE t_e_i_l.type WHEN ? THEN 1 WHEN ? THEN 2 ELSE 3 END, t_e_i.size DESC").bind(ImageType::Media).bind(ImageType::FrontCover);
|
||||
break;
|
||||
case TrackEmbeddedImageSortMethod::FrontTypeThenSize:
|
||||
query.orderBy("CASE WHEN t_e_i_l.type = ? THEN 0 ELSE 1 END, t_e_i.size DESC").bind(ImageType::FrontCover);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,14 @@ namespace lms::db
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->find<TrackEmbeddedImageLink>().where("id = ?").bind(id));
|
||||
}
|
||||
|
||||
void TrackEmbeddedImageLink::find(Session& session, TrackEmbeddedImageId trackEmbeddedImageId, std::function<void(const pointer&)> visitor)
|
||||
{
|
||||
auto query{ session.getDboSession()->find<TrackEmbeddedImageLink>() };
|
||||
query.where("track_embedded_image_id = ?").bind(trackEmbeddedImageId);
|
||||
|
||||
return utils::forEachQueryResult(query, visitor);
|
||||
}
|
||||
|
||||
ObjectPtr<Track> TrackEmbeddedImageLink::getTrack() const
|
||||
{
|
||||
return _track;
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace lms::db
|
||||
TrackId track;
|
||||
ReleaseId release;
|
||||
TrackListId trackList;
|
||||
std::optional<bool> isPreferred;
|
||||
TrackEmbeddedImageSortMethod sortMethod{ TrackEmbeddedImageSortMethod::None };
|
||||
|
||||
FindParameters& setRange(std::optional<Range> _range)
|
||||
@@ -72,11 +71,6 @@ namespace lms::db
|
||||
trackList = _trackList;
|
||||
return *this;
|
||||
}
|
||||
FindParameters& setIsPreferred(std::optional<bool> _isPreferred)
|
||||
{
|
||||
isPreferred = _isPreferred;
|
||||
return *this;
|
||||
}
|
||||
FindParameters& setSortMethod(TrackEmbeddedImageSortMethod _sortMethod)
|
||||
{
|
||||
sortMethod = _sortMethod;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <Wt/Dbo/Dbo.h>
|
||||
|
||||
#include "database/Object.hpp"
|
||||
#include "database/TrackEmbeddedImageId.hpp"
|
||||
#include "database/TrackEmbeddedImageLinkId.hpp"
|
||||
#include "database/Types.hpp"
|
||||
|
||||
@@ -44,18 +45,17 @@ namespace lms::db
|
||||
// find
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, TrackEmbeddedImageLinkId id);
|
||||
static void find(Session& session, TrackEmbeddedImageId trackEmbeddedImageId, std::function<void(const pointer&)> visitor);
|
||||
|
||||
// getters
|
||||
ObjectPtr<Track> getTrack() const;
|
||||
ObjectPtr<TrackEmbeddedImage> getImage() const;
|
||||
std::size_t getIndex() const { return _index; }
|
||||
bool isPreferred() const { return _isPreferred; }
|
||||
ImageType getType() const { return _type; }
|
||||
std::string_view getDescription() const { return _description; }
|
||||
|
||||
// setters
|
||||
void setIndex(std::size_t index) { _index = static_cast<int>(index); }
|
||||
void setIsPreferred(bool isPreferred) { _isPreferred = isPreferred; }
|
||||
void setType(ImageType type) { _type = type; }
|
||||
void setDescription(std::string_view description) { _description = description; }
|
||||
|
||||
@@ -63,7 +63,6 @@ namespace lms::db
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _index, "index");
|
||||
Wt::Dbo::field(a, _isPreferred, "is_preferred");
|
||||
Wt::Dbo::field(a, _type, "type");
|
||||
Wt::Dbo::field(a, _description, "description");
|
||||
|
||||
@@ -78,7 +77,6 @@ namespace lms::db
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<TrackEmbeddedImage> image);
|
||||
|
||||
int _index{}; // index within the track
|
||||
bool _isPreferred{};
|
||||
ImageType _type{ ImageType::Unknown };
|
||||
std::string _description;
|
||||
|
||||
|
||||
@@ -171,7 +171,8 @@ namespace lms::db
|
||||
enum class TrackEmbeddedImageSortMethod
|
||||
{
|
||||
None,
|
||||
FrontCoverAndSize,
|
||||
MediaTypeThenFrontTypeThenSize,
|
||||
FrontTypeThenSize,
|
||||
};
|
||||
|
||||
enum class TrackListSortMethod
|
||||
|
||||
@@ -118,23 +118,22 @@ namespace lms::db::tests
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setIsPreferred(true);
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImage::find(session, params, [&](const auto&) { visited = true; });
|
||||
EXPECT_FALSE(visited);
|
||||
EXPECT_TRUE(visited);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createWriteTransaction() };
|
||||
link.get().modify()->setIsPreferred(true);
|
||||
link.get().modify()->setType(ImageType::FrontCover);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setIsPreferred(true);
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::FrontTypeThenSize);
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImage::find(session, params, [&](const auto&) { visited = true; });
|
||||
@@ -145,8 +144,8 @@ namespace lms::db::tests
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setIsPreferred(true);
|
||||
params.setRelease(release.getId());
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::MediaTypeThenFrontTypeThenSize);
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImage::find(session, params, [&](const auto&) { visited = true; });
|
||||
@@ -162,9 +161,8 @@ namespace lms::db::tests
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setIsPreferred(true);
|
||||
params.setRelease(release.getId());
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::FrontCoverAndSize);
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::MediaTypeThenFrontTypeThenSize);
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImage::find(session, params, [&](const auto&) { visited = true; });
|
||||
@@ -175,9 +173,8 @@ namespace lms::db::tests
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setIsPreferred(true);
|
||||
params.setTrack(track.getId());
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::FrontCoverAndSize);
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::FrontTypeThenSize);
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImage::find(session, params, [&](const auto&) { visited = true; });
|
||||
@@ -185,6 +182,55 @@ namespace lms::db::tests
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, TrackEmbeddedImage_findByParams_sorts)
|
||||
{
|
||||
ScopedTrackEmbeddedImage image1{ session };
|
||||
ScopedTrackEmbeddedImage image2{ session };
|
||||
ScopedTrackEmbeddedImage image3{ session };
|
||||
ScopedTrack track{ session };
|
||||
ScopedRelease release{ session, "MyRelease" };
|
||||
ScopedTrackEmbeddedImageLink link1{ session, track.lockAndGet(), image1.lockAndGet() };
|
||||
ScopedTrackEmbeddedImageLink link2{ session, track.lockAndGet(), image2.lockAndGet() };
|
||||
ScopedTrackEmbeddedImageLink link3{ session, track.lockAndGet(), image3.lockAndGet() };
|
||||
|
||||
{
|
||||
auto transaction{ session.createWriteTransaction() };
|
||||
link1.get().modify()->setType(ImageType::FrontCover);
|
||||
link2.get().modify()->setType(ImageType::Media);
|
||||
image2.get().modify()->setSize(1000);
|
||||
link3.get().modify()->setType(ImageType::Media);
|
||||
image3.get().modify()->setSize(2000);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::FrontTypeThenSize);
|
||||
|
||||
std::vector<TrackEmbeddedImageId> visitedIds;
|
||||
TrackEmbeddedImage::find(session, params, [&](const TrackEmbeddedImage::pointer& image) { visitedIds.push_back(image->getId()); });
|
||||
ASSERT_EQ(visitedIds.size(), 3);
|
||||
EXPECT_EQ(visitedIds[0], image1.getId());
|
||||
EXPECT_EQ(visitedIds[1], image3.getId());
|
||||
EXPECT_EQ(visitedIds[2], image2.getId());
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackEmbeddedImage::FindParameters params;
|
||||
params.setSortMethod(TrackEmbeddedImageSortMethod::MediaTypeThenFrontTypeThenSize);
|
||||
|
||||
std::vector<TrackEmbeddedImageId> visitedIds;
|
||||
TrackEmbeddedImage::find(session, params, [&](const TrackEmbeddedImage::pointer& image) { visitedIds.push_back(image->getId()); });
|
||||
ASSERT_EQ(visitedIds.size(), 3);
|
||||
EXPECT_EQ(visitedIds[0], image3.getId());
|
||||
EXPECT_EQ(visitedIds[1], image2.getId());
|
||||
EXPECT_EQ(visitedIds[2], image1.getId());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Track_findByEmbeddedImage)
|
||||
{
|
||||
ScopedTrackEmbeddedImage image{ session };
|
||||
@@ -279,5 +325,20 @@ namespace lms::db::tests
|
||||
EXPECT_EQ(img->getType(), ImageType::FrontCover);
|
||||
EXPECT_EQ(img->getDescription(), "MyDesc");
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
bool visited{};
|
||||
TrackEmbeddedImageLink::find(session, image->getId(), [&](const TrackEmbeddedImageLink::pointer& link) {
|
||||
EXPECT_EQ(link->getIndex(), 2);
|
||||
EXPECT_EQ(link->getType(), ImageType::FrontCover);
|
||||
EXPECT_EQ(link->getDescription(), "MyDesc");
|
||||
EXPECT_EQ(link->getTrack(), track.get());
|
||||
|
||||
visited = true;
|
||||
});
|
||||
EXPECT_TRUE(visited);
|
||||
}
|
||||
}
|
||||
} // namespace lms::db::tests
|
||||
Reference in New Issue
Block a user