11
11
// allows the track reference count to drop to zero. The track cache basically
12
12
// functions to hold a reference to the track so its reference count stays above
14
#define TRACK_CACHE_SIZE 20
14
#define TRACK_CACHE_SIZE 50
16
16
TrackDAO::TrackDAO(QSqlDatabase& database, CueDAO& cueDao, ConfigObject<ConfigValue> * pConfig)
17
17
: m_database(database),
110
111
qWarning() << "TrackDAO::saveTrack() was given NULL track.";
113
//qDebug() << "TrackDAO::saveTrack" << pTrack->getId() << pTrack->getInfo();
112
114
// If track's id is not -1, then update, otherwise add.
113
115
int trackId = pTrack->getId();
114
116
if (trackId != -1) {
115
117
if (pTrack->isDirty()) {
118
if (!m_dirtyTracks.contains(trackId)) {
119
qDebug() << "WARNING: Inconsistent state in TrackDAO. Track is dirty while TrackDAO thinks it is clean.";
122
//qDebug() << this << "Dirty tracks before claen save:" << m_dirtyTracks.size();
123
//qDebug() << "TrackDAO::saveTrack. Dirty. Calling update";
116
124
updateTrack(pTrack);
117
m_dirtyTracks.remove(trackId);
119
//Write audio meta data, if enabled in the preferences
126
// Write audio meta data, if enabled in the preferences
120
127
writeAudioMetaData(pTrack);
122
emit(trackClean(trackId));
129
//qDebug() << this << "Dirty tracks remaining after clean save:" << m_dirtyTracks.size();
124
// We don't know why this is happening right now, but this assert is
125
//failing. The condition is mostly harmless, so simply take
126
//corrective action instead of asserting and warn about it in the
127
//log -- rryan 12/2010
131
//qDebug() << "TrackDAO::saveTrack. Not Dirty";
132
//qDebug() << this << "Dirty tracks remaining:" << m_dirtyTracks.size();
129
134
// Q_ASSERT(!m_dirtyTracks.contains(trackId));
130
if (!m_dirtyTracks.contains(trackId)) {
135
if (m_dirtyTracks.contains(trackId)) {
131
136
qDebug() << "WARNING: Inconsistent state in TrackDAO. Track is clean while TrackDAO thinks it is dirty. Correcting.";
132
137
m_dirtyTracks.remove(trackId);
143
148
return m_dirtyTracks.contains(trackId);
146
void TrackDAO::slotTrackDirty() {
151
void TrackDAO::slotTrackDirty(TrackInfoObject* pTrack) {
152
//qDebug() << "TrackDAO::slotTrackDirty" << pTrack->getInfo();
147
153
// This is a private slot that is connected to TIO's created by this
148
154
// TrackDAO. It is a way for the track to ask that it be saved. The only
149
155
// time this could be unsafe is when the TIO's reference count drops to
150
156
// 0. When that happens, the TIO is deleted with QObject:deleteLater, so Qt
151
157
// will wait for this slot to comlete.
152
TrackInfoObject* pTrack = dynamic_cast<TrackInfoObject*>(sender());
154
159
int id = pTrack->getId();
162
void TrackDAO::slotTrackChanged() {
163
// This is a private slot that is connected to TIO's created by this
164
// TrackDAO. It is a way for the track to ask that it be saved. The only
165
// time this could be unsafe is when the TIO's reference count drops to
166
// 0. When that happens, the TIO is deleted with QObject:deleteLater, so Qt
167
// will wait for this slot to comlete.
168
TrackInfoObject* pTrack = dynamic_cast<TrackInfoObject*>(sender());
167
void TrackDAO::slotTrackClean(TrackInfoObject* pTrack) {
168
//qDebug() << "TrackDAO::slotTrackClean" << pTrack->getInfo();
169
// This is a private slot that is connected to TIO's created by this
170
// TrackDAO. It is a way for the track to ask that it be saved. The only
171
// time this could be unsafe is when the TIO's reference count drops to
172
// 0. When that happens, the TIO is deleted with QObject:deleteLater, so Qt
173
// will wait for this slot to comlete.
176
int id = pTrack->getId();
178
m_dirtyTracks.remove(id);
179
emit(trackClean(id));
184
void TrackDAO::slotTrackChanged(TrackInfoObject* pTrack) {
185
//qDebug() << "TrackDAO::slotTrackChanged" << pTrack->getInfo();
186
// This is a private slot that is connected to TIO's created by this
187
// TrackDAO. It is a way for the track to ask that it be saved. The only
188
// time this could be unsafe is when the TIO's reference count drops to
189
// 0. When that happens, the TIO is deleted with QObject:deleteLater, so Qt
190
// will wait for this slot to comlete.
170
192
int id = pTrack->getId();
177
void TrackDAO::slotTrackSave() {
199
void TrackDAO::slotTrackSave(TrackInfoObject* pTrack) {
200
//qDebug() << "TrackDAO::slotTrackSave" << pTrack->getId() << pTrack->getInfo();
178
201
// This is a private slot that is connected to TIO's created by this
179
202
// TrackDAO. It is a way for the track to ask that it be saved. The last
180
203
// time it is used is when the track is being deleted (i.e. its reference
181
204
// count has dropped to 0). The TIO is deleted with QObject:deleteLater, so
182
205
// Qt will wait for this slot to comlete.
183
TrackInfoObject* pTrack = dynamic_cast<TrackInfoObject*>(sender());
185
207
saveTrack(pTrack);
189
211
void TrackDAO::saveDirtyTracks() {
212
qDebug() << "TrackDAO::saveDirtyTracks()";
190
213
QHashIterator<int, TrackWeakPointer> it(m_tracks);
191
214
while (it.hasNext()) {
498
522
//qDebug() << "Got deletion call for track" << pTrack << "ID" << pTrack->getId() << pTrack->getInfo();
500
// Save dirty tracks.
503
// if (iId != -1 && isDirty(iId)) {
524
// Save the track if it is dirty.
507
527
// Now Qt will delete it in the event loop.
508
528
pTrack->deleteLater();
586
606
track->setDirty(false);
588
608
// Listen to dirty and changed signals
589
connect(track, SIGNAL(dirty()),
590
this, SLOT(slotTrackDirty()));
591
connect(track, SIGNAL(changed()),
592
this, SLOT(slotTrackChanged()));
593
connect(track, SIGNAL(save()),
594
this, SLOT(slotTrackSave()));
609
connect(track, SIGNAL(dirty(TrackInfoObject*)),
610
this, SLOT(slotTrackDirty(TrackInfoObject*)),
611
Qt::DirectConnection);
612
connect(track, SIGNAL(clean(TrackInfoObject*)),
613
this, SLOT(slotTrackClean(TrackInfoObject*)),
614
Qt::DirectConnection);
615
connect(track, SIGNAL(changed(TrackInfoObject*)),
616
this, SLOT(slotTrackChanged(TrackInfoObject*)),
617
Qt::DirectConnection);
618
connect(track, SIGNAL(save(TrackInfoObject*)),
619
this, SLOT(slotTrackSave(TrackInfoObject*)),
620
Qt::DirectConnection);
596
TrackPointer pTrack = TrackPointer(track, this->deleteTrack);
622
TrackPointer pTrack = TrackPointer(track, &TrackDAO::deleteTrack);
598
624
// Automatic conversion to a weak pointer
599
625
m_tracks[trackId] = pTrack;
621
647
// to the track. We do this first so that the QCache keeps track of the
622
648
// least-recently-used track so that it expires them intelligently.
623
649
if (m_trackCache.contains(id)) {
624
TrackPointer& pTrack = *m_trackCache[id];
650
TrackPointer pTrack = *m_trackCache[id];
626
652
// If the strong reference is still valid (it should be), then return
627
653
// it. Otherwise query the DB for the track.