diff --git a/src/cover/CoverArtGrabber.cpp b/src/cover/CoverArtGrabber.cpp index ba2ced72..bed0ef5b 100644 --- a/src/cover/CoverArtGrabber.cpp +++ b/src/cover/CoverArtGrabber.cpp @@ -103,13 +103,11 @@ Grabber::getFromRelease(Wt::Dbo::Session& session, std::string releaseName) SearchFilter filter; filter.exactMatch[SearchFilter::Field::Release].push_back(releaseName); - Wt::Dbo::collection tracks + std::vector tracks = Track::getAll(session, filter, -1, 1 /* limit result size */); - Wt::Dbo::collection::iterator it = tracks.begin(); - - if (it != tracks.end()) - return getFromTrack(*it); + if (!tracks.empty()) + return getFromTrack( tracks.front() ); else return std::vector(); } diff --git a/src/database/Track.cpp b/src/database/Track.cpp index 28e8f459..5c7b3bd0 100644 --- a/src/database/Track.cpp +++ b/src/database/Track.cpp @@ -194,18 +194,17 @@ Track::getAllQuery(Wt::Dbo::Session& session, SearchFilter filter) return query; } -Wt::Dbo::collection< Track::pointer > +std::vector Track::getAll(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size) { - return getAllQuery(session, filter).limit(size).offset(offset); + Wt::Dbo::collection res = getAllQuery(session, filter).limit(size).offset(offset); + return std::vector(res.begin(), res.end()); } std::vector Track::getTracks(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size) { - Wt::Dbo::collection< Track::pointer > tracks = getAll(session, filter, offset, size); - - return std::vector(tracks.begin(), tracks.end()); + return getAll(session, filter, offset, size); } Wt::Dbo::Query diff --git a/src/database/Track.hpp b/src/database/Track.hpp index 524ab4ec..8b32d1cb 100644 --- a/src/database/Track.hpp +++ b/src/database/Track.hpp @@ -110,7 +110,7 @@ class Track static pointer getById(Wt::Dbo::Session& session, id_type id); static Wt::Dbo::collection< pointer > getAll(Wt::Dbo::Session& session); // Used for remote - static Wt::Dbo::collection< pointer > getAll(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); + static std::vector getAll(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); static std::vector getTracks(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); static std::vector getReleases(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); static std::vector getArtists(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); diff --git a/src/remote/server/AudioCollectionRequestHandler.cpp b/src/remote/server/AudioCollectionRequestHandler.cpp index b4b09932..bd3cf912 100644 --- a/src/remote/server/AudioCollectionRequestHandler.cpp +++ b/src/remote/server/AudioCollectionRequestHandler.cpp @@ -256,33 +256,31 @@ AudioCollectionRequestHandler::processGetTracks(const AudioCollectionRequest::Ge Wt::Dbo::Transaction transaction( _db.getSession() ); - Wt::Dbo::collection tracks + std::vector tracks = Database::Track::getAll( _db.getSession(), filter, request.batch_parameter().offset(), static_cast(size)); - typedef Wt::Dbo::collection< Database::Track::pointer > Tracks; - - for (Tracks::const_iterator it = tracks.begin(); it != tracks.end(); ++it) + BOOST_FOREACH(Database::Track::pointer track, tracks) { - AudioCollectionResponse_Track* track = response.add_tracks(); + AudioCollectionResponse_Track* newTrack = response.add_tracks(); - track->set_id(it->id()); - track->set_disc_number( (*it)->getDiscNumber() ); - track->set_track_number( (*it)->getTrackNumber() ); - track->set_artist( (*it)->getArtistName() ); - track->set_release( (*it)->getReleaseName() ); + newTrack->set_id(track.id()); + newTrack->set_disc_number( track->getDiscNumber() ); + newTrack->set_track_number( track->getTrackNumber() ); + newTrack->set_artist( track->getArtistName() ); + newTrack->set_release( track->getReleaseName() ); - track->set_name( std::string( boost::locale::conv::to_utf((*it)->getName(), "UTF-8") ) ); - track->set_duration_secs( (*it)->getDuration().total_seconds() ); + newTrack->set_name( std::string( boost::locale::conv::to_utf(track->getName(), "UTF-8") ) ); + newTrack->set_duration_secs( track->getDuration().total_seconds() ); // Only send the year part of the release times - if (!(*it)->getDate().is_special()) - track->set_release_date( std::to_string((*it)->getDate().date().year()) ); - if (!(*it)->getOriginalDate().is_special()) - track->set_original_release_date( std::to_string((*it)->getOriginalDate().date().year()) ); + if (!track->getDate().is_special()) + newTrack->set_release_date( std::to_string(track->getDate().date().year()) ); + if (!track->getOriginalDate().is_special()) + newTrack->set_original_release_date( std::to_string(track->getOriginalDate().date().year()) ); - BOOST_FOREACH(Database::Genre::pointer genre, (*it)->getGenres()) - track->add_genre( genre->getName() ); + BOOST_FOREACH(Database::Genre::pointer genre, track->getGenres()) + newTrack->add_genre( genre->getName() ); } @@ -307,13 +305,11 @@ AudioCollectionRequestHandler::processGetCoverArt(const AudioCollectionRequest:: SearchFilter filter; filter.exactMatch[SearchFilter::Field::Release].push_back(request.release()); - Wt::Dbo::collection tracks + std::vector tracks = Database::Track::getAll(_db.getSession(), filter, -1, 1 /* limit reuslt size */); - Wt::Dbo::collection::iterator it = tracks.begin(); - - if (it != tracks.end()) - track = *it; + if (!tracks.empty()) + track = tracks.front(); res = true; } diff --git a/src/ui/resource/CoverResource.cpp b/src/ui/resource/CoverResource.cpp index 6866512e..33f917fa 100644 --- a/src/ui/resource/CoverResource.cpp +++ b/src/ui/resource/CoverResource.cpp @@ -72,6 +72,7 @@ CoverResource::getTrackUrl(Database::Track::id_type trackId) void CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) { + // Get the id of the track const std::string *trackIdStr = request.getParameter("trackid"); const std::string *releaseStr = request.getParameter("release"); @@ -80,22 +81,35 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons if (trackIdStr) { - Database::Track::id_type trackId; + Database::Track::id_type trackId = std::stol(*trackIdStr); + std::string path; + bool hasCover = false;; + { - std::istringstream iss(*trackIdStr); - iss >> trackId; + // transactions are not thread safe + std::unique_lock lock(_mutex); + + Wt::Dbo::Transaction transaction(_db.getSession()); + + Database::Track::pointer track = Database::Track::getById(_db.getSession(), trackId); + if (track) + { + hasCover = track->hasCover();; + path = track->getPath(); + } } - Wt::Dbo::Transaction transaction(_db.getSession()); - - Database::Track::pointer track = Database::Track::getById(_db.getSession(), trackId); - covers = CoverArt::Grabber::getFromTrack(track); - - transaction.commit(); + if (hasCover) + { + covers = CoverArt::Grabber::getFromTrack(path); + } } else if (releaseStr) { + // transactions are not thread safe + std::unique_lock lock(_mutex); Wt::Dbo::Transaction transaction(_db.getSession()); + covers = CoverArt::Grabber::getFromRelease(_db.getSession(), *releaseStr); } diff --git a/src/ui/resource/CoverResource.hpp b/src/ui/resource/CoverResource.hpp index 9436899f..c1625718 100644 --- a/src/ui/resource/CoverResource.hpp +++ b/src/ui/resource/CoverResource.hpp @@ -20,6 +20,8 @@ #ifndef COVER_RESOURCE_HPP_ #define COVER_RESOURCE_HPP_ +#include + #include #include @@ -45,6 +47,7 @@ class CoverResource : public Wt::WResource private: + std::mutex _mutex; Database::Handler& _db; std::size_t _size; CoverArt::CoverArt _defaultCover;