/src/libtomahawk/database/DatabaseCommand_AllTracks.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 174 lines · 129 code · 25 blank · 20 comment · 14 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. #include "DatabaseCommand_AllTracks.h"
  20. #include <QSqlQuery>
  21. #include "utils/Logger.h"
  22. #include "Album.h"
  23. #include "Artist.h"
  24. #include "DatabaseImpl.h"
  25. #include "Result.h"
  26. #include "SourceList.h"
  27. #include "Track.h"
  28. #include <unordered_map>
  29. namespace Tomahawk
  30. {
  31. void
  32. DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
  33. {
  34. TomahawkSqlQuery query = dbi->newquery();
  35. QList<Tomahawk::query_ptr> ql;
  36. QString m_orderToken, sourceToken;
  37. switch ( m_sortOrder )
  38. {
  39. case 0:
  40. break;
  41. case Album:
  42. m_orderToken = "album.name, file_join.discnumber, file_join.albumpos";
  43. break;
  44. case ModificationTime:
  45. m_orderToken = "file.mtime";
  46. break;
  47. case AlbumPosition:
  48. m_orderToken = "file_join.discnumber, file_join.albumpos";
  49. break;
  50. }
  51. if ( !m_collection.isNull() )
  52. sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) );
  53. QString albumToken;
  54. if ( m_album )
  55. {
  56. if ( m_album->id() == 0 )
  57. {
  58. m_artist = m_album->artist();
  59. albumToken = QString( "AND album.id IS NULL" );
  60. }
  61. else
  62. albumToken = QString( "AND album.id = %1" ).arg( m_album->id() );
  63. }
  64. QString sql = QString(
  65. "SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, " //0
  66. "file.duration, file.bitrate, file.url, file.source, file.mtime, " //6
  67. "file.mimetype, file_join.discnumber, file_join.albumpos, track.id, albumArtist.name " //11
  68. "FROM file, artist, track, file_join "
  69. "LEFT OUTER JOIN album "
  70. "ON file_join.album = album.id "
  71. "LEFT OUTER JOIN artist AS composer "
  72. "ON file_join.composer = composer.id "
  73. "LEFT OUTER JOIN artist AS albumArtist "
  74. "ON album.artist = albumArtist.id "
  75. "WHERE file.id = file_join.file "
  76. "AND file_join.artist = artist.id "
  77. "AND file_join.track = track.id "
  78. "%1 "
  79. "%2 %3 "
  80. "%4 %5 %6"
  81. ).arg( sourceToken )
  82. .arg( !m_artist ? QString() : QString( "AND artist.id = %1" ).arg( m_artist->id() ) )
  83. .arg( !m_album ? QString() : albumToken )
  84. .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() )
  85. .arg( m_sortDescending ? "DESC" : QString() )
  86. .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() );
  87. query.prepare( sql );
  88. query.exec();
  89. // Small cache to keep already created source objects.
  90. // This saves some mutex locking.
  91. std::unordered_map<uint, Tomahawk::source_ptr> sourceCache;
  92. while( query.next() )
  93. {
  94. const QString artist = query.value( 1 ).toString();
  95. const QString album = query.value( 2 ).toString();
  96. const QString track = query.value( 3 ).toString();
  97. const QString composer = query.value( 4 ).toString();
  98. const uint size = query.value( 5 ).toUInt();
  99. const uint duration = query.value( 6 ).toUInt();
  100. const uint bitrate = query.value( 7 ).toUInt();
  101. QString url = query.value( 8 ).toString();
  102. const uint sourceId = query.value( 9 ).toUInt();
  103. const uint modificationTime = query.value( 10 ).toUInt();
  104. const QString mimetype = query.value( 11 ).toString();
  105. const uint discnumber = query.value( 12 ).toUInt();
  106. const uint albumpos = query.value( 13 ).toUInt();
  107. const uint trackId = query.value( 14 ).toUInt();
  108. const QString albumArtist = query.value( 15 ).toString();
  109. std::unordered_map<uint, Tomahawk::source_ptr>::const_iterator _s = sourceCache.find( sourceId );
  110. Tomahawk::source_ptr s;
  111. if ( _s == sourceCache.end() )
  112. {
  113. s = SourceList::instance()->get( sourceId );
  114. sourceCache[sourceId] = s;
  115. }
  116. else
  117. {
  118. s = _s->second;
  119. }
  120. if ( !s )
  121. {
  122. Q_ASSERT( false );
  123. continue;
  124. }
  125. if ( !s->isLocal() )
  126. url = QString( "servent://%1\t%2" ).arg( s->nodeId() ).arg( url );
  127. Tomahawk::track_ptr t = Tomahawk::Track::get( trackId,
  128. artist, track, album,
  129. albumArtist, duration, composer,
  130. albumpos, discnumber );
  131. if ( !t )
  132. continue;
  133. if ( m_album || m_artist )
  134. t->loadAttributes();
  135. Tomahawk::result_ptr result = Tomahawk::Result::get( url, t );
  136. if ( !result )
  137. continue;
  138. result->setSize( size );
  139. result->setBitrate( bitrate );
  140. result->setModificationTime( modificationTime );
  141. result->setMimetype( mimetype );
  142. result->setResolvedByCollection( s->dbCollection(), false );
  143. ql << Tomahawk::Query::getFixed( t, result );
  144. }
  145. emit tracks( ql, data() );
  146. emit tracks( ql );
  147. emit done( m_collection );
  148. }
  149. }