-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Last Played" column to library #2670
Closed
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
6e5acb1
last-played-datetime: initial work to create a sortable column for la…
ywwg a920568
last played time: Respond to setlog changes
ywwg 36a0e54
last played: cleanup before review
ywwg 95446b1
last played: tiny optimization
ywwg 06f4ed6
last played: triple slashes for docs
ywwg ff8a303
last played: this change breaks the PR. Why doesn't bindValue work??
ywwg a7960e2
last played: fix bindvalue uses
ywwg 7cd7eaa
last played: oops can't return nothing
ywwg b7a8236
last played: oops use the right conditional
ywwg 8b42a7c
last played: address notes
ywwg a013e9e
last played: make const extern
ywwg cbbff3f
last played: fix naming
ywwg 9fe8ba0
last played: persist and reuse QSqlQuery
ywwg 9d50d62
last played: check for not-found
ywwg f7ec07d
last played: make sure query is finished
ywwg 2ebf657
Merge branch 'master' into last-played
ywwg 46ba736
Merge branch 'master' into last-played
ywwg ddb88eb
Merge branch 'master' into last-played
ywwg eb3c64f
Merge branch 'master' into last-played
ywwg 55d5350
Merge branch 'master' into last-played
ywwg 8734cf8
Last Played: fix not reprocessing tracks from deleted playlists
ywwg b6b4ed4
Last Played: minor cleanup
ywwg a8576f8
Last Played: line wrap
ywwg 975cb46
Merge branch 'master' into last-played
ywwg a22a3cd
Merge branch 'master' into last-played
ywwg c718c15
Merge branch 'master' into last-played
ywwg bd27ffb
Fix bad merge
ywwg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include "library/lastplayedcache.h" | ||
|
||
#include <QSqlDatabase> | ||
#include <QtDebug> | ||
|
||
#include "library/dao/playlistdao.h" | ||
#include "library/trackcollection.h" | ||
|
||
const QString LASTPLAYEDTABLE_NAME = "last_played_datetimes"; | ||
|
||
QDateTime LastPlayedFetcher::fetch(TrackPointer pTrack) { | ||
m_fetchQuery.prepare( | ||
"SELECT datetime_played FROM " + | ||
LASTPLAYEDTABLE_NAME + | ||
" WHERE track_id = :trackid"); | ||
m_fetchQuery.bindValue(":trackid", pTrack->getId().toVariant()); | ||
if (!m_fetchQuery.exec()) { | ||
LOG_FAILED_QUERY(m_fetchQuery); | ||
return QDateTime(); | ||
} | ||
if (!m_fetchQuery.first()) { | ||
return QDateTime(); | ||
} | ||
QDateTime ret = m_fetchQuery.value(0).toDateTime(); | ||
m_fetchQuery.finish(); | ||
return ret; | ||
} | ||
|
||
LastPlayedCache::LastPlayedCache(TrackCollection* trackCollection) | ||
: m_pTrackCollection(trackCollection), | ||
m_helper(trackCollection->database()) { | ||
initTableView(); | ||
|
||
connect(&m_pTrackCollection->getPlaylistDAO(), | ||
&PlaylistDAO::trackAdded, | ||
this, | ||
[=](int playlistId, TrackId trackId) { | ||
playlistTrackChanged(playlistId, trackId); | ||
}); | ||
connect(&m_pTrackCollection->getPlaylistDAO(), | ||
&PlaylistDAO::trackRemoved, | ||
this, | ||
[=](int playlistId, TrackId trackId) { | ||
playlistTrackChanged(playlistId, trackId); | ||
}); | ||
} | ||
|
||
void LastPlayedCache::initTableView() { | ||
QSqlQuery lastPlayedQuery(m_pTrackCollection->database()); | ||
// Views can't use params, so just use .args here. There is no injection | ||
// risk because these are constants. | ||
lastPlayedQuery.prepare(QStringLiteral( | ||
"CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " | ||
"SELECT " | ||
" PlaylistTracks.track_id, " | ||
" MAX(PlaylistTracks.pl_datetime_added) as datetime_played " | ||
"FROM PlaylistTracks " | ||
"JOIN Playlists ON PlaylistTracks.playlist_id == Playlists.id " | ||
"WHERE Playlists.hidden = %2 " | ||
"GROUP BY PlaylistTracks.track_id") | ||
.arg(LASTPLAYEDTABLE_NAME, | ||
QString::number(PlaylistDAO:: | ||
PLHT_SET_LOG))); | ||
if (!lastPlayedQuery.exec()) { | ||
LOG_FAILED_QUERY(lastPlayedQuery); | ||
} | ||
} | ||
|
||
void LastPlayedCache::playlistTrackChanged( | ||
int playlistId, TrackId trackId) { | ||
const auto type = m_pTrackCollection->getPlaylistDAO().getHiddenType(playlistId); | ||
// Deleted playlists show up as unknown type | ||
if (type != PlaylistDAO::PLHT_SET_LOG && type != PlaylistDAO::PLHT_UNKNOWN) { | ||
return; | ||
} | ||
|
||
TrackPointer pTrack = m_pTrackCollection->getTrackById(trackId); | ||
if (pTrack) { | ||
pTrack->setLastPlayedDate(m_helper.fetch(pTrack)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#pragma once | ||
|
||
#include <QObject> | ||
#include <QSet> | ||
#include <QSqlDatabase> | ||
#include <QString> | ||
|
||
#include "library/queryutil.h" | ||
#include "track/track.h" | ||
#include "track/trackid.h" | ||
|
||
class TrackCollection; | ||
|
||
extern const QString LASTPLAYEDTABLE_NAME; | ||
|
||
/// LastPlayedFetcher is a small object for fetching last played times from the | ||
/// database. It holds and reuses a QSqlQuery for efficiency. | ||
class LastPlayedFetcher { | ||
public: | ||
explicit LastPlayedFetcher(QSqlDatabase db) | ||
: m_fetchQuery(db) { | ||
} | ||
|
||
/// Fetches the last played time for the given track. Returns an empty (null) | ||
/// QDateTime on error. | ||
QDateTime fetch(TrackPointer pTrack); | ||
|
||
private: | ||
QSqlQuery m_fetchQuery; | ||
}; | ||
|
||
/// LastPlayedCache is a helper object for creating and maintaining | ||
/// the "last_played" temporary view on the database. It creates the | ||
/// view and also watches for changes to the Setlog Playlists and updates | ||
/// tracks in the cache as necessary. | ||
class LastPlayedCache : public QObject { | ||
Q_OBJECT | ||
public: | ||
explicit LastPlayedCache(TrackCollection* trackCollection); | ||
~LastPlayedCache() override = default; | ||
|
||
private: | ||
void initTableView(); | ||
void playlistTrackChanged(int playlistId, TrackId trackId); | ||
|
||
TrackCollection* const m_pTrackCollection; | ||
LastPlayedFetcher m_helper; | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commits in the history that do not even build are bad for git bisect. Redo and force push.