Better handle badly tagged multi-discs releases

This commit is contained in:
emeric
2022-09-04 21:14:48 +02:00
parent a6e2818a38
commit 56e9b4f787
8 changed files with 72 additions and 16 deletions
+1 -1
View File
@@ -178,7 +178,7 @@ AudioFile::getBestStream() const
} }
bool bool
AudioFile::hasAttachedPictures(void) const AudioFile::hasAttachedPictures() const
{ {
for (std::size_t i = 0; i < _context->nb_streams; ++i) for (std::size_t i = 0; i < _context->nb_streams; ++i)
{ {
+14 -2
View File
@@ -264,7 +264,7 @@ Release::find(Session& session, const FindParameters& params)
} }
std::optional<std::size_t> std::optional<std::size_t>
Release::getTotalTrack(void) const Release::getTotalTrack() const
{ {
assert(session()); assert(session());
@@ -276,7 +276,7 @@ Release::getTotalTrack(void) const
} }
std::optional<std::size_t> std::optional<std::size_t>
Release::getTotalDisc(void) const Release::getTotalDisc() const
{ {
assert(session()); assert(session());
@@ -287,6 +287,18 @@ Release::getTotalDisc(void) const
return (res > 0) ? std::make_optional<std::size_t>(res) : std::nullopt; return (res > 0) ? std::make_optional<std::size_t>(res) : std::nullopt;
} }
std::size_t
Release::getDiscCount() const
{
assert(session());
int res {session()->query<int>("SELECT COUNT(DISTINCT disc_number) FROM track t")
.join("release r ON r.id = t.release_id")
.where("r.id = ?")
.bind(getId())};
return res;
}
std::optional<int> std::optional<int>
Release::getReleaseYear(bool original) const Release::getReleaseYear(bool original) const
{ {
+2 -2
View File
@@ -58,7 +58,7 @@ WhereClause::Or(const WhereClause& otherClause)
} }
std::string std::string
WhereClause::get(void) const WhereClause::get() const
{ {
if (!_clause.empty()) if (!_clause.empty())
return "WHERE " + _clause; return "WHERE " + _clause;
@@ -176,7 +176,7 @@ FromClause::get() const
} }
std::string std::string
SqlQuery::get(void) const SqlQuery::get() const
{ {
std::ostringstream oss; std::ostringstream oss;
+8 -8
View File
@@ -36,7 +36,7 @@ class WhereClause
WhereClause& bind(const std::string& arg); WhereClause& bind(const std::string& arg);
std::string get() const; std::string get() const;
const std::list<std::string>& getBindArgs(void) const {return _bindArgs;} const std::list<std::string>& getBindArgs() const {return _bindArgs;}
private: private:
std::string _clause; // WHERE clause std::string _clause; // WHERE clause
@@ -101,15 +101,15 @@ class FromClause
class SqlQuery class SqlQuery
{ {
public: public:
SelectStatement& select(void) { return _selectStatement;} SelectStatement& select() { return _selectStatement;}
SelectStatement& select(const std::string& statement) { _selectStatement = SelectStatement(statement); return _selectStatement; } SelectStatement& select(const std::string& statement) { _selectStatement = SelectStatement(statement); return _selectStatement; }
FromClause& from(void) { return _fromClause; } FromClause& from() { return _fromClause; }
FromClause& from(const std::string& clause) { _whereClause = WhereClause(clause); return _fromClause; } FromClause& from(const std::string& clause) { _whereClause = WhereClause(clause); return _fromClause; }
InnerJoinClause& innerJoin(void) { return _innerJoinClause; } InnerJoinClause& innerJoin() { return _innerJoinClause; }
WhereClause& where(void) { return _whereClause; } WhereClause& where() { return _whereClause; }
const WhereClause& where(void) const { return _whereClause; } const WhereClause& where() const { return _whereClause; }
GroupByStatement& groupBy(void) { return _groupByStatement; } GroupByStatement& groupBy() { return _groupByStatement; }
const GroupByStatement& groupBy(void) const { return _groupByStatement; } const GroupByStatement& groupBy() const { return _groupByStatement; }
std::string get() const; std::string get() const;
@@ -107,6 +107,7 @@ class Release : public Object<Release, ReleaseId>
std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); } std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); }
std::optional<std::size_t> getTotalTrack() const; std::optional<std::size_t> getTotalTrack() const;
std::optional<std::size_t> getTotalDisc() const; std::optional<std::size_t> getTotalDisc() const;
std::size_t getDiscCount() const; // may not be total disc (if incomplete for example)
std::chrono::milliseconds getDuration() const; std::chrono::milliseconds getDuration() const;
Wt::WDateTime getLastWritten() const; Wt::WDateTime getLastWritten() const;
@@ -207,5 +207,3 @@ TEST_F(DatabaseFixture, Common_subRange)
} }
} }
@@ -464,3 +464,47 @@ TEST_F(DatabaseFixture, Release_artist)
} }
} }
TEST_F(DatabaseFixture, Release_getDiscCount)
{
ScopedRelease release {session, "MyRelease"};
ScopedTrack track {session, "MyTrack"};
ScopedTrack track2 {session, "MyTrack2"};
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(release.get()->getDiscCount(), 0);
}
{
auto transaction {session.createUniqueTransaction()};
track.get().modify()->setRelease(release.get());
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(release.get()->getDiscCount(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
track.get().modify()->setDiscNumber(5);
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(release.get()->getDiscCount(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
track2.get().modify()->setRelease(release.get());
track2.get().modify()->setDiscNumber(5);
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(release.get()->getDiscCount(), 1);
}
{
auto transaction {session.createUniqueTransaction()};
track2.get().modify()->setDiscNumber(6);
}
{
auto transaction {session.createSharedTransaction()};
EXPECT_EQ(release.get()->getDiscCount(), 2);
}
}
+2 -1
View File
@@ -197,7 +197,8 @@ Release::refreshView()
const bool variousArtists {release->hasVariousArtists()}; const bool variousArtists {release->hasVariousArtists()};
const auto totalDisc {release->getTotalDisc()}; const auto totalDisc {release->getTotalDisc()};
const bool isReleaseMultiDisc {totalDisc && *totalDisc > 1}; const std::size_t discCount {release->getDiscCount()};
const bool isReleaseMultiDisc {(discCount > 1) || (totalDisc && *totalDisc > 1)};
// Expect to be called in asc order // Expect to be called in asc order
std::map<std::size_t, Wt::WContainerWidget*> trackContainers; std::map<std::size_t, Wt::WContainerWidget*> trackContainers;