Simplified db schema
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 <boost/foreach.hpp>
|
||||
|
||||
#include "AudioTypes.hpp"
|
||||
|
||||
#include "SqlQuery.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
|
||||
Artist::Artist(const std::string& name)
|
||||
: _name(std::string(name, 0 , _maxNameLength))
|
||||
{
|
||||
}
|
||||
|
||||
// Accesoors
|
||||
Artist::pointer
|
||||
Artist::getByName(Wt::Dbo::Session& session, const std::string& name)
|
||||
{
|
||||
return session.find<Artist>().where("name = ?").bind( std::string(name, 0, _maxNameLength) );
|
||||
}
|
||||
|
||||
// Create
|
||||
Artist::pointer
|
||||
Artist::create(Wt::Dbo::Session& session, const std::string& name)
|
||||
{
|
||||
return session.add( new Artist( name ) );
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
pointer res = getByName(session, "<None>");
|
||||
if (!res)
|
||||
res = create(session, "<None>");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Wt::Dbo::collection<Artist::pointer>
|
||||
Artist::getAll(Wt::Dbo::Session& session, int offset, int size)
|
||||
{
|
||||
return session.find<Artist>().offset(offset).limit(size);
|
||||
}
|
||||
|
||||
Wt::Dbo::collection<Artist::pointer>
|
||||
Artist::getAllOrphans(Wt::Dbo::Session& session)
|
||||
{
|
||||
return session.query< Wt::Dbo::ptr<Artist> >("select a from artist a LEFT OUTER JOIN Track t ON a.id = t.artist_id WHERE t.id IS NULL");
|
||||
}
|
||||
|
||||
Wt::Dbo::collection<Artist::pointer>
|
||||
Artist::getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
int offset, int size)
|
||||
{
|
||||
std::string sqlQuery = "SELECT a FROM artist a";
|
||||
|
||||
if (!genreIds.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN genre g ON g.id = t_g.genre_id";
|
||||
sqlQuery += " INNER JOIN track t ON t.id = t_g.track_id AND t.artist_id = a.id";
|
||||
sqlQuery += " INNER JOIN track_genre t_g ON t_g.track_id = t.id AND t_g.genre_id = g.id";
|
||||
}
|
||||
|
||||
WhereClause where;
|
||||
{
|
||||
WhereClause genreWhere;
|
||||
|
||||
for (std::size_t i = 0; i < genreIds.size(); ++i)
|
||||
genreWhere.Or( WhereClause("g.id = ?") );
|
||||
|
||||
where.And(genreWhere);
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<Artist::pointer> query = session.query<Artist::pointer>( sqlQuery + " " + where.get() ).offset(offset).limit(size);
|
||||
|
||||
BOOST_FOREACH(const Genre::id_type genreId, genreIds)
|
||||
query.bind(genreId);
|
||||
|
||||
query.groupBy("a");
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
+24
-109
@@ -33,8 +33,6 @@
|
||||
namespace Database {
|
||||
|
||||
class Track;
|
||||
class Release;
|
||||
class Artist;
|
||||
|
||||
class Genre
|
||||
{
|
||||
@@ -73,99 +71,6 @@ class Genre
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Track> > _tracks;
|
||||
};
|
||||
|
||||
|
||||
class Artist
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Wt::Dbo::ptr<Artist> pointer;
|
||||
typedef Wt::Dbo::dbo_traits<Artist>::IdType id_type;
|
||||
|
||||
Artist() {}
|
||||
Artist(const std::string& p_name);
|
||||
|
||||
// Accessors
|
||||
static pointer getByName(Wt::Dbo::Session& session, const std::string& name);
|
||||
static pointer getNone(Wt::Dbo::Session& session);
|
||||
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session, int offset = -1, int size = -1);
|
||||
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
int offset = -1, int size = -1);
|
||||
static Wt::Dbo::collection<pointer> getAllOrphans(Wt::Dbo::Session& session);
|
||||
|
||||
const std::string& getName(void) const { return _name; }
|
||||
const Wt::Dbo::collection< Wt::Dbo::ptr<Track> >& getTracks(void) const { return _tracks;}
|
||||
|
||||
// Create
|
||||
static pointer create(Wt::Dbo::Session& session, const std::string& name);
|
||||
|
||||
bool isNone(void) const;
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
|
||||
Wt::Dbo::hasMany(a, _tracks, Wt::Dbo::ManyToOne, "artist");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static const std::size_t _maxNameLength = 128;
|
||||
|
||||
std::string _name;
|
||||
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Track> > _tracks; // Tracks of this artist
|
||||
};
|
||||
|
||||
|
||||
// Album release
|
||||
class Release
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Wt::Dbo::ptr<Release> pointer;
|
||||
typedef Wt::Dbo::dbo_traits<Release>::IdType id_type;
|
||||
|
||||
Release() {}
|
||||
Release(const std::string& name);
|
||||
|
||||
// Accessors
|
||||
static pointer getByName(Wt::Dbo::Session& session, const std::string& name);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static pointer getNone(Wt::Dbo::Session& session);
|
||||
static Wt::Dbo::collection<pointer> getAllOrphans(Wt::Dbo::Session& session);
|
||||
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Artist::id_type>& artistIds,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
int offset = -1, int size = -1);
|
||||
|
||||
// Create
|
||||
static pointer create(Wt::Dbo::Session& session, const std::string& name);
|
||||
|
||||
std::string getName() const { return _name; }
|
||||
bool isNone(void) const;
|
||||
const Wt::Dbo::collection<Wt::Dbo::ptr<Track> >& getTracks(void) const { return _tracks;}
|
||||
boost::posix_time::time_duration getDuration(void) const;
|
||||
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
|
||||
Wt::Dbo::hasMany(a, _tracks, Wt::Dbo::ManyToOne, "release");
|
||||
}
|
||||
|
||||
private:
|
||||
static const std::size_t _maxNameLength = 128;
|
||||
std::string _name;
|
||||
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Track> > _tracks; // Tracks in the release
|
||||
};
|
||||
|
||||
|
||||
class Track
|
||||
{
|
||||
public:
|
||||
@@ -174,25 +79,37 @@ class Track
|
||||
typedef Wt::Dbo::dbo_traits<Track>::IdType id_type;
|
||||
|
||||
Track() {}
|
||||
Track(const boost::filesystem::path& p, Artist::pointer artist, Release::pointer release);
|
||||
Track(const boost::filesystem::path& p);
|
||||
|
||||
// Find utilities
|
||||
static pointer getByPath(Wt::Dbo::Session& session, const boost::filesystem::path& p);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static Wt::Dbo::collection< pointer > getAll(Wt::Dbo::Session& session);
|
||||
static Wt::Dbo::collection< pointer > getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Artist::id_type>& artistIds,
|
||||
const std::vector<Release::id_type>& releaseIds,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
const std::vector<std::string>& artists, // OR filter if many
|
||||
const std::vector<std::string>& releases, // OR filter if many
|
||||
const std::vector<std::string>& genres, // OR filter if many
|
||||
int offset = -1, int size = -1);
|
||||
|
||||
static std::vector<std::string> getReleases(Wt::Dbo::Session& session,
|
||||
const std::vector<std::string>& artists, // OR filter if many
|
||||
const std::vector<std::string>& genres, // OR filter if many
|
||||
int offset = -1, int size = -1);
|
||||
|
||||
static std::vector<std::string> getArtists(Wt::Dbo::Session& session,
|
||||
const std::vector<std::string>& genres, // OR filter
|
||||
int offset = -1, int size = -1);
|
||||
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, const boost::filesystem::path& p, Artist::pointer artist, Release::pointer release);
|
||||
static pointer create(Wt::Dbo::Session& session, const boost::filesystem::path& p);
|
||||
|
||||
// Accessors
|
||||
void setTrackNumber(int num) { _trackNumber = num; }
|
||||
void setDiscNumber(int num) { _discNumber = num; }
|
||||
void setName(const std::string& name) { _name = std::string(name, 0, _maxNameLength); }
|
||||
void setArtistName(const std::string& name) { _artistName = std::string(name, 0, _maxNameLength); }
|
||||
void setReleaseName(const std::string& name) { _releaseName = std::string(name, 0, _maxNameLength); }
|
||||
void setDuration(boost::posix_time::time_duration duration) { _duration = duration; }
|
||||
void setLastWriteTime(boost::posix_time::ptime time) { _fileLastWrite = time; }
|
||||
void setChecksum(const std::vector<unsigned char>& checksum) { _fileChecksum = checksum; }
|
||||
@@ -200,18 +117,16 @@ class Track
|
||||
void setOriginalDate(const boost::posix_time::ptime& date) { _originalDate = date; }
|
||||
void setGenres(const std::string& genreList) { _genreList = genreList; }
|
||||
void setGenres(std::vector<Genre::pointer> genres);
|
||||
void setArtist(Artist::pointer artist) { _artist = artist; }
|
||||
void setRelease(Release::pointer release) { _release = release; }
|
||||
|
||||
int getTrackNumber(void) const { return _trackNumber; }
|
||||
int getDiscNumber(void) const { return _discNumber; }
|
||||
std::string getName(void) const { return _name; }
|
||||
std::string getArtistName(void) const { return _artistName; }
|
||||
std::string getReleaseName(void) const { return _releaseName; }
|
||||
const std::string& getPath(void) const { return _filePath; }
|
||||
boost::posix_time::time_duration getDuration(void) const { return _duration; }
|
||||
boost::posix_time::ptime getDate(void) const { return _date; }
|
||||
boost::posix_time::ptime getOriginalDate(void) const { return _originalDate; }
|
||||
Artist::pointer getArtist(void) const { return _artist; }
|
||||
Release::pointer getRelease(void) const { return _release; }
|
||||
bool hasGenre(Genre::pointer genre) const { return _genres.count(genre); }
|
||||
std::vector< Genre::pointer > getGenres(void) const;
|
||||
|
||||
@@ -224,6 +139,8 @@ class Track
|
||||
Wt::Dbo::field(a, _trackNumber, "track_number");
|
||||
Wt::Dbo::field(a, _discNumber, "disc_number");
|
||||
Wt::Dbo::field(a, _name, "name");
|
||||
Wt::Dbo::field(a, _artistName, "artist_name");
|
||||
Wt::Dbo::field(a, _releaseName, "release_name");
|
||||
Wt::Dbo::field(a, _duration, "duration");
|
||||
Wt::Dbo::field(a, _date, "date");
|
||||
Wt::Dbo::field(a, _originalDate, "original_date");
|
||||
@@ -232,8 +149,6 @@ class Track
|
||||
Wt::Dbo::field(a, _fileLastWrite, "last_write");
|
||||
Wt::Dbo::field(a, _fileChecksum, "checksum");
|
||||
Wt::Dbo::hasMany(a, _genres, Wt::Dbo::ManyToMany, "track_genre", "", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -243,6 +158,8 @@ class Track
|
||||
int _trackNumber;
|
||||
int _discNumber;
|
||||
std::string _name;
|
||||
std::string _artistName;
|
||||
std::string _releaseName;
|
||||
boost::posix_time::time_duration _duration;
|
||||
boost::posix_time::ptime _date;
|
||||
boost::posix_time::ptime _originalDate;
|
||||
@@ -251,9 +168,7 @@ class Track
|
||||
std::vector<unsigned char> _fileChecksum;
|
||||
boost::posix_time::ptime _fileLastWrite;
|
||||
|
||||
Artist::pointer _artist; // Associated Artist
|
||||
Release::pointer _release; // Associated Release
|
||||
Wt::Dbo::collection< Genre::pointer > _genres; // Tracks in the release
|
||||
Wt::Dbo::collection< Genre::pointer > _genres; // Tracks that belong to this genre
|
||||
};
|
||||
|
||||
} // namespace database
|
||||
|
||||
@@ -85,9 +85,6 @@ _dbBackend( db.string() )
|
||||
_session.setConnection(_dbBackend);
|
||||
_session.mapClass<Database::Genre>("genre");
|
||||
_session.mapClass<Database::Track>("track");
|
||||
_session.mapClass<Database::Artist>("artist");
|
||||
_session.mapClass<Database::Release>("release");
|
||||
_session.mapClass<Database::Release>("release");
|
||||
_session.mapClass<Database::Video>("video");
|
||||
_session.mapClass<Database::MediaDirectory>("media_directory");
|
||||
_session.mapClass<Database::MediaDirectorySettings>("media_directory_settings");
|
||||
@@ -99,6 +96,8 @@ _dbBackend( db.string() )
|
||||
|
||||
try {
|
||||
_session.createTables();
|
||||
_dbBackend.executeSql("CREATE INDEX artist_name_idx ON track(artist_name)");
|
||||
_dbBackend.executeSql("CREATE INDEX release_name_idx ON track(release_name)");
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
LMS_LOG(MOD_DB, SEV_ERROR) << "Cannot create tables: " << e.what();
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 <boost/foreach.hpp>
|
||||
|
||||
#include "SqlQuery.hpp"
|
||||
|
||||
#include "AudioTypes.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
Release::Release(const std::string& name)
|
||||
: _name(std::string(name, 0, _maxNameLength))
|
||||
{
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::getByName(Wt::Dbo::Session& session, const std::string& name)
|
||||
{
|
||||
return session.find<Release>().where("name = ?").bind( std::string(name, 0, _maxNameLength) );
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::getById(Wt::Dbo::Session& session, id_type id)
|
||||
{
|
||||
return session.find<Release>().where("id = ?").bind(id);
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::getNone(Wt::Dbo::Session& session)
|
||||
{
|
||||
pointer res = getByName(session, "<None>");
|
||||
if (!res)
|
||||
res = create(session, "<None>");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::create(Wt::Dbo::Session& session, const std::string& name)
|
||||
{
|
||||
return session.add(new Release(name));
|
||||
}
|
||||
|
||||
Wt::Dbo::collection<Release::pointer>
|
||||
Release::getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Artist::id_type>& artistIds,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
int offset, int size)
|
||||
{
|
||||
std::string sqlQuery = "SELECT r FROM release r";
|
||||
|
||||
if (!artistIds.empty() || !genreIds.empty())
|
||||
sqlQuery += " INNER JOIN track t ON t.release_id = r.id";
|
||||
|
||||
if (!artistIds.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN artist a ON a.id = t.artist_id";
|
||||
}
|
||||
|
||||
if (!genreIds.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN genre g ON g.id = t_g.genre_id";
|
||||
sqlQuery += " INNER JOIN track_genre t_g ON t_g.track_id = t.id AND t_g.genre_id = g.id";
|
||||
}
|
||||
|
||||
WhereClause where;
|
||||
{
|
||||
WhereClause artistWhere;
|
||||
|
||||
for (std::size_t i = 0; i < artistIds.size(); ++i)
|
||||
artistWhere.Or( WhereClause("a.id = ?") );
|
||||
|
||||
where.And(artistWhere);
|
||||
}
|
||||
|
||||
{
|
||||
WhereClause genreWhere;
|
||||
|
||||
for (std::size_t i = 0; i < genreIds.size(); ++i)
|
||||
genreWhere.Or( WhereClause("g.id = ?") );
|
||||
|
||||
where.And(genreWhere);
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<Release::pointer> query = session.query<Release::pointer>( sqlQuery + " " + where.get() ).offset(offset).limit(size);
|
||||
|
||||
BOOST_FOREACH(const Artist::id_type artistId, artistIds)
|
||||
query.bind(artistId);
|
||||
|
||||
BOOST_FOREACH(const Genre::id_type genreId, genreIds)
|
||||
query.bind(genreId);
|
||||
|
||||
query.groupBy("r");
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
boost::posix_time::time_duration
|
||||
Release::getDuration(void) const
|
||||
{
|
||||
typedef Wt::Dbo::collection< Wt::Dbo::ptr<Track> > Tracks;
|
||||
|
||||
boost::posix_time::time_duration res;
|
||||
|
||||
for (Tracks::const_iterator it = _tracks.begin(); it != _tracks.end(); ++it)
|
||||
res += (*it)->getDuration();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Wt::Dbo::collection<Release::pointer>
|
||||
Release::getAllOrphans(Wt::Dbo::Session& session)
|
||||
{
|
||||
return session.query< Wt::Dbo::ptr<Release> >("select r from release r LEFT OUTER JOIN Track t ON r.id = t.release_id WHERE t.id IS NULL");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Database
|
||||
+104
-28
@@ -25,13 +25,11 @@
|
||||
|
||||
namespace Database {
|
||||
|
||||
Track::Track(const boost::filesystem::path& p, Artist::pointer artist, Release::pointer release)
|
||||
Track::Track(const boost::filesystem::path& p)
|
||||
:
|
||||
_trackNumber(0),
|
||||
_discNumber(0),
|
||||
_filePath( p.string() ),
|
||||
_artist(artist),
|
||||
_release(release)
|
||||
_filePath( p.string() )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,9 +59,9 @@ Track::getById(Wt::Dbo::Session& session, id_type id)
|
||||
|
||||
|
||||
Track::pointer
|
||||
Track::create(Wt::Dbo::Session& session, const boost::filesystem::path& p, Artist::pointer artist, Release::pointer release)
|
||||
Track::create(Wt::Dbo::Session& session, const boost::filesystem::path& p)
|
||||
{
|
||||
return session.add(new Track(p, artist, release) );
|
||||
return session.add(new Track(p) );
|
||||
}
|
||||
|
||||
Wt::Dbo::collection< Track::pointer >
|
||||
@@ -82,20 +80,14 @@ Track::getGenres(void) const
|
||||
|
||||
Wt::Dbo::collection< Track::pointer >
|
||||
Track::getAll(Wt::Dbo::Session& session,
|
||||
const std::vector<Artist::id_type>& artistIds,
|
||||
const std::vector<Release::id_type>& releaseIds,
|
||||
const std::vector<Genre::id_type>& genreIds,
|
||||
const std::vector<std::string>& artists,
|
||||
const std::vector<std::string>& releases,
|
||||
const std::vector<std::string>& genres,
|
||||
int offset, int size)
|
||||
{
|
||||
std::string sqlQuery = "SELECT t FROM track t";
|
||||
|
||||
if (!artistIds.empty())
|
||||
sqlQuery += " INNER JOIN artist a ON a.id = t.artist_id";
|
||||
|
||||
if (!releaseIds.empty())
|
||||
sqlQuery += " INNER JOIN release r ON r.id = t.release_id";
|
||||
|
||||
if (!genreIds.empty())
|
||||
if (!genres.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN genre g ON g.id = t_g.genre_id";
|
||||
sqlQuery += " INNER JOIN track_genre t_g ON t_g.track_id = t.id AND t_g.genre_id = g.id";
|
||||
@@ -106,8 +98,8 @@ Track::getAll(Wt::Dbo::Session& session,
|
||||
{
|
||||
WhereClause artistWhere;
|
||||
|
||||
for (std::size_t i = 0; i < artistIds.size(); ++i)
|
||||
artistWhere.Or( WhereClause("a.id = ?") );
|
||||
for (std::size_t i = 0; i < artists.size(); ++i)
|
||||
artistWhere.Or( WhereClause("t.artist_name = ?") );
|
||||
|
||||
where.And(artistWhere);
|
||||
}
|
||||
@@ -115,8 +107,8 @@ Track::getAll(Wt::Dbo::Session& session,
|
||||
{
|
||||
WhereClause releaseWhere;
|
||||
|
||||
for (std::size_t i = 0; i < releaseIds.size(); ++i)
|
||||
releaseWhere.Or( WhereClause("r.id = ?") );
|
||||
for (std::size_t i = 0; i < releases.size(); ++i)
|
||||
releaseWhere.Or( WhereClause("t.release_name = ?") );
|
||||
|
||||
where.And(releaseWhere);
|
||||
}
|
||||
@@ -124,8 +116,8 @@ Track::getAll(Wt::Dbo::Session& session,
|
||||
{
|
||||
WhereClause genreWhere;
|
||||
|
||||
for (std::size_t i = 0; i < genreIds.size(); ++i)
|
||||
genreWhere.Or( WhereClause("g.id = ?") );
|
||||
for (std::size_t i = 0; i < genres.size(); ++i)
|
||||
genreWhere.Or( WhereClause("g.name = ?") );
|
||||
|
||||
where.And(genreWhere);
|
||||
}
|
||||
@@ -133,20 +125,104 @@ Track::getAll(Wt::Dbo::Session& session,
|
||||
|
||||
Wt::Dbo::Query<Track::pointer> query = session.query<Track::pointer>( sqlQuery + " " + where.get() ).offset(offset).limit(size);
|
||||
|
||||
BOOST_FOREACH(const Artist::id_type artistId, artistIds)
|
||||
query.bind(artistId);
|
||||
BOOST_FOREACH(const std::string& artist, artists)
|
||||
query.bind(artist);
|
||||
|
||||
BOOST_FOREACH(const Release::id_type releaseId, releaseIds)
|
||||
query.bind(releaseId);
|
||||
BOOST_FOREACH(const std::string& release, releases)
|
||||
query.bind(release);
|
||||
|
||||
BOOST_FOREACH(const Genre::id_type genreId, genreIds)
|
||||
query.bind(genreId);
|
||||
BOOST_FOREACH(const std::string& genre, genres)
|
||||
query.bind(genre);
|
||||
|
||||
query.groupBy("t");
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
Track::getArtists(Wt::Dbo::Session& session,
|
||||
const std::vector<std::string>& genres,
|
||||
int offset, int size)
|
||||
{
|
||||
std::string sqlQuery = "SELECT t.artist_name FROM track t";
|
||||
|
||||
if (!genres.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN genre g ON g.id = t_g.genre_id";
|
||||
sqlQuery += " INNER JOIN track_genre t_g ON t_g.track_id = t.id AND t_g.genre_id = g.id";
|
||||
}
|
||||
|
||||
WhereClause whereClause;
|
||||
|
||||
for (std::size_t i = 0; i < genres.size(); ++i)
|
||||
whereClause.Or( WhereClause("g.name = ?") );
|
||||
|
||||
Wt::Dbo::Query<std::string> query = session.query<std::string>( sqlQuery + " " + whereClause.get() ).offset(offset).limit(size).groupBy("t.artist_name");
|
||||
|
||||
BOOST_FOREACH(const std::string& genre, genres)
|
||||
query.bind(genre);
|
||||
|
||||
typedef Wt::Dbo::collection< std::string > ArtistNames;
|
||||
ArtistNames artistNames(query);
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (ArtistNames::const_iterator it = artistNames.begin(); it != artistNames.end(); ++it)
|
||||
res.push_back((*it));
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
Track::getReleases(Wt::Dbo::Session& session,
|
||||
const std::vector<std::string>& artists,
|
||||
const std::vector<std::string>& genres,
|
||||
int offset, int size)
|
||||
{
|
||||
|
||||
std::string sqlQuery = "SELECT t.release_name FROM track t";
|
||||
|
||||
if (!genres.empty())
|
||||
{
|
||||
sqlQuery += " INNER JOIN genre g ON g.id = t_g.genre_id";
|
||||
sqlQuery += " INNER JOIN track_genre t_g ON t_g.track_id = t.id AND t_g.genre_id = g.id";
|
||||
}
|
||||
|
||||
WhereClause whereClause;
|
||||
|
||||
{
|
||||
WhereClause clause;
|
||||
|
||||
BOOST_FOREACH(const std::string& artist, artists)
|
||||
clause.Or( WhereClause("t.artist_name = ?") ).bind(artist);
|
||||
|
||||
whereClause.And(clause);
|
||||
}
|
||||
{
|
||||
WhereClause clause;
|
||||
|
||||
BOOST_FOREACH(const std::string& genre, genres)
|
||||
clause.Or( WhereClause("g.name = ?") ).bind(genre);
|
||||
|
||||
whereClause.And(clause);
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<std::string> query = session.query<std::string>( sqlQuery + " " + whereClause.get() ).offset(offset).limit(size).groupBy("t.release_name");
|
||||
|
||||
BOOST_FOREACH(const std::string& bindArg, whereClause.getBindArgs())
|
||||
query.bind(bindArg);
|
||||
|
||||
typedef Wt::Dbo::collection< std::string > ReleaseNames;
|
||||
ReleaseNames releaseNames(query);
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (ReleaseNames::const_iterator it = releaseNames.begin(); it != releaseNames.end(); ++it)
|
||||
res.push_back((*it));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Database
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user