PageRenderTime 103ms CodeModel.GetById 40ms app.highlight 20ms RepoModel.GetById 40ms app.codeStats 0ms

/src/libtomahawk/database/DatabaseCommand_AllTracks.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 174 lines | 129 code | 25 blank | 20 comment | 13 complexity | fbab39d2c8cefc0cfcdff72a77c055ae MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *   Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
  5 *
  6 *   Tomahawk is free software: you can redistribute it and/or modify
  7 *   it under the terms of the GNU General Public License as published by
  8 *   the Free Software Foundation, either version 3 of the License, or
  9 *   (at your option) any later version.
 10 *
 11 *   Tomahawk is distributed in the hope that it will be useful,
 12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14 *   GNU General Public License for more details.
 15 *
 16 *   You should have received a copy of the GNU General Public License
 17 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 18 */
 19
 20#include "DatabaseCommand_AllTracks.h"
 21
 22#include <QSqlQuery>
 23
 24#include "utils/Logger.h"
 25
 26#include "Album.h"
 27#include "Artist.h"
 28#include "DatabaseImpl.h"
 29#include "Result.h"
 30#include "SourceList.h"
 31#include "Track.h"
 32
 33#include <unordered_map>
 34
 35namespace Tomahawk
 36{
 37
 38void
 39DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
 40{
 41    TomahawkSqlQuery query = dbi->newquery();
 42    QList<Tomahawk::query_ptr> ql;
 43
 44    QString m_orderToken, sourceToken;
 45    switch ( m_sortOrder )
 46    {
 47        case 0:
 48            break;
 49
 50        case Album:
 51            m_orderToken = "album.name, file_join.discnumber, file_join.albumpos";
 52            break;
 53
 54        case ModificationTime:
 55            m_orderToken = "file.mtime";
 56            break;
 57
 58        case AlbumPosition:
 59            m_orderToken = "file_join.discnumber, file_join.albumpos";
 60            break;
 61    }
 62
 63    if ( !m_collection.isNull() )
 64        sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) );
 65
 66    QString albumToken;
 67    if ( m_album )
 68    {
 69        if ( m_album->id() == 0 )
 70        {
 71            m_artist = m_album->artist();
 72            albumToken = QString( "AND album.id IS NULL" );
 73        }
 74        else
 75            albumToken = QString( "AND album.id = %1" ).arg( m_album->id() );
 76    }
 77
 78    QString sql = QString(
 79            "SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, "             //0
 80                   "file.duration, file.bitrate, file.url, file.source, file.mtime, "                     //6
 81                   "file.mimetype, file_join.discnumber, file_join.albumpos, track.id, albumArtist.name " //11
 82            "FROM file, artist, track, file_join "
 83            "LEFT OUTER JOIN album "
 84            "ON file_join.album = album.id "
 85            "LEFT OUTER JOIN artist AS composer "
 86            "ON file_join.composer = composer.id "
 87            "LEFT OUTER JOIN artist AS albumArtist "
 88            "ON album.artist = albumArtist.id "
 89            "WHERE file.id = file_join.file "
 90            "AND file_join.artist = artist.id "
 91            "AND file_join.track = track.id "
 92            "%1 "
 93            "%2 %3 "
 94            "%4 %5 %6"
 95            ).arg( sourceToken )
 96             .arg( !m_artist ? QString() : QString( "AND artist.id = %1" ).arg( m_artist->id() ) )
 97             .arg( !m_album ? QString() : albumToken )
 98             .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() )
 99             .arg( m_sortDescending ? "DESC" : QString() )
100             .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() );
101
102    query.prepare( sql );
103    query.exec();
104
105    // Small cache to keep already created source objects.
106    // This saves some mutex locking.
107    std::unordered_map<uint, Tomahawk::source_ptr> sourceCache;
108
109    while( query.next() )
110    {
111        const QString artist = query.value( 1 ).toString();
112        const QString album = query.value( 2 ).toString();
113        const QString track = query.value( 3 ).toString();
114        const QString composer = query.value( 4 ).toString();
115        const uint size = query.value( 5 ).toUInt();
116        const uint duration = query.value( 6 ).toUInt();
117        const uint bitrate = query.value( 7 ).toUInt();
118        QString url = query.value( 8 ).toString();
119        const uint sourceId = query.value( 9 ).toUInt();
120        const uint modificationTime = query.value( 10 ).toUInt();
121        const QString mimetype = query.value( 11 ).toString();
122        const uint discnumber = query.value( 12 ).toUInt();
123        const uint albumpos = query.value( 13 ).toUInt();
124        const uint trackId = query.value( 14 ).toUInt();
125        const QString albumArtist = query.value( 15 ).toString();
126
127        std::unordered_map<uint, Tomahawk::source_ptr>::const_iterator _s = sourceCache.find( sourceId );
128        Tomahawk::source_ptr s;
129        if ( _s == sourceCache.end() )
130        {
131            s = SourceList::instance()->get( sourceId );
132            sourceCache[sourceId] = s;
133        }
134        else
135        {
136            s = _s->second;
137        }
138        if ( !s )
139        {
140            Q_ASSERT( false );
141            continue;
142        }
143        if ( !s->isLocal() )
144            url = QString( "servent://%1\t%2" ).arg( s->nodeId() ).arg( url );
145
146        Tomahawk::track_ptr t = Tomahawk::Track::get( trackId,
147                                                      artist, track, album,
148                                                      albumArtist, duration, composer,
149                                                      albumpos, discnumber );
150        if ( !t )
151            continue;
152
153        if ( m_album || m_artist )
154            t->loadAttributes();
155
156        Tomahawk::result_ptr result = Tomahawk::Result::get( url, t );
157        if ( !result )
158            continue;
159
160        result->setSize( size );
161        result->setBitrate( bitrate );
162        result->setModificationTime( modificationTime );
163        result->setMimetype( mimetype );
164        result->setResolvedByCollection( s->dbCollection(), false );
165
166        ql << Tomahawk::Query::getFixed( t, result );
167    }
168
169    emit tracks( ql, data() );
170    emit tracks( ql );
171    emit done( m_collection );
172}
173
174}