File indexing completed on 2024-05-19 04:49:26
0001 /**************************************************************************************** 0002 * Copyright (c) 2009 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify it under * 0006 * the terms of the GNU General Public License as published by the Free Software * 0007 * Foundation; either version 2 of the License, or (at your option) any later * 0008 * version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License along with * 0015 * this program. If not, see <http://www.gnu.org/licenses/>. * 0016 ****************************************************************************************/ 0017 0018 #include "PersistentStatisticsStore.h" 0019 0020 #include "core/meta/Meta.h" 0021 #include "core/support/Amarok.h" 0022 #include "core/support/Debug.h" 0023 0024 const QString PersistentStatisticsStore::s_sqlDateFormat( QStringLiteral("yyyy-MM-dd hh:mm:ss") ); 0025 0026 PersistentStatisticsStore::PersistentStatisticsStore( Meta::Track *track ) 0027 : m_track( track ) 0028 , m_score( 0.0 ) 0029 , m_rating( 0 ) 0030 , m_playCount( 0 ) 0031 , m_batch( 0 ) 0032 { 0033 subscribeTo( track ); // notice the track being deleted 0034 } 0035 0036 PersistentStatisticsStore::~PersistentStatisticsStore() 0037 { 0038 } 0039 0040 double 0041 PersistentStatisticsStore::score() const 0042 { 0043 QReadLocker locker( &m_lock ); 0044 return m_score; 0045 } 0046 0047 void 0048 PersistentStatisticsStore::setScore( double newScore ) 0049 { 0050 QWriteLocker locker( &m_lock ); 0051 m_score = newScore; 0052 commitIfInNonBatchUpdate(); 0053 } 0054 0055 int 0056 PersistentStatisticsStore::rating() const 0057 { 0058 // no lock, int fetching is atomic 0059 return m_rating; 0060 } 0061 0062 void 0063 PersistentStatisticsStore::setRating( int newRating ) 0064 { 0065 QWriteLocker locker( &m_lock ); 0066 m_rating = newRating; 0067 commitIfInNonBatchUpdate(); 0068 } 0069 0070 QDateTime 0071 PersistentStatisticsStore::lastPlayed() const 0072 { 0073 QReadLocker locker( &m_lock ); 0074 return m_lastPlayed; 0075 } 0076 0077 void 0078 PersistentStatisticsStore::setLastPlayed( const QDateTime &dt ) 0079 { 0080 QWriteLocker locker( &m_lock ); 0081 m_lastPlayed = dt; 0082 commitIfInNonBatchUpdate(); 0083 } 0084 0085 QDateTime 0086 PersistentStatisticsStore::firstPlayed() const 0087 { 0088 QReadLocker locker( &m_lock ); 0089 return m_firstPlayed; 0090 } 0091 0092 void 0093 PersistentStatisticsStore::setFirstPlayed( const QDateTime &dt ) 0094 { 0095 QWriteLocker locker( &m_lock ); 0096 m_firstPlayed = dt; 0097 commitIfInNonBatchUpdate(); 0098 } 0099 0100 int 0101 PersistentStatisticsStore::playCount() const 0102 { 0103 // no lock, in fetching is atomic 0104 return m_playCount; 0105 } 0106 0107 void 0108 PersistentStatisticsStore::setPlayCount( int playCount ) 0109 { 0110 QWriteLocker locker( &m_lock ); 0111 m_playCount = playCount; 0112 commitIfInNonBatchUpdate(); 0113 } 0114 0115 void PersistentStatisticsStore::beginUpdate() 0116 { 0117 QWriteLocker locker( &m_lock ); 0118 m_batch++; 0119 } 0120 0121 void PersistentStatisticsStore::endUpdate() 0122 { 0123 QWriteLocker locker( &m_lock ); 0124 Q_ASSERT( m_batch > 0 ); 0125 m_batch--; 0126 commitIfInNonBatchUpdate(); 0127 } 0128 0129 void 0130 PersistentStatisticsStore::entityDestroyed() 0131 { 0132 QWriteLocker locker( &m_lock ); 0133 m_track = nullptr; // prevent stale pointer 0134 } 0135 0136 void 0137 PersistentStatisticsStore::commitIfInNonBatchUpdate() 0138 { 0139 if( m_batch > 0 ) 0140 return; 0141 0142 save(); 0143 if( m_track ) 0144 { 0145 m_lock.unlock(); // better call the notify without lock hold to prevent deadlocks 0146 m_track->notifyObservers(); 0147 m_lock.lockForWrite(); 0148 } 0149 }