[WIP] Added Artist/ReleaseInfo
This commit is contained in:
@@ -199,6 +199,12 @@ Artist::getReleases(const std::set<IdType>& clusterIds) const
|
||||
return std::vector< Wt::Dbo::ptr<Release> > (res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Wt::Dbo::ptr<Track>>
|
||||
Artist::getTracks() const
|
||||
{
|
||||
return std::vector<Wt::Dbo::ptr<Track>>(_tracks.begin(), _tracks.end());
|
||||
}
|
||||
|
||||
std::vector<std::vector<Wt::Dbo::ptr<Cluster>>>
|
||||
Artist::getClusterGroups(std::vector<ClusterType::pointer> clusterTypes, std::size_t size) const
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@ class Artist : public Wt::Dbo::Dbo<Artist>
|
||||
|
||||
// Get the releases that have at least one track for this artist that belongs to optional cluster filters
|
||||
std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::set<IdType>& clusterIds = std::set<IdType>()) const;
|
||||
std::vector<Wt::Dbo::ptr<Track>> getTracks() const;
|
||||
|
||||
// Get the cluster of the tracks made by this artist
|
||||
// Each clusters are grouped by cluster type, sorted by the number of occurence
|
||||
|
||||
@@ -37,7 +37,7 @@ class ScanSettings;
|
||||
class Cluster : public Wt::Dbo::Dbo<Cluster>
|
||||
{
|
||||
public:
|
||||
typedef Wt::Dbo::ptr<Cluster> pointer;
|
||||
using pointer = Wt::Dbo::ptr<Cluster>;
|
||||
|
||||
Cluster();
|
||||
Cluster(Wt::Dbo::ptr<ClusterType> type, std::string name);
|
||||
@@ -50,7 +50,7 @@ class Cluster : public Wt::Dbo::Dbo<Cluster>
|
||||
static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr<ClusterType> type, std::string name);
|
||||
|
||||
// Accessors
|
||||
const std::string& getName(void) const { return _name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
Wt::Dbo::ptr<ClusterType> getType() const { return _clusterType; }
|
||||
std::size_t getCount() const { return _tracks.size(); }
|
||||
std::vector<Wt::Dbo::ptr<Track>> getTracks(int offset, int limit) const;
|
||||
|
||||
@@ -35,10 +35,12 @@
|
||||
|
||||
#include "Artist.hpp"
|
||||
#include "Cluster.hpp"
|
||||
#include "TrackList.hpp"
|
||||
#include "Release.hpp"
|
||||
#include "ScanSettings.hpp"
|
||||
#include "SimilaritySettings.hpp"
|
||||
#include "Track.hpp"
|
||||
#include "TrackList.hpp"
|
||||
#include "TrackFeature.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
@@ -104,8 +106,11 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool)
|
||||
_session.mapClass<TrackListEntry>("tracklist_entry");
|
||||
_session.mapClass<Release>("release");
|
||||
_session.mapClass<Track>("track");
|
||||
_session.mapClass<TrackFeature>("track_feature");
|
||||
_session.mapClass<TrackFeatureType>("track_feature_type");
|
||||
|
||||
_session.mapClass<ScanSettings>("scan_settings");
|
||||
_session.mapClass<SimilaritySettings>("similarity_settings");
|
||||
|
||||
_session.mapClass<AuthInfo>("auth_info");
|
||||
_session.mapClass<AuthInfo::AuthIdentityType>("auth_identity");
|
||||
@@ -129,13 +134,18 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool)
|
||||
|
||||
// Indexes
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_path_idx ON track(file_path)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_name_idx ON track(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS artist_name_idx ON artist(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS release_name_idx ON release(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_artist_idx ON track(artist_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_release_idx ON track(release_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS cluster_name_idx ON cluster(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS cluster_type_name_idx ON cluster_type(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS tracklist_name ON tracklist(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS tracklist_name_idx ON tracklist(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_feature_type_name_idx ON track_feature_type(name)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_feature_type_idx ON track_feature(type_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_feature_track_idx ON track_feature(track_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_feature_type_track_idx ON track_feature(type_id, track_id)");
|
||||
}
|
||||
|
||||
_users = new UserDatabase(_session);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Database {
|
||||
ScanSettings::pointer
|
||||
ScanSettings::get(Wt::Dbo::Session& session)
|
||||
{
|
||||
ScanSettings::pointer settings = session.find<ScanSettings>();
|
||||
pointer settings = session.find<ScanSettings>();
|
||||
if (!settings)
|
||||
{
|
||||
settings = session.add(std::make_unique<ScanSettings>());
|
||||
@@ -81,16 +81,17 @@ ScanSettings::setClusterTypes(const std::set<std::string>& clusterTypeNames)
|
||||
assert(session());
|
||||
|
||||
// Create any missing cluster type
|
||||
for (auto clusterTypeName : clusterTypeNames)
|
||||
for (const auto& clusterTypeName : clusterTypeNames)
|
||||
{
|
||||
auto clusterType = ClusterType::getByName(*session(), clusterTypeName);
|
||||
if (!clusterType)
|
||||
{
|
||||
LMS_LOG(DB, INFO) << "Creating cluster type " << clusterTypeName;
|
||||
clusterType = ClusterType::create(*session(), clusterTypeName);
|
||||
_clusterTypes.insert(clusterType);
|
||||
|
||||
needRescan = true;
|
||||
}
|
||||
_clusterTypes.insert(clusterType);
|
||||
}
|
||||
|
||||
// Delete no longer existing cluster types
|
||||
@@ -101,7 +102,6 @@ ScanSettings::setClusterTypes(const std::set<std::string>& clusterTypeNames)
|
||||
{
|
||||
LMS_LOG(DB, INFO) << "Deleting cluster type " << clusterType->getName();
|
||||
clusterType.remove();
|
||||
needRescan = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,5 +109,6 @@ ScanSettings::setClusterTypes(const std::set<std::string>& clusterTypeNames)
|
||||
_scanVersion += 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
namespace Database {
|
||||
|
||||
class ClusterType;
|
||||
|
||||
class ScanSettings : public Wt::Dbo::Dbo<ScanSettings>
|
||||
{
|
||||
public:
|
||||
@@ -39,8 +40,6 @@ class ScanSettings : public Wt::Dbo::Dbo<ScanSettings>
|
||||
Monthly
|
||||
};
|
||||
|
||||
ScanSettings() {}
|
||||
|
||||
static pointer get(Wt::Dbo::Session& session);
|
||||
|
||||
// Getters
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SimilaritySettings.hpp"
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "TrackFeature.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
std::set<std::string> defaultTrackFeaturesNames =
|
||||
{
|
||||
"lowlevel.average_loudness",
|
||||
"lowlevel.barkbands_flatness_db.mean",
|
||||
"lowlevel.dissonance.mean",
|
||||
"lowlevel.dynamic_complexity",
|
||||
"lowlevel.hfc.mean", // GOOD
|
||||
"lowlevel.melbands_crest.mean",
|
||||
"lowlevel.melbands_kurtosis.mean",
|
||||
"lowlevel.melbands_skewness.mean",
|
||||
"lowlevel.melbands_spread.mean",
|
||||
"lowlevel.pitch_salience.mean",
|
||||
"lowlevel.pitch_salience.var",
|
||||
"lowlevel.silence_rate_30dB.mean",
|
||||
"lowlevel.silence_rate_60dB.mean",
|
||||
"lowlevel.spectral_centroid.mean",
|
||||
"lowlevel.spectral_complexity.mean",
|
||||
"lowlevel.spectral_decrease.mean",
|
||||
"lowlevel.spectral_energy.mean",
|
||||
"lowlevel.spectral_energyband_high.mean",
|
||||
"lowlevel.spectral_energyband_low.mean",
|
||||
"lowlevel.spectral_energyband_middle_high.mean",
|
||||
"lowlevel.spectral_energyband_middle_low.mean",
|
||||
"lowlevel.spectral_entropy.mean",
|
||||
"lowlevel.spectral_flux.mean",
|
||||
"lowlevel.spectral_kurtosis.mean",
|
||||
"lowlevel.spectral_rms.mean",
|
||||
"lowlevel.spectral_skewness.mean",
|
||||
"lowlevel.spectral_spread.mean",
|
||||
"lowlevel.spectral_strongpeak.mean",
|
||||
"lowlevel.zerocrossingrate.mean",
|
||||
"rhythm.beats_loudness.mean", // BAD
|
||||
"rhythm.bpm",
|
||||
"tonal.chords_changes_rate", // OK
|
||||
"tonal.chords_number_rate", // BAD
|
||||
"tonal.chords_strength.mean", // OK
|
||||
"tonal.hpcp_entropy.mean", // GOOD
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Database {
|
||||
|
||||
|
||||
SimilaritySettings::pointer
|
||||
SimilaritySettings::get(Wt::Dbo::Session& session)
|
||||
{
|
||||
pointer settings = session.find<SimilaritySettings>();
|
||||
if (!settings)
|
||||
{
|
||||
settings = session.add(std::make_unique<SimilaritySettings>());
|
||||
settings.modify()->setTrackFeatureTypes(defaultTrackFeaturesNames);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::vector<Wt::Dbo::ptr<TrackFeatureType>>
|
||||
SimilaritySettings::getTrackFeatureTypes() const
|
||||
{
|
||||
return std::vector<Wt::Dbo::ptr<TrackFeatureType>>(_trackFeatureTypes.begin(), _trackFeatureTypes.end());
|
||||
}
|
||||
|
||||
void
|
||||
SimilaritySettings::setTrackFeatureTypes(const std::set<std::string>& featuresNames)
|
||||
{
|
||||
bool needRescan = false;
|
||||
assert(session());
|
||||
|
||||
// Create any missing feature type
|
||||
for (const auto& featureName : featuresNames)
|
||||
{
|
||||
auto featureType = TrackFeatureType::getByName(*session(), featureName);
|
||||
if (!featureType)
|
||||
{
|
||||
LMS_LOG(DB, INFO) << "Creating feature type " << featureName;
|
||||
featureType = TrackFeatureType::create(*session(), featureName);
|
||||
_trackFeatureTypes.insert(featureType);
|
||||
|
||||
needRescan = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete no longer existing feature type
|
||||
for (auto trackFeatureType : _trackFeatureTypes)
|
||||
{
|
||||
if (std::none_of(featuresNames.begin(), featuresNames.end(),
|
||||
[trackFeatureType](const std::string& name) { return name == trackFeatureType->getName(); }))
|
||||
{
|
||||
LMS_LOG(DB, INFO) << "Deleting track feature type " << trackFeatureType->getName();
|
||||
trackFeatureType.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (needRescan)
|
||||
_scanVersion += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/Dbo/Dbo.h>
|
||||
|
||||
namespace Database {
|
||||
|
||||
class TrackFeature;
|
||||
class TrackFeatureType;
|
||||
|
||||
class SimilaritySettings : public Wt::Dbo::Dbo<SimilaritySettings>
|
||||
{
|
||||
public:
|
||||
using pointer = Wt::Dbo::ptr<SimilaritySettings>;
|
||||
|
||||
static pointer get(Wt::Dbo::Session& session);
|
||||
|
||||
std::size_t getVersion() const { return _scanVersion; }
|
||||
|
||||
std::vector<Wt::Dbo::ptr<TrackFeatureType>> getTrackFeatureTypes() const;
|
||||
void setTrackFeatureTypes(const std::set<std::string>& featureTypeNames);
|
||||
|
||||
void setNetworkData(std::string data) { _refFeaturesData = data; }
|
||||
const std::string& getNetworkData() const { return _refFeaturesData; }
|
||||
|
||||
void setNormalizationData(std::string data) { _normalizationData = data; }
|
||||
const std::string& getNormalizationData() const { return _normalizationData; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _scanVersion, "settings_version");
|
||||
Wt::Dbo::field(a, _normalizationData, "normalization_data");
|
||||
Wt::Dbo::field(a, _refFeaturesData, "ref_features_data");
|
||||
Wt::Dbo::hasMany(a, _trackFeatureTypes, Wt::Dbo::ManyToOne, "similarity_settings");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int _scanVersion = 0;
|
||||
std::string _normalizationData;
|
||||
std::string _refFeaturesData;
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<TrackFeatureType>> _trackFeatureTypes;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Artist.hpp"
|
||||
#include "Cluster.hpp"
|
||||
#include "Release.hpp"
|
||||
#include "TrackFeature.hpp"
|
||||
#include "SqlQuery.hpp"
|
||||
|
||||
namespace Database {
|
||||
@@ -107,6 +108,25 @@ Track::getLastAdded(Wt::Dbo::Session& session, Wt::WDateTime after, int limit)
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Track::pointer>
|
||||
Track::getAllWithMBIDAndMissingFeatures(Wt::Dbo::Session& session)
|
||||
{
|
||||
Wt::Dbo::collection<pointer> res = session.query<pointer>
|
||||
("SELECT t FROM track t")
|
||||
.where("LENGTH(t.mbid) > 0")
|
||||
.where("NOT EXISTS (SELECT * FROM track_feature t_f WHERE t_f.track_id = t.id)");
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Track::pointer>
|
||||
Track::getAllWithFeatures(Wt::Dbo::Session& session)
|
||||
{
|
||||
Wt::Dbo::collection<pointer> res = session.query<pointer>
|
||||
("SELECT t FROM track t")
|
||||
.where("EXISTS (SELECT * from track_feature t_f WHERE t_f.track_id = t.id)");
|
||||
return std::vector<pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
std::vector<Cluster::pointer>
|
||||
Track::getClusters(void) const
|
||||
{
|
||||
@@ -115,6 +135,12 @@ Track::getClusters(void) const
|
||||
return clusters;
|
||||
}
|
||||
|
||||
bool
|
||||
Track::hasTrackFeatures() const
|
||||
{
|
||||
return !_trackFeatures.empty();
|
||||
}
|
||||
|
||||
static
|
||||
Wt::Dbo::Query< Track::pointer >
|
||||
getQuery(Wt::Dbo::Session& session,
|
||||
@@ -236,6 +262,18 @@ Track::getCopyrightURL() const
|
||||
return _copyrightURL != "" ? boost::make_optional<std::string>(_copyrightURL) : boost::none;
|
||||
}
|
||||
|
||||
Wt::Dbo::ptr<TrackFeature>
|
||||
Track::getTrackFeature(Wt::Dbo::ptr<TrackFeatureType> type) const
|
||||
{
|
||||
assert(self());
|
||||
assert(IdIsValid(self()->id()));
|
||||
assert(session());
|
||||
|
||||
return session()->find<TrackFeature>()
|
||||
.where("type_id = ?").bind(type.id())
|
||||
.where("track_id = ?").bind(self()->id());
|
||||
}
|
||||
|
||||
std::vector<std::vector<Cluster::pointer>>
|
||||
Track::getClusterGroups(std::vector<ClusterType::pointer> clusterTypes, std::size_t size) const
|
||||
{
|
||||
|
||||
+17
-3
@@ -36,15 +36,17 @@ namespace Database {
|
||||
class Artist;
|
||||
class Cluster;
|
||||
class ClusterType;
|
||||
class TrackListEntry;
|
||||
class Release;
|
||||
class TrackFeature;
|
||||
class TrackFeatureType;
|
||||
class TrackListEntry;
|
||||
class TrackStats;
|
||||
|
||||
class Track : public Wt::Dbo::Dbo<Track>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Wt::Dbo::ptr<Track> pointer;
|
||||
using pointer = Wt::Dbo::ptr<Track>;
|
||||
|
||||
Track() {}
|
||||
Track(const boost::filesystem::path& p);
|
||||
@@ -68,6 +70,8 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
static std::vector<pointer> getMBIDDuplicates(Wt::Dbo::Session& session);
|
||||
static std::vector<pointer> getChecksumDuplicates(Wt::Dbo::Session& session);
|
||||
static std::vector<pointer> getLastAdded(Wt::Dbo::Session& session, Wt::WDateTime after, int size = 1);
|
||||
static std::vector<pointer> getAllWithMBIDAndMissingFeatures(Wt::Dbo::Session& session); // nested transaction
|
||||
static std::vector<pointer> getAllWithFeatures(Wt::Dbo::Session& session); // nested transaction
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, const boost::filesystem::path& p);
|
||||
@@ -76,7 +80,8 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
static void removeClusters(std::string type);
|
||||
|
||||
// Accessors
|
||||
void setScanVersion(std::size_t version) {_scanVersion = version; }
|
||||
void setScanVersion(std::size_t version) { _scanVersion = version; }
|
||||
void setSimilarityScanVersion(std::size_t version) { _similarityScanVersion = version; }
|
||||
void setTrackNumber(int num) { _trackNumber = num; }
|
||||
void setTotalTrackNumber(int num) { _totalTrackNumber = num; }
|
||||
void setDiscNumber(int num) { _discNumber = num; }
|
||||
@@ -96,8 +101,10 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
void setArtist(Wt::Dbo::ptr<Artist> artist) { _artist = artist; }
|
||||
void setRelease(Wt::Dbo::ptr<Release> release) { _release = release; }
|
||||
void eraseClusters() { _clusters.clear(); }
|
||||
void eraseFeatures() { _trackFeatures.clear(); }
|
||||
|
||||
std::size_t getScanVersion() const { return _scanVersion; }
|
||||
std::size_t getSimilarityScanVersion() const { return _similarityScanVersion; }
|
||||
boost::optional<std::size_t> getTrackNumber() const;
|
||||
boost::optional<std::size_t> getTotalTrackNumber() const;
|
||||
boost::optional<std::size_t> getDiscNumber() const;
|
||||
@@ -117,6 +124,9 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
Wt::Dbo::ptr<Artist> getArtist() const { return _artist; }
|
||||
Wt::Dbo::ptr<Release> getRelease() const { return _release; }
|
||||
std::vector<Wt::Dbo::ptr<Cluster>> getClusters() const;
|
||||
std::vector<Wt::Dbo::ptr<TrackFeature>> getTrackFeatures() const; // ordered by feature's name
|
||||
bool hasTrackFeatures() const;
|
||||
Wt::Dbo::ptr<TrackFeature> getTrackFeature(Wt::Dbo::ptr<TrackFeatureType> type) const;
|
||||
|
||||
std::vector<std::vector<Wt::Dbo::ptr<Cluster>>> getClusterGroups(std::vector<Wt::Dbo::ptr<ClusterType>> clusterTypes, std::size_t size) const;
|
||||
|
||||
@@ -124,6 +134,7 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _scanVersion, "scan_version");
|
||||
Wt::Dbo::field(a, _similarityScanVersion, "similarity_version");
|
||||
Wt::Dbo::field(a, _trackNumber, "track_number");
|
||||
Wt::Dbo::field(a, _totalTrackNumber, "total_track_number");
|
||||
Wt::Dbo::field(a, _discNumber, "disc_number");
|
||||
@@ -145,6 +156,7 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::hasMany(a, _clusters, Wt::Dbo::ManyToMany, "track_cluster", "", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::hasMany(a, _playlistEntries, Wt::Dbo::ManyToOne, "track");
|
||||
Wt::Dbo::hasMany(a, _trackFeatures, Wt::Dbo::ManyToOne, "track");
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -154,6 +166,7 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
static const std::size_t _maxCopyrightURLLength = 128;
|
||||
|
||||
int _scanVersion = 0;
|
||||
int _similarityScanVersion = 0;
|
||||
int _trackNumber = 0;
|
||||
int _totalTrackNumber = 0;
|
||||
int _discNumber = 0;
|
||||
@@ -178,6 +191,7 @@ class Track : public Wt::Dbo::Dbo<Track>
|
||||
Wt::Dbo::ptr<Release> _release;
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<Cluster>> _clusters;
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<TrackListEntry>> _playlistEntries;
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<TrackFeature>> _trackFeatures;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TrackFeature.hpp"
|
||||
|
||||
#include "SimilaritySettings.hpp"
|
||||
#include "Track.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
TrackFeatureType::TrackFeatureType(std::string name)
|
||||
: _name(name)
|
||||
{
|
||||
}
|
||||
|
||||
TrackFeatureType::pointer
|
||||
TrackFeatureType::getByName(Wt::Dbo::Session& session, std::string name)
|
||||
{
|
||||
return session.find<TrackFeatureType>().where("name = ?").bind(name);
|
||||
}
|
||||
|
||||
TrackFeatureType::pointer
|
||||
TrackFeatureType::create(Wt::Dbo::Session& session, std::string name)
|
||||
{
|
||||
return session.add(std::make_unique<TrackFeatureType>(name));
|
||||
}
|
||||
|
||||
|
||||
TrackFeature::TrackFeature(Wt::Dbo::ptr<TrackFeatureType> type, Wt::Dbo::ptr<Track> track, double value)
|
||||
: _type(type),
|
||||
_track(track),
|
||||
_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
TrackFeature::pointer
|
||||
TrackFeature::create(Wt::Dbo::Session& session, Wt::Dbo::ptr<TrackFeatureType> type, Wt::Dbo::ptr<Track> track, double value)
|
||||
{
|
||||
return session.add(std::make_unique<TrackFeature>(type, track, value));
|
||||
}
|
||||
|
||||
} // namespace Database
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Wt/Dbo/Dbo.h>
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
class Track;
|
||||
class SimilaritySettings;
|
||||
|
||||
class TrackFeatureType : public Wt::Dbo::Dbo<TrackFeatureType>
|
||||
{
|
||||
public:
|
||||
using pointer = Wt::Dbo::ptr<TrackFeatureType>;
|
||||
|
||||
TrackFeatureType() = default;
|
||||
TrackFeatureType(std::string name);
|
||||
|
||||
// Find utility
|
||||
static pointer getByName(Wt::Dbo::Session& session, std::string name);
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, std::string name);
|
||||
|
||||
// Accessors
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
Wt::Dbo::belongsTo(a, _similaritySettings, "similarity_settings", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string _name;
|
||||
|
||||
Wt::Dbo::ptr<SimilaritySettings> _similaritySettings;
|
||||
};
|
||||
|
||||
class TrackFeature : public Wt::Dbo::Dbo<TrackFeature>
|
||||
{
|
||||
public:
|
||||
|
||||
using pointer = Wt::Dbo::ptr<TrackFeature>;
|
||||
|
||||
TrackFeature() = default;
|
||||
TrackFeature(Wt::Dbo::ptr<TrackFeatureType> type, Wt::Dbo::ptr<Track> track, double value);
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr<TrackFeatureType> type, Wt::Dbo::ptr<Track> track, double value);
|
||||
|
||||
Wt::Dbo::ptr<TrackFeatureType> getType() const { return _type; }
|
||||
double getValue() const { return _value; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _value, "value");
|
||||
Wt::Dbo::belongsTo(a, _type, "type", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Wt::Dbo::ptr<TrackFeatureType> _type;
|
||||
Wt::Dbo::ptr<Track> _track;
|
||||
double _value = 0.;
|
||||
};
|
||||
|
||||
|
||||
} // namespace database
|
||||
|
||||
|
||||
Reference in New Issue
Block a user