WIP, Remote Client/Server, fist working track list

This commit is contained in:
emeric
2014-05-23 14:56:22 +02:00
parent d945f4623f
commit 61341a090a
19 changed files with 932 additions and 587 deletions
+26 -12
View File
@@ -21,7 +21,7 @@ class Artist
typedef Wt::Dbo::ptr<Artist> pointer;
typedef Wt::Dbo::dbo_traits<Artist>::IdType id_type;
Artist() {}
Artist(const std::string& p_name);
@@ -59,6 +59,7 @@ class Release
public:
typedef Wt::Dbo::ptr<Release> pointer;
typedef Wt::Dbo::dbo_traits<Release>::IdType id_type;
Release() {}
Release(const std::string& name);
@@ -67,13 +68,15 @@ class Release
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, Artist::id_type id, int offset = -1, int size = -1);
static Wt::Dbo::collection<pointer> getAll(Wt::Dbo::Session& session, std::vector<Artist::id_type> artistIds, int offset = -1, int size = -1);
// Create
static pointer create(Wt::Dbo::Session& session, const std::string& name);
std::string getName() const;
std::string getName() const { return _name; }
bool isNone(void) 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)
@@ -95,6 +98,7 @@ class Genre
public:
typedef Wt::Dbo::ptr<Genre> pointer;
typedef Wt::Dbo::dbo_traits<Genre>::IdType id_type;
Genre();
Genre(const std::string& name);
@@ -129,6 +133,7 @@ class Track
public:
typedef Wt::Dbo::ptr<Track> pointer;
typedef Wt::Dbo::dbo_traits<Track>::IdType id_type;
Track() {}
Track(const boost::filesystem::path& p, Artist::pointer artist, Release::pointer release);
@@ -136,6 +141,11 @@ class Track
// Find utilities
static pointer getByPath(Wt::Dbo::Session& session, const boost::filesystem::path& p);
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,
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);
@@ -153,15 +163,19 @@ class Track
void setArtist(Artist::pointer artist) { _artist = artist; }
void setRelease(Release::pointer release) { _release = release; }
std::string getName(void) const { return _name; }
const std::string& getPath(void) const { return _filePath; }
boost::posix_time::time_duration getDuration(void) const { return _duration; }
boost::posix_time::ptime getLastWriteTime(void) const { return _fileLastWrite; }
const std::vector<unsigned char>& getChecksum(void) const { return _fileChecksum; }
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;
int getTrackNumber(void) const { return _trackNumber; }
int getDiscNumber(void) const { return _discNumber; }
std::string getName(void) const { return _name; }
const std::string& getPath(void) const { return _filePath; }
boost::posix_time::time_duration getDuration(void) const { return _duration; }
boost::posix_time::ptime getCreationTime(void) const { return _creationTime; }
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;
boost::posix_time::ptime getLastWriteTime(void) const { return _fileLastWrite; }
const std::vector<unsigned char>& getChecksum(void) const { return _fileChecksum; }
template<class Action>
void persist(Action& a)
+35 -2
View File
@@ -1,5 +1,10 @@
#include <boost/foreach.hpp>
#include "SqlQuery.hpp"
#include "AudioTypes.hpp"
Release::Release(const std::string& name)
: _name(name)
{
@@ -28,8 +33,36 @@ Release::create(Wt::Dbo::Session& session, const std::string& name)
}
Wt::Dbo::collection<Release::pointer>
Release::getAll(Wt::Dbo::Session& session, Artist::id_type id, int offset, int size)
Release::getAll(Wt::Dbo::Session& session, std::vector<Artist::id_type> artistIds, int offset, int size)
{
return session.query<Release::pointer>("select * from Release INNER JOIN Release.id = Artist.id").where("artist.id = ?").bind(id);
std::string sqlQuery = "SELECT r FROM release r";
if (!artistIds.empty())
{
sqlQuery += " INNER JOIN artist a ON a.id = t.artist_id";
sqlQuery += " INNER JOIN track t ON t.release_id = r.id";
}
Wt::Dbo::Query<Release::pointer> query = session.query<Release::pointer>( sqlQuery ).offset(offset).limit(size);
BOOST_FOREACH(const Artist::id_type artistId, artistIds)
query.where("a.id = ?").bind(artistId);
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;
}
+47 -10
View File
@@ -59,24 +59,54 @@ WhereClause::bind(const std::string& bindArg)
return *this;
}
SelectStatement&
SelectStatement::And(const SelectStatement& statement)
InnerJoinClause::InnerJoinClause(const std::string& clause)
:_clause(clause)
{
if( _statement.empty() && !statement._statement.empty())
_statement = "SELECT ";
else if (!_statement.empty() && !statement._statement.empty())
_statement += ",";
}
InnerJoinClause&
InnerJoinClause::And(const InnerJoinClause& clause)
{
if (!_clause.empty())
_clause += " ";
_clause += clause._clause;
_statement += statement._statement;
return *this;
}
FromClause::FromClause(const std::string& clause)
SelectStatement::SelectStatement(const std::string& statement)
{
_clause.push_back(clause);
And(statement);
}
SelectStatement&
SelectStatement::And(const std::string& statement)
{
_statement.push_back(statement);
_statement.sort();
_statement.unique();
return *this;
}
std::string
SelectStatement::get() const
{
std::string res = "SELECT ";
for (std::list<std::string>::const_iterator it = _statement.begin(); it != _statement.end(); ++it)
{
if (it != _statement.begin())
res += ",";
res += *it;
}
return res;
}
GroupByStatement&
GroupByStatement::And(const GroupByStatement& statement)
@@ -90,6 +120,10 @@ GroupByStatement::And(const GroupByStatement& statement)
return *this;
}
FromClause::FromClause(const std::string& clause)
{
_clause.push_back(clause);
}
FromClause&
FromClause::And(const FromClause& clause)
@@ -133,6 +167,9 @@ SqlQuery::get(void) const
if (!_fromClause.get().empty())
oss << " " << _fromClause.get();
if (!_innerJoinClause.get().empty())
oss << " " << _innerJoinClause.get();
if (!_whereClause.get().empty())
oss << " " << _whereClause.get();
+24 -5
View File
@@ -28,6 +28,21 @@ class WhereClause
};
class InnerJoinClause
{
public:
InnerJoinClause() {}
InnerJoinClause(const std::string& clause);
InnerJoinClause& And(const InnerJoinClause& clause);
std::string get() const { return _clause;}
private:
std::string _clause;
};
class GroupByStatement
{
public:
@@ -46,16 +61,16 @@ class GroupByStatement
class SelectStatement
{
public:
SelectStatement() {}
SelectStatement(const std::string& statement) { _statement = statement; }
SelectStatement() {};
SelectStatement(const std::string& item);
SelectStatement& And(const SelectStatement& statement);
SelectStatement& And(const std::string& item);
std::string get() const {return _statement;}
std::string get() const;
private:
std::string _statement; // SELECT statement
std::list<std::string> _statement;
};
class FromClause
@@ -80,7 +95,10 @@ class SqlQuery
public:
SelectStatement& select(void) { return _selectStatement;}
SelectStatement& select(const std::string& statement) { _selectStatement = SelectStatement(statement); return _selectStatement; }
FromClause& from(void) { return _fromClause; }
FromClause& from(const std::string& clause) { _whereClause = WhereClause(clause); return _fromClause; }
InnerJoinClause& innerJoin(void) { return _innerJoinClause; }
WhereClause& where(void) { return _whereClause; }
const WhereClause& where(void) const { return _whereClause; }
GroupByStatement& groupBy(void) { return _groupByStatement; }
@@ -91,6 +109,7 @@ class SqlQuery
private:
SelectStatement _selectStatement; // SELECT statement
InnerJoinClause _innerJoinClause; // INNER JOIN
FromClause _fromClause; // FROM tables
WhereClause _whereClause; // WHERE clause
GroupByStatement _groupByStatement; // GROUP BY statement
+74
View File
@@ -1,5 +1,7 @@
#include <boost/foreach.hpp>
#include "SqlQuery.hpp"
#include "AudioTypes.hpp"
@@ -53,3 +55,75 @@ Track::getGenres(void) const
std::copy(_genres.begin(), _genres.end(), std::back_inserter(genres));
return genres;
}
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,
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())
{
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_d.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 releaseWhere;
for (std::size_t i = 0; i < releaseIds.size(); ++i)
releaseWhere.Or( WhereClause("r.id = ?") );
where.And(releaseWhere);
}
{
WhereClause genreWhere;
for (std::size_t i = 0; i < genreIds.size(); ++i)
genreWhere.Or( WhereClause("g.id = ?") );
where.And(genreWhere);
}
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 Release::id_type releaseId, releaseIds)
query.bind(releaseId);
BOOST_FOREACH(const Genre::id_type genreId, genreIds)
query.bind(genreId);
query.groupBy("t");
return query;
}