From a3da259a37158c62ab3f897f1d398becea688ebc Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 31 Oct 2023 09:45:29 +1100 Subject: [PATCH] Improve representation of track numbers in indexes --- src/database/database.cpp | 2 +- src/database/index.cpp | 31 ++++++++++++++++++++++--------- src/database/tag_parser.cpp | 8 +++----- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/database/database.cpp b/src/database/database.cpp index e826f576..ec4df5f8 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -51,7 +51,7 @@ static SingletonEnv sEnv; static const char kDbPath[] = "/.tangara-db"; static const char kKeyDbVersion[] = "schema_version"; -static const uint8_t kCurrentDbVersion = 3; +static const uint8_t kCurrentDbVersion = 4; static const char kKeyCollator[] = "collator"; static const char kKeyTrackId[] = "next_track_id"; diff --git a/src/database/index.cpp b/src/database/index.cpp index 7d556192..1548a3be 100644 --- a/src/database/index.cpp +++ b/src/database/index.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include "collation.hpp" @@ -55,7 +56,7 @@ static auto missing_component_text(const Track& track, Tag tag) case Tag::kTitle: return track.TitleOrFilename(); case Tag::kAlbumTrack: - return "0000"; + return "0"; case Tag::kDuration: default: return {}; @@ -76,17 +77,29 @@ auto Index(locale::ICollator& collator, const IndexInfo& info, const Track& t) }; for (std::uint8_t i = 0; i < info.components.size(); i++) { + Tag component = info.components.at(i); // Fill in the text for this depth. - auto text = t.tags().at(info.components.at(i)); std::pmr::string value; - if (text) { - std::pmr::string orig = *text; - auto xfrm = collator.Transform({orig.data(), orig.size()}); - key.item = {xfrm.data(), xfrm.size()}; - value = *text; + + if (component == Tag::kAlbumTrack) { + // Track numbers are a special case, since they're numbers rather than + // text. + auto pmr_num = t.tags().at(component).value_or("0"); + // std::pmr continues to be a true disappointment. + std::string raw_num{pmr_num.data(), pmr_num.size()}; + uint32_t num = std::stoi(raw_num); + key.item = std::pmr::string{reinterpret_cast(&num), 4}; } else { - key.item = {}; - value = missing_component_text(t, info.components.at(i)).value_or(""); + auto text = t.tags().at(component); + if (text) { + std::pmr::string orig = *text; + auto xfrm = collator.Transform({orig.data(), orig.size()}); + key.item = {xfrm.data(), xfrm.size()}; + value = *text; + } else { + key.item = {}; + value = missing_component_text(t, info.components.at(i)).value_or(""); + } } // If this is the last component, then we should also fill in the track id diff --git a/src/database/tag_parser.cpp b/src/database/tag_parser.cpp index eb5f3a43..44377074 100644 --- a/src/database/tag_parser.cpp +++ b/src/database/tag_parser.cpp @@ -30,9 +30,8 @@ const static std::array, 5> kVorbisIdToTag = {{ }}; static auto convert_track_number(int number) -> std::pmr::string { - std::ostringstream oss; - oss << std::setw(4) << std::setfill('0') << number; - return std::pmr::string(oss.str()); + std::string s = std::to_string(number); + return {s.data(), s.size()}; } static auto convert_track_number(const std::pmr::string& raw) @@ -167,8 +166,7 @@ auto TagParserImpl::ReadAndParseTags(const std::pmr::string& path) } } - // Normalise track numbers; they're usually treated as strings, but we would - // like to sort them lexicographically. + // Normalise track numbers to ensure that they're actually numbers. tags->set(Tag::kAlbumTrack, convert_track_number(tags->at(Tag::kAlbumTrack).value_or("0")));