Fixed output bug for values, added some optims

This commit is contained in:
emeric
2023-10-21 14:45:39 +02:00
parent 07f58b3d10
commit 61e0931a82
11 changed files with 58 additions and 72 deletions
+3 -3
View File
@@ -32,11 +32,11 @@ namespace Database
{ {
namespace namespace
{ {
Wt::Dbo::Query<ClusterId> createQuery(Session& session, const Cluster::FindParameters& params) Wt::Dbo::Query<Cluster::ClusterFindResult> createQuery(Session& session, const Cluster::FindParameters& params)
{ {
session.checkSharedLocked(); session.checkSharedLocked();
auto query{ session.getDboSession().query<ClusterId>("SELECT DISTINCT c.id FROM cluster c") }; auto query{ session.getDboSession().query<Cluster::ClusterFindResult>("SELECT DISTINCT c.id,c.name FROM cluster c") };
if (params.track.isValid() || params.release.isValid()) if (params.track.isValid() || params.release.isValid())
{ {
@@ -74,7 +74,7 @@ namespace Database
return session.getDboSession().query<int>("SELECT COUNT(*) FROM cluster"); return session.getDboSession().query<int>("SELECT COUNT(*) FROM cluster");
} }
RangeResults<ClusterId> Cluster::find(Session& session, const FindParameters& params) RangeResults<Cluster::ClusterFindResult> Cluster::find(Session& session, const FindParameters& params)
{ {
session.checkSharedLocked(); session.checkSharedLocked();
auto query{ createQuery(session, params) }; auto query{ createQuery(session, params) };
@@ -672,7 +672,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
if (version == LMS_DATABASE_VERSION) if (version == LMS_DATABASE_VERSION)
{ {
LMS_LOG(DB, DEBUG) << "Lms database version " << LMS_DATABASE_VERSION << ": up to date!"; LMS_LOG(DB, INFO) << "Lms database version " << LMS_DATABASE_VERSION << ": up to date!";
return; return;
} }
else if (version > LMS_DATABASE_VERSION) else if (version > LMS_DATABASE_VERSION)
@@ -683,13 +683,15 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
if (version < migrationFunctions.begin()->first) if (version < migrationFunctions.begin()->first)
throw LmsException{ outdatedMsg }; throw LmsException{ outdatedMsg };
LMS_LOG(DB, INFO) << "Migrating database from version " << version << "..."; LMS_LOG(DB, INFO) << "Migrating database from version " << version << " to " << version + 1 << "...";
auto itMigrationFunc{ migrationFunctions.find(version) }; auto itMigrationFunc{ migrationFunctions.find(version) };
assert(itMigrationFunc != std::cend(migrationFunctions)); assert(itMigrationFunc != std::cend(migrationFunctions));
itMigrationFunc->second(session); itMigrationFunc->second(session);
VersionInfo::get(session).modify()->setVersion(++version); VersionInfo::get(session).modify()->setVersion(++version);
LMS_LOG(DB, INFO) << "Migration complete to version " << version;
} }
} }
} }
@@ -21,6 +21,7 @@
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <tuple>
#include <vector> #include <vector>
#include <Wt/Dbo/Dbo.h> #include <Wt/Dbo/Dbo.h>
@@ -58,10 +59,12 @@ namespace Database {
Cluster() = default; Cluster() = default;
// Find utility // Find utility
static std::size_t getCount(Session& session); // As clusters only have a name, this is an optim to directly get the cluster names
static RangeResults<ClusterId> find(Session& session, const FindParameters& range); using ClusterFindResult = std::tuple<ClusterId, std::string>;
static pointer find(Session& session, ClusterId id); static std::size_t getCount(Session& session);
static RangeResults<ClusterId> findOrphans(Session& session, Range range); static RangeResults<ClusterFindResult> find(Session& session, const FindParameters& range);
static pointer find(Session& session, ClusterId id);
static RangeResults<ClusterId> findOrphans(Session& session, Range range);
// Accessors // Accessors
const std::string& getName() const { return _name; } const std::string& getName() const { return _name; }
+13 -11
View File
@@ -48,13 +48,17 @@ TEST_F(DatabaseFixture, Cluster)
EXPECT_EQ(Cluster::getCount(session), 1); EXPECT_EQ(Cluster::getCount(session), 1);
EXPECT_EQ(cluster->getType()->getId(), clusterType.getId()); EXPECT_EQ(cluster->getType()->getId(), clusterType.getId());
auto clusters{ Cluster::find(session, Cluster::FindParameters {}) }; {
ASSERT_EQ(clusters.results.size(), 1); const auto clusters{ Cluster::find(session, Cluster::FindParameters {}) };
EXPECT_EQ(clusters.results.front(), cluster.getId()); ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(std::get<ClusterId>(clusters.results.front()), cluster.getId());
}
clusters = Cluster::findOrphans(session, Range{}); {
ASSERT_EQ(clusters.results.size(), 1); const auto clusters{ Cluster::findOrphans(session, Range{}) };
EXPECT_EQ(clusters.results.front(), cluster.getId()); ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster.getId());
}
auto clusterTypes{ ClusterType::find(session, Range {}) }; auto clusterTypes{ ClusterType::find(session, Range {}) };
ASSERT_EQ(clusterTypes.results.size(), 1); ASSERT_EQ(clusterTypes.results.size(), 1);
@@ -114,7 +118,7 @@ TEST_F(DatabaseFixture, Cluster_singleTrack)
auto transaction{ session.createSharedTransaction() }; auto transaction{ session.createSharedTransaction() };
auto clusters{ Cluster::find(session, Cluster::FindParameters {}.setTrack(track.getId())) }; auto clusters{ Cluster::find(session, Cluster::FindParameters {}.setTrack(track.getId())) };
ASSERT_EQ(clusters.results.size(), 1); ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster1.getId()); EXPECT_EQ(std::get<ClusterId>(clusters.results.front()), cluster1.getId());
} }
{ {
@@ -317,9 +321,9 @@ TEST_F(DatabaseFixture, Cluster_singleTrackSingleReleaseSingleCluster)
{ {
auto transaction{ session.createSharedTransaction() }; auto transaction{ session.createSharedTransaction() };
auto clusters{ Cluster::find(session, Cluster::FindParameters{}.setRelease(release.getId())) }; const auto clusters{ Cluster::find(session, Cluster::FindParameters{}.setRelease(release.getId())) };
ASSERT_EQ(clusters.results.size(), 1); ASSERT_EQ(clusters.results.size(), 1);
EXPECT_EQ(clusters.results.front(), cluster.getId()); EXPECT_EQ(std::get<ClusterId>(clusters.results.front()), cluster.getId());
} }
{ {
@@ -1106,5 +1110,3 @@ TEST_F(DatabaseFixture, MultipleTracksMultipleReleasesMultiClusters)
} }
} }
} }
+4 -4
View File
@@ -58,7 +58,7 @@ namespace API::Subsonic
_attributes[key] = std::string{ value }; _attributes[key] = std::string{ value };
} }
void Response::Node::addChild(Key key, Node node) void Response::Node::addChild(Key key, Node&& node)
{ {
assert(!_value); assert(!_value);
assert(_children.find(key) == std::cend(_children)); assert(_children.find(key) == std::cend(_children));
@@ -72,7 +72,7 @@ namespace API::Subsonic
_childrenArrays.emplace(key, std::vector<Node>{}); _childrenArrays.emplace(key, std::vector<Node>{});
} }
void Response::Node::addArrayChild(Key key, Node node) void Response::Node::addArrayChild(Key key, Node&& node)
{ {
assert(!_value); assert(!_value);
assert(_children.find(key) == std::cend(_children)); assert(_children.find(key) == std::cend(_children));
@@ -155,7 +155,7 @@ namespace API::Subsonic
return response; return response;
} }
void Response::addNode(Node::Key key, Node node) void Response::addNode(Node::Key key, Node&& node)
{ {
return _root._children["subsonic-response"].addChild(key, std::move(node)); return _root._children["subsonic-response"].addChild(key, std::move(node));
} }
@@ -266,7 +266,7 @@ namespace API::Subsonic
if (!first) if (!first)
os << ','; os << ',';
os << "value:"; os << "\"value\":";
serializeValue(os, *node._value); serializeValue(os, *node._value);
first = false; first = false;
+3 -3
View File
@@ -225,9 +225,9 @@ namespace API::Subsonic
Node& createChild(Key key); Node& createChild(Key key);
Node& createArrayChild(Key key); Node& createArrayChild(Key key);
void addChild(Key key, Node node); void addChild(Key key, Node&& node);
void createEmptyArrayChild(Key key); void createEmptyArrayChild(Key key);
void addArrayChild(Key key, Node node); void addArrayChild(Key key, Node&& node);
void createEmptyArrayValue(Key key); void createEmptyArrayValue(Key key);
void addArrayValue(Key key, std::string_view value); void addArrayValue(Key key, std::string_view value);
void addArrayValue(Key key, long long value); void addArrayValue(Key key, long long value);
@@ -255,7 +255,7 @@ namespace API::Subsonic
Response(Response&&) = default; Response(Response&&) = default;
Response& operator=(Response&&) = default; Response& operator=(Response&&) = default;
void addNode(Node::Key key, Node node); void addNode(Node::Key key, Node&& node);
Node& createNode(Node::Key key); Node& createNode(Node::Key key);
Node& createArrayNode(Node::Key key); Node& createArrayNode(Node::Key key);
@@ -75,7 +75,7 @@ namespace API::Subsonic
for (const TrackListEntry::pointer& entry : entries) for (const TrackListEntry::pointer& entry : entries)
playlistNode.addArrayChild("entry", createSongNode(entry->getTrack(), context.dbSession, user)); playlistNode.addArrayChild("entry", createSongNode(entry->getTrack(), context.dbSession, user));
response.addNode("playlist", playlistNode); response.addNode("playlist", std::move(playlistNode));
return response; return response;
} }
+10 -20
View File
@@ -133,7 +133,7 @@ namespace API::Subsonic
} }
if (const Wt::WDateTime dateTime{ Service<Scrobbling::IScrobblingService>::get()->getStarredDateTime(user->getId(), release->getId()) }; dateTime.isValid()) if (const Wt::WDateTime dateTime{ Service<Scrobbling::IScrobblingService>::get()->getStarredDateTime(user->getId(), release->getId()) }; dateTime.isValid())
albumNode.setAttribute("starred", StringUtils::toISO8601String(dateTime)); // TODO report correct date/time albumNode.setAttribute("starred", StringUtils::toISO8601String(dateTime));
// OpenSubsonic specific fields (must always be set) // OpenSubsonic specific fields (must always be set)
if (!id3) if (!id3)
@@ -160,33 +160,23 @@ namespace API::Subsonic
params.setRelease(release->getId()); params.setRelease(release->getId());
params.setClusterType(clusterType->getId()); params.setClusterType(clusterType->getId());
for (const ClusterId clusterId : Cluster::find(dbSession, params).results) for (const auto& cluster : Cluster::find(dbSession, params).results)
{ albumNode.addArrayValue(field, std::get<std::string>(cluster));
Cluster::pointer cluster{ Cluster::find(dbSession, clusterId) };
if (cluster)
albumNode.addArrayValue(field, cluster->getName());
}
} }
} }; } };
addClusters("moods", "MOOD"); addClusters("moods", "MOOD");
// Genres // Genres
albumNode.createEmptyArrayChild("genres");
if (genreClusterType)
{ {
albumNode.createEmptyArrayChild("genres"); Cluster::FindParameters params;
if (genreClusterType) params.setRelease(release->getId());
{ params.setClusterType(genreClusterType->getId());
Cluster::FindParameters params;
params.setRelease(release->getId());
params.setClusterType(genreClusterType->getId());
for (const ClusterId clusterId : Cluster::find(dbSession, params).results) for (const auto& cluster : Cluster::find(dbSession, params).results)
{ albumNode.addArrayChild("genres", createItemGenreNode(std::get<std::string>(cluster)));
Cluster::pointer cluster{ Cluster::find(dbSession, clusterId) };
if (cluster)
albumNode.addArrayChild("genres", createItemGenreNode(cluster));
}
}
} }
albumNode.createEmptyArrayChild("artists"); albumNode.createEmptyArrayChild("artists");
@@ -23,11 +23,11 @@
namespace API::Subsonic namespace API::Subsonic
{ {
Response::Node createItemGenreNode(const Database::Cluster::pointer& cluster) Response::Node createItemGenreNode(std::string_view name)
{ {
Response::Node genreNode; Response::Node genreNode;
genreNode.setAttribute("name", cluster->getName()); genreNode.setAttribute("name", name);
return genreNode; return genreNode;
} }
@@ -19,7 +19,7 @@
#pragma once #pragma once
#include "services/database/Object.hpp" #include <string_view>
#include "SubsonicResponse.hpp" #include "SubsonicResponse.hpp"
namespace Database namespace Database
@@ -29,5 +29,5 @@ namespace Database
namespace API::Subsonic namespace API::Subsonic
{ {
Response::Node createItemGenreNode(const Database::ObjectPtr<Database::Cluster>& cluster); Response::Node createItemGenreNode(std::string_view name);
} }
+9 -20
View File
@@ -221,34 +221,23 @@ namespace API::Subsonic
params.setTrack(track->getId()); params.setTrack(track->getId());
params.setClusterType(clusterType->getId()); params.setClusterType(clusterType->getId());
for (const ClusterId clusterId : Cluster::find(dbSession, params).results) for (const auto& cluster : Cluster::find(dbSession, params).results)
{ trackResponse.addArrayValue(field, std::get<std::string>(cluster));
Cluster::pointer cluster {Cluster::find(dbSession, clusterId)};
if (cluster)
trackResponse.addArrayValue(field, cluster->getName());
}
} }
} }; } };
addClusters("moods", "MOOD"); addClusters("moods", "MOOD");
// Genres // Genres
trackResponse.createEmptyArrayChild("genres");
if (genreClusterType)
{ {
trackResponse.createEmptyArrayChild("genres"); Cluster::FindParameters params;
params.setTrack(track->getId());
params.setClusterType(genreClusterType->getId());
if (genreClusterType) for (const auto& cluster : Cluster::find(dbSession, params).results)
{ trackResponse.addArrayChild("genres", createItemGenreNode(std::get<std::string>(cluster)));
Cluster::FindParameters params;
params.setTrack(track->getId());
params.setClusterType(genreClusterType->getId());
for (const ClusterId clusterId : Cluster::find(dbSession, params).results)
{
Cluster::pointer cluster{ Cluster::find(dbSession, clusterId) };
if (cluster)
trackResponse.addArrayChild("genres", createItemGenreNode(cluster));
}
}
} }
trackResponse.addChild("replayGain", createReplayGainNode(track)); trackResponse.addChild("replayGain", createReplayGainNode(track));