~mixxxdevelopers/mixxx/mixxx-buildserver

« back to all changes in this revision

Viewing changes to mixxx/src/library/dao/trackdao.cpp

  • Committer: Albert Santoni
  • Date: 2011-03-20 00:27:15 UTC
  • mfrom: (2607.1.162 mixxx-1.9)
  • Revision ID: alberts@mixxx.org-20110320002715-sa2d88zbuc5kkyya
MergedĀ fromĀ 1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
13
13
// 0.
14
 
#define TRACK_CACHE_SIZE 20
 
14
#define TRACK_CACHE_SIZE 50
15
15
 
16
16
TrackDAO::TrackDAO(QSqlDatabase& database, CueDAO& cueDao, ConfigObject<ConfigValue> * pConfig)
17
17
        : m_database(database),
35
35
 
36
36
TrackDAO::~TrackDAO()
37
37
{
 
38
    qDebug() << "~TrackDAO()";
38
39
}
39
40
 
40
41
void TrackDAO::initialize()
109
110
    if (!pTrack) {
110
111
        qWarning() << "TrackDAO::saveTrack() was given NULL track.";
111
112
    }
 
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.";
 
120
            }
 
121
 
 
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);
118
125
 
119
 
            //Write audio meta data, if enabled in the preferences
 
126
            // Write audio meta data, if enabled in the preferences
120
127
            writeAudioMetaData(pTrack);
121
128
 
122
 
            emit(trackClean(trackId));
 
129
            //qDebug() << this << "Dirty tracks remaining after clean save:" << m_dirtyTracks.size();
123
130
        } else {
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();
128
133
 
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);
133
138
            }
143
148
    return m_dirtyTracks.contains(trackId);
144
149
}
145
150
 
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());
153
158
    if (pTrack) {
154
159
        int id = pTrack->getId();
155
160
        if (id != -1) {
159
164
    }
160
165
}
161
166
 
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.
 
174
 
 
175
    if (pTrack) {
 
176
        int id = pTrack->getId();
 
177
        if (id != -1) {
 
178
            m_dirtyTracks.remove(id);
 
179
            emit(trackClean(id));
 
180
        }
 
181
    }
 
182
}
 
183
 
 
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.
169
191
    if (pTrack) {
170
192
        int id = pTrack->getId();
171
193
        if (id != -1) {
174
196
    }
175
197
}
176
198
 
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());
184
206
    if (pTrack) {
185
207
        saveTrack(pTrack);
186
208
    }
187
209
}
188
210
 
189
211
void TrackDAO::saveDirtyTracks() {
 
212
    qDebug() << "TrackDAO::saveDirtyTracks()";
190
213
    QHashIterator<int, TrackWeakPointer> it(m_tracks);
191
214
    while (it.hasNext()) {
192
215
        it.next();
196
219
            saveTrack(pTrack);
197
220
        }
198
221
    }
 
222
    clearCache();
199
223
}
200
224
 
201
225
void TrackDAO::prepareTrackLocationsInsert(QSqlQuery& query) {
497
521
 
498
522
    //qDebug() << "Got deletion call for track" << pTrack << "ID" << pTrack->getId() << pTrack->getInfo();
499
523
 
500
 
    // Save dirty tracks.
501
 
    pTrack->save();
502
 
 
503
 
    // if (iId != -1 && isDirty(iId)) {
504
 
    //     saveTrack(track);
505
 
    // }
 
524
    // Save the track if it is dirty.
 
525
    pTrack->doSave();
506
526
 
507
527
    // Now Qt will delete it in the event loop.
508
528
    pTrack->deleteLater();
586
606
        track->setDirty(false);
587
607
 
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);
595
621
 
596
 
        TrackPointer pTrack = TrackPointer(track, this->deleteTrack);
 
622
        TrackPointer pTrack = TrackPointer(track, &TrackDAO::deleteTrack);
597
623
 
598
624
        // Automatic conversion to a weak pointer
599
625
        m_tracks[trackId] = pTrack;
613
639
    return TrackPointer();
614
640
}
615
641
 
616
 
TrackPointer TrackDAO::getTrack(int id) const
 
642
TrackPointer TrackDAO::getTrack(int id, bool cacheOnly) const
617
643
{
618
644
    //qDebug() << "TrackDAO::getTrack" << QThread::currentThread() << m_database.connectionName();
619
645
 
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];
625
651
 
626
652
        // If the strong reference is still valid (it should be), then return
627
653
        // it. Otherwise query the DB for the track.
643
669
            return pTrack;
644
670
    }
645
671
 
 
672
    // The person only wanted the track if it was cached.
 
673
    if (cacheOnly) {
 
674
        //qDebug() << "TrackDAO::getTrack()" << id << "Caller wanted track but only if it was cached. Returning null.";
 
675
        return TrackPointer();
 
676
    }
 
677
 
646
678
    QTime time;
647
679
    time.start();
648
680
    QSqlQuery query(m_database);