Added performers. fixes #278
This commit is contained in:
@@ -600,6 +600,17 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
migrateFromV37(Session& session)
|
||||
{
|
||||
// Support Performer tags (via subtypes)
|
||||
session.getDboSession().execute("ALTER TABLE track_artist_link ADD subtype TEXT");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
void
|
||||
doDbMigration(Session& session)
|
||||
{
|
||||
@@ -643,6 +654,7 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
{34, migrateFromV34},
|
||||
{35, migrateFromV35},
|
||||
{36, migrateFromV36},
|
||||
{37, migrateFromV37},
|
||||
};
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Database
|
||||
class Session;
|
||||
|
||||
using Version = std::size_t;
|
||||
static constexpr Version LMS_DATABASE_VERSION {37};
|
||||
static constexpr Version LMS_DATABASE_VERSION {38};
|
||||
class VersionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -24,36 +24,78 @@
|
||||
#include "services/database/Track.hpp"
|
||||
|
||||
#include "IdTypeTraits.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
TrackArtistLink::TrackArtistLink(ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type)
|
||||
: _type {type},
|
||||
_track {getDboPtr(track)},
|
||||
_artist {getDboPtr(artist)}
|
||||
namespace Database
|
||||
{
|
||||
}
|
||||
|
||||
TrackArtistLink::pointer
|
||||
TrackArtistLink::create(Session& session, ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
TrackArtistLink::pointer res {session.getDboSession().add(std::make_unique<TrackArtistLink>(track, artist, type))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
EnumSet<TrackArtistLinkType>
|
||||
TrackArtistLink::findUsedTypes(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto res {session.getDboSession().query<TrackArtistLinkType>("SELECT DISTINCT type from track_artist_link").resultList()};
|
||||
|
||||
return EnumSet<TrackArtistLinkType>(std::begin(res), std::end(res));
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
Wt::Dbo::Query<TrackArtistLinkId>
|
||||
createQuery(Session& session, const TrackArtistLink::FindParameters& params)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<TrackArtistLinkId>("SELECT DISTINCT t_a_l.id FROM track_artist_link t_a_l")};
|
||||
|
||||
if (params.linkType)
|
||||
query.where("t_a_l.type = ?").bind(*params.linkType);
|
||||
|
||||
if (params.track.isValid() || params.release.isValid())
|
||||
query.join("track t ON t.id = t_a_l.track_id");
|
||||
|
||||
if (params.track.isValid())
|
||||
query.where("t.id = ?").bind(params.track);
|
||||
|
||||
if (params.release.isValid())
|
||||
query.where("t.release_id = ?").bind(params.release);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
TrackArtistLink::TrackArtistLink(ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type, std::string_view subType)
|
||||
: _type {type}
|
||||
, _subType {subType}
|
||||
, _track {getDboPtr(track)}
|
||||
, _artist {getDboPtr(artist)}
|
||||
{
|
||||
}
|
||||
|
||||
TrackArtistLink::pointer
|
||||
TrackArtistLink::create(Session& session, ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type, std::string_view subType)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
TrackArtistLink::pointer res {session.getDboSession().add(std::make_unique<TrackArtistLink>(track, artist, type, subType))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TrackArtistLink::pointer
|
||||
TrackArtistLink::find(Session& session, TrackArtistLinkId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<TrackArtistLink>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
|
||||
RangeResults<TrackArtistLinkId>
|
||||
TrackArtistLink::find(Session& session, const FindParameters& params)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {createQuery(session, params)};
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
|
||||
EnumSet<TrackArtistLinkType>
|
||||
TrackArtistLink::findUsedTypes(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto res {session.getDboSession().query<TrackArtistLinkType>("SELECT DISTINCT type from track_artist_link").resultList()};
|
||||
|
||||
return EnumSet<TrackArtistLinkType>(std::begin(res), std::end(res));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,6 @@ class Artist : public Object<Artist, ArtistId>
|
||||
static RangeResults<ArtistId> findAllOrphans(Session& session, Range range); // No track related
|
||||
static bool exists(Session& session, ArtistId id);
|
||||
|
||||
|
||||
// Accessors
|
||||
const std::string& getName() const { return _name; }
|
||||
const std::string& getSortName() const { return _sortName; }
|
||||
|
||||
@@ -20,11 +20,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <Wt/Dbo/Dbo.h>
|
||||
|
||||
#include "services/database/IdType.hpp"
|
||||
#include "services/database/Object.hpp"
|
||||
#include "services/database/ReleaseId.hpp"
|
||||
#include "services/database/TrackId.hpp"
|
||||
#include "services/database/Types.hpp"
|
||||
#include "utils/EnumSet.hpp"
|
||||
|
||||
@@ -40,31 +43,48 @@ namespace Database
|
||||
class TrackArtistLink : public Object<TrackArtistLink, TrackArtistLinkId>
|
||||
{
|
||||
public:
|
||||
TrackArtistLink() = default;
|
||||
TrackArtistLink(ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type);
|
||||
struct FindParameters
|
||||
{
|
||||
Range range;
|
||||
std::optional<TrackArtistLinkType> linkType; // if set, only artists that have produced at least one track with this link type
|
||||
TrackId track; // artists involved in this track
|
||||
ReleaseId release; // artists involved in this release
|
||||
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type);
|
||||
FindParameters& setRange(Range _range) {range = _range; return *this; }
|
||||
FindParameters& setLinkType(std::optional<TrackArtistLinkType> _linkType) { linkType = _linkType; return *this; }
|
||||
FindParameters& setTrack(TrackId _track) { track = _track; return *this; }
|
||||
FindParameters& setRelease(ReleaseId _release) { release = _release; return *this; }
|
||||
};
|
||||
|
||||
TrackArtistLink() = default;
|
||||
TrackArtistLink(ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type, std::string_view subType);
|
||||
|
||||
static RangeResults<TrackArtistLinkId> find(Session& session, const FindParameters& parameters);
|
||||
static pointer find(Session& session, TrackArtistLinkId linkId);
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type, std::string_view subType = {});
|
||||
static EnumSet<TrackArtistLinkType> findUsedTypes(Session& session);
|
||||
|
||||
ObjectPtr<Track> getTrack() const { return _track; }
|
||||
ObjectPtr<Artist> getArtist() const { return _artist; }
|
||||
TrackArtistLinkType getType() const { return _type; }
|
||||
std::string_view getSubType() const { return _subType; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _type, "type");
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _type, "type");
|
||||
Wt::Dbo::field(a, _subType, "subtype");
|
||||
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
TrackArtistLinkType _type;
|
||||
std::string _subType;
|
||||
|
||||
Wt::Dbo::ptr<Track> _track;
|
||||
Wt::Dbo::ptr<Artist> _artist;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -837,6 +837,12 @@ ScannerService::scanAudioFile(const std::filesystem::path& file, bool forceScan,
|
||||
for (const Artist::pointer& mixer : getOrCreateArtists(_dbSession, trackInfo->mixerArtists, true))
|
||||
track.modify()->addArtistLink(TrackArtistLink::create(_dbSession, track, mixer, TrackArtistLinkType::Mixer));
|
||||
|
||||
for (const auto& [role, performers] : trackInfo->performerArtists)
|
||||
{
|
||||
for (const Artist::pointer& performer : getOrCreateArtists(_dbSession, performers, true))
|
||||
track.modify()->addArtistLink(TrackArtistLink::create(_dbSession, track, performer, TrackArtistLinkType::Performer, role));
|
||||
}
|
||||
|
||||
for (const Artist::pointer& producer : getOrCreateArtists(_dbSession, trackInfo->producerArtists, true))
|
||||
track.modify()->addArtistLink(TrackArtistLink::create(_dbSession, track, producer, TrackArtistLinkType::Producer));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user