From ec1db6671ab82aaa9512483579005f0f314f5150 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sat, 20 Jul 2013 14:53:39 +0200 Subject: [PATCH] Really use all data instead of only cached --- .../NetworkActivityWorker.cpp | 103 ++++++------------ .../NetworkActivityWorker.h | 7 +- .../NetworkActivityWorker_p.h | 6 +- .../DatabaseCommand_CalculatePlaytime.cpp | 47 +++++++- .../DatabaseCommand_CalculatePlaytime.h | 2 + .../DatabaseCommand_CalculatePlaytime_p.h | 2 + .../DatabaseCommand_LoadAllPlaylists.cpp | 47 +++++++- .../DatabaseCommand_LoadAllPlaylists.h | 15 +++ .../DatabaseCommand_LoadAllPlaylists_p.h | 2 + 9 files changed, 145 insertions(+), 86 deletions(-) diff --git a/src/libtomahawk-widgets/NetworkActivityWorker.cpp b/src/libtomahawk-widgets/NetworkActivityWorker.cpp index 9a970896f..afce0db8c 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker.cpp +++ b/src/libtomahawk-widgets/NetworkActivityWorker.cpp @@ -26,6 +26,8 @@ #include "database/DatabaseImpl.h" #include "NetworkActivityWidget.h" +#include "utils/Logger.h" + #include namespace Tomahawk @@ -49,6 +51,7 @@ NetworkActivityWorker::~NetworkActivityWorker() void NetworkActivityWorker::run() { + tLog() << Q_FUNC_INFO << QDateTime::currentDateTime().toTime_t(); { // Load trending tracks qRegisterMetaType< QList< QPair< double,Tomahawk::track_ptr > > >("QList< QPair< double,Tomahawk::track_ptr > >"); @@ -66,31 +69,29 @@ NetworkActivityWorker::run() Qt::QueuedConnection); Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); } + tLog() << Q_FUNC_INFO << QDateTime::currentDateTime().toTime_t(); } void -NetworkActivityWorker::allPlaylistsReceived( const QList& playlists ) +NetworkActivityWorker::allPlaylistsReceived( const QHash< Tomahawk::playlist_ptr, QStringList >& playlists ) { Q_D( NetworkActivityWorker ); d->sourcesToLoad--; - d->playlists.append( playlists ); + d->playlists.unite( playlists ); if ( d->sourcesToLoad == 0 ) { + tLog() << Q_FUNC_INFO << QDateTime::currentDateTime().toTime_t(); // Load all playlist entries - foreach( playlist_ptr playlist, d->playlists ) + + foreach( playlist_ptr playlist, d->playlists.keys() ) { - if ( !playlist->loaded() ) - { - d->playlistsRevisionToLoad++; - connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), - SLOT( revisionLoaded( Tomahawk::PlaylistRevision ) ), - Qt::QueuedConnection ); - playlist->loadRevision(); - } + d->playtimesToLoad++; + DatabaseCommand_CalculatePlaytime* dbcmd = new DatabaseCommand_CalculatePlaytime( playlist, d->playlists.value( playlist ), QDateTime::currentDateTime().addDays( -7 ), QDateTime::currentDateTime() ); + connect( dbcmd, SIGNAL( done( Tomahawk::playlist_ptr, uint ) ), SLOT( playtime( Tomahawk::playlist_ptr, uint ) ) ); + Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); } - checkRevisionLoadedDone(); } } @@ -98,14 +99,16 @@ NetworkActivityWorker::allPlaylistsReceived( const QList& playlist void NetworkActivityWorker::allSourcesReceived( const QList& sources ) { + tLog() << Q_FUNC_INFO << QDateTime::currentDateTime().toTime_t(); Q_D( NetworkActivityWorker ); d->sourcesToLoad = sources.count(); foreach ( const source_ptr& source, sources) { DatabaseCommand_LoadAllPlaylists* dbcmd = new DatabaseCommand_LoadAllPlaylists( source ); - connect( dbcmd, SIGNAL( done( QList ) ), - SLOT( allPlaylistsReceived ( QList ) ), + dbcmd->setReturnPlEntryIds( true ); + connect( dbcmd, SIGNAL( done( QHash< Tomahawk::playlist_ptr, QStringList > ) ), + SLOT( allPlaylistsReceived ( QHash< Tomahawk::playlist_ptr, QStringList > ) ), Qt::QueuedConnection ); Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); } @@ -113,21 +116,28 @@ NetworkActivityWorker::allSourcesReceived( const QList& sources ) void -NetworkActivityWorker::playtime( uint playtime ) +NetworkActivityWorker::playtime( const Tomahawk::playlist_ptr& playlist, uint playtime ) { Q_D( NetworkActivityWorker ); - d->playlistCount.insert( playtime, d->playlistStack.pop() ); - calculateNextPlaylist(); -} + d->playtimesToLoad--; + d->playlistCount.insert( playtime, playlist ); - -void -NetworkActivityWorker::revisionLoaded(PlaylistRevision revision) -{ - Q_UNUSED( revision ); - Q_D( NetworkActivityWorker ); - d->playlistsRevisionToLoad--; - checkRevisionLoadedDone(); + if ( d->playtimesToLoad == 0 ) + { + tLog() << Q_FUNC_INFO << QDateTime::currentDateTime().toTime_t(); + d->playlistCount.remove( 0 ); + QList playlists; + QMapIterator iter( d->playlistCount ); + iter.toBack(); + while (iter.hasPrevious() && (uint)playlists.size() < Widgets::NetworkActivityWidget::numberOfHotPlaylists ) + { + iter.previous(); + playlists << iter.value(); + } + emit hotPlaylists( playlists ); + d->hotPlaylistsDone = true; + checkDone(); + } } @@ -149,47 +159,6 @@ NetworkActivityWorker::trendingTracksReceived( const QListplaylistStack.isEmpty() ) - { - DatabaseCommand_CalculatePlaytime* dbcmd = new DatabaseCommand_CalculatePlaytime( d->playlistStack.top(), QDateTime::currentDateTime().addDays( -7 ), QDateTime::currentDateTime() ); - connect( dbcmd, SIGNAL( done( uint ) ), SLOT( playtime( uint ) ), Qt::QueuedConnection ); - Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); - } - else - { - d->playlistCount.remove( 0 ); - QList playlists; - QMapIterator iter (d->playlistCount); - iter.toBack(); - while (iter.hasPrevious() && (uint)playlists.size() < Widgets::NetworkActivityWidget::numberOfHotPlaylists ) - { - iter.previous(); - playlists << iter.value(); - } - emit hotPlaylists( playlists ); - d->hotPlaylistsDone = true; - checkDone(); - } -} - -void -NetworkActivityWorker::checkRevisionLoadedDone() -{ - Q_D( NetworkActivityWorker ); - if ( d->playlistsRevisionToLoad == 0 ) - { - foreach (playlist_ptr playlist, d->playlists) { - d->playlistStack.push( playlist ); - } - calculateNextPlaylist(); - } -} - void NetworkActivityWorker::checkDone() { diff --git a/src/libtomahawk-widgets/NetworkActivityWorker.h b/src/libtomahawk-widgets/NetworkActivityWorker.h index ba28333e6..a68154c35 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker.h +++ b/src/libtomahawk-widgets/NetworkActivityWorker.h @@ -52,17 +52,14 @@ protected: QScopedPointer d_ptr; private slots: - void allPlaylistsReceived( const QList& playlists ); + void allPlaylistsReceived( const QHash< Tomahawk::playlist_ptr, QStringList >& playlists ); void allSourcesReceived( const QList< Tomahawk::source_ptr >& sources ); - void playtime( uint playtime ); - void revisionLoaded( Tomahawk::PlaylistRevision revision ); + void playtime( const Tomahawk::playlist_ptr& playlist , uint playtime ); void trendingTracksReceived( const QList< QPair< double,Tomahawk::track_ptr > >& tracks ); private: Q_DECLARE_PRIVATE( NetworkActivityWorker ) - void calculateNextPlaylist(); - void checkRevisionLoadedDone(); void checkDone(); }; diff --git a/src/libtomahawk-widgets/NetworkActivityWorker_p.h b/src/libtomahawk-widgets/NetworkActivityWorker_p.h index 43bb0c30c..de0a20114 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker_p.h +++ b/src/libtomahawk-widgets/NetworkActivityWorker_p.h @@ -37,7 +37,7 @@ public: : q_ptr( q ) , trendingTracksDone( false ) , hotPlaylistsDone( false ) - , playlistsRevisionToLoad( 0 ) + , playtimesToLoad( 0 ) , trackStatsToLoad( 0 ) { } @@ -48,8 +48,8 @@ private: bool trendingTracksDone; bool hotPlaylistsDone; - QList playlists; - uint playlistsRevisionToLoad; + QHash< Tomahawk::playlist_ptr, QStringList > playlists; + uint playtimesToLoad; uint sourcesToLoad; uint trackStatsToLoad; QStack playlistStack; diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp index c83d01c25..ac174329c 100644 --- a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp @@ -32,6 +32,15 @@ DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const play { d->trackIds.append( QString::number( entry->query()->track()->trackId() ) ); } + d->playlist = playlist; +} + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const playlist_ptr& playlist, const QStringList& plEntryIds, QDateTime from, QDateTime to, QObject* parent ) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + d->plEntryIds = plEntryIds; + d->playlist = playlist; } DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const track_ptr& track, QDateTime from, QDateTime to, QObject* parent ) @@ -81,11 +90,34 @@ DatabaseCommand_CalculatePlaytime::exec( DatabaseImpl *dbi ) { Q_D( DatabaseCommand_CalculatePlaytime ); - QString sql = QString( - " SELECT SUM(secs_played) " - " FROM playback_log " - " WHERE track in ( %1 ) AND playtime >= %2 AND playtime <= %3 " - ).arg( d->trackIds.join(", ") ).arg( d->from.toTime_t() ).arg( d->to.toTime_t() ); + QString sql; + + if ( d->plEntryIds.isEmpty() ) + { + sql = QString( + " SELECT SUM(pl.secs_played) " + " FROM playback_log pl " + " WHERE track in ( %1 ) AND playtime >= %2 AND playtime <= %3 " + ).arg( d->trackIds.join(", ") ).arg( d->from.toTime_t() ).arg( d->to.toTime_t() ); + } + else + { + // Escape all GUIDs + QMutableStringListIterator iter( d->plEntryIds ); + while ( iter.hasNext() ) + { + iter.setValue( QString( "'%1'" ).arg( iter.next() ) ); + } + sql = QString( + " SELECT SUM(pl.secs_played) " + " FROM playlist_item pi " + " JOIN track t ON pi.trackname = t.name " + " JOIN artist a ON a.name = pi.artistname AND t.artist = a.id " + " JOIN playback_log pl ON pl.track = t.id " + " WHERE guid IN (%1); " + ) + .arg( d->plEntryIds.join(", ") ); + } TomahawkSqlQuery query = dbi->newquery(); query.prepare( sql ); @@ -97,6 +129,11 @@ DatabaseCommand_CalculatePlaytime::exec( DatabaseImpl *dbi ) playtime = query.value( 0 ).toUInt(); } emit done( playtime ); + + if ( !d->playlist.isNull() ) + { + emit done( d->playlist, playtime ); + } } diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h index 45b900d9d..c735cce65 100644 --- a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h @@ -31,6 +31,7 @@ class DLLEXPORT DatabaseCommand_CalculatePlaytime : public Tomahawk::DatabaseCom Q_OBJECT public: explicit DatabaseCommand_CalculatePlaytime( const playlist_ptr& playlist, QDateTime from, QDateTime to, QObject* parent = 0 ); + explicit DatabaseCommand_CalculatePlaytime( const playlist_ptr& playlist, const QStringList& plEntryIds, QDateTime from, QDateTime to, QObject* parent = 0 ); explicit DatabaseCommand_CalculatePlaytime( const track_ptr& track, QDateTime from, QDateTime to, QObject* parent = 0 ); explicit DatabaseCommand_CalculatePlaytime( const QList& tracks, QDateTime from, QDateTime to, QObject* parent = 0 ); explicit DatabaseCommand_CalculatePlaytime( const query_ptr& query, QDateTime from, QDateTime to, QObject* parent = 0 ); @@ -45,6 +46,7 @@ public: signals: void done( uint playtime ); + void done( const Tomahawk::playlist_ptr& playlist, uint playtime ); private: Q_DECLARE_PRIVATE( DatabaseCommand_CalculatePlaytime ) diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h index 2dcaf2a55..227634e3c 100644 --- a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h @@ -43,7 +43,9 @@ class DatabaseCommand_CalculatePlaytimePrivate : public DatabaseCommandPrivate private: QDateTime from; QDateTime to; + QStringList plEntryIds; QStringList trackIds; + Tomahawk::playlist_ptr playlist; }; } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp index 70347a01c..c665103f4 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp @@ -24,6 +24,8 @@ #include "PlaylistEntry.h" #include "Source.h" +#include + #include using namespace Tomahawk; @@ -32,6 +34,7 @@ using namespace Tomahawk; DatabaseCommand_LoadAllPlaylists::DatabaseCommand_LoadAllPlaylists( const source_ptr& s, QObject* parent ) : DatabaseCommand( parent, new DatabaseCommand_LoadAllPlaylistsPrivate( this, s ) ) { + qRegisterMetaType< QHash< Tomahawk::playlist_ptr, QStringList > >("QHash< Tomahawk::playlist_ptr, QStringList >"); } @@ -55,19 +58,32 @@ DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) if ( !source().isNull() ) sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); - query.exec( QString( " SELECT p.guid, p.title, p.info, p.creator, p.lastmodified, p.shared, p.currentrevision, p.createdOn " + QString trackIdJoin; + QString trackIdFields; + if ( d->returnPlEntryIds ) + { + trackIdFields = ", pr.entries"; + trackIdJoin = "JOIN playlist_revision pr ON pr.playlist = p.guid AND pr.guid = p.currentrevision"; + } + + query.exec( QString( " SELECT p.guid, p.title, p.info, p.creator, p.lastmodified, p.shared, p.currentrevision, p.createdOn %6 " " FROM playlist p " + " %5 " " WHERE dynplaylist = 'false' " " %1 " " %2 %3 %4 " - ) - .arg( sourceToken ) - .arg( orderToken ) - .arg( d->sortDescending ? "DESC" : QString() ) - .arg( d->limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( d->limitAmount ) : QString() ) + ) + .arg( sourceToken ) + .arg( orderToken ) + .arg( d->sortDescending ? "DESC" : QString() ) + .arg( d->limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( d->limitAmount ) : QString() ) + .arg( trackIdJoin ) + .arg( trackIdFields ) ); QList plists; + QHash phash; + QJson::Parser parser; while ( query.next() ) { playlist_ptr p( new Playlist( source(), //src @@ -82,9 +98,20 @@ DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) ), &QObject::deleteLater ); p->setWeakSelf( p.toWeakRef() ); plists.append( p ); + + if ( d->returnPlEntryIds ) + { + QStringList trackIds = parser.parse( query.value( 8 ).toByteArray() ).toStringList(); + phash.insert( p, trackIds ); + } } emit done( plists ); + + if ( d->returnPlEntryIds ) + { + emit done( phash ); + } } @@ -111,3 +138,11 @@ DatabaseCommand_LoadAllPlaylists::setSortDescending( bool descending ) d->sortDescending = descending; } + +void +DatabaseCommand_LoadAllPlaylists::setReturnPlEntryIds( bool returnPlEntryIds ) +{ + Q_D( DatabaseCommand_LoadAllPlaylists ); + d->returnPlEntryIds = returnPlEntryIds; +} + diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.h b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.h index 836808a6d..92a1d39fe 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.h +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.h @@ -54,9 +54,24 @@ public: void setSortOrder( SortOrder order ); void setSortDescending( bool descending ); + /** + * By default, only playlists with no revision will be loaded as fully + * loading a revision is a lot of work which cannot be integrated into + * one query. + * + * Often one only needs to know the trackIds of a playlist, not the + * whole revision information. + */ + void setReturnPlEntryIds( bool returnPlEntryIds ); + signals: void done( const QList& playlists ); + /** + * This signal is only emitted if returnTrackIds == true. + */ + void done( const QHash< Tomahawk::playlist_ptr, QStringList >& playlists ); + private: Q_DECLARE_PRIVATE( DatabaseCommand_LoadAllPlaylists ) }; diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists_p.h b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists_p.h index 108d7969c..1d08978e1 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists_p.h +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists_p.h @@ -35,6 +35,7 @@ public: DatabaseCommand_LoadAllPlaylistsPrivate( DatabaseCommand_LoadAllPlaylists* q, const source_ptr& s ) : DatabaseCommandPrivate( q, s ) , limitAmount( 0 ) + , returnPlEntryIds( false ) , sortOrder( DatabaseCommand_LoadAllPlaylists::None ) , sortDescending( false ) { @@ -44,6 +45,7 @@ public: private: unsigned int limitAmount; + bool returnPlEntryIds; DatabaseCommand_LoadAllPlaylists::SortOrder sortOrder; bool sortDescending; };