void DatabaseCommand_UpdateSearchIndex::exec( DatabaseImpl* db ) { db->m_fuzzyIndex->beginIndexing(); QMap< unsigned int, QMap< QString, QString > > data; TomahawkSqlQuery q = db->newquery(); q.exec( "SELECT track.id, track.name, artist.name, artist.id FROM track, artist WHERE artist.id = track.artist" ); while ( q.next() ) { QMap< QString, QString > track; track.insert( "track", q.value( 1 ).toString() ); track.insert( "artist", q.value( 2 ).toString() ); track.insert( "artistid", q.value( 3 ).toString() ); data.insert( q.value( 0 ).toUInt(), track ); } db->m_fuzzyIndex->appendFields( data ); data.clear(); q.exec( "SELECT album.id, album.name FROM album" ); while ( q.next() ) { QMap< QString, QString > album; album.insert( "album", q.value( 1 ).toString() ); data.insert( q.value( 0 ).toUInt(), album ); } db->m_fuzzyIndex->appendFields( data ); qDebug() << "Building index finished."; db->m_fuzzyIndex->endIndexing(); }
void DatabaseCommand_SetPlaylistRevision::exec( DatabaseImpl* lib ) { // get the current revision for this playlist // this also serves to check the playlist exists. TomahawkSqlQuery chkq = lib->newquery(); chkq.prepare( "SELECT currentrevision FROM playlist WHERE guid = ?" ); chkq.addBindValue( m_playlistguid ); if( chkq.exec() && chkq.next() ) { m_currentRevision = chkq.value( 0 ).toString(); qDebug() << Q_FUNC_INFO << "pl guid" << m_playlistguid << "- curr rev" << m_currentRevision; } else { tDebug() << "Playlist:" << m_playlistguid << m_currentRevision << source()->friendlyName() << source()->id(); Q_ASSERT_X( false, "DatabaseCommand_SetPlaylistRevision::exec", "No such playlist, WTF?" ); return; } QVariantList vlist = m_orderedguids; QJson::Serializer ser; const QByteArray entries = ser.serialize( vlist ); // add any new items: TomahawkSqlQuery adde = lib->newquery(); if ( m_localOnly ) { QString sql = "UPDATE playlist_item SET result_hint = ? WHERE guid = ?"; adde.prepare( sql ); foreach( const plentry_ptr& e, m_entries ) { if ( e->query()->results().isEmpty() ) continue; adde.bindValue( 0, e->query()->results().first()->url() ); adde.bindValue( 1, e->guid() ); adde.exec(); } return; } else if ( m_metadataUpdate )
void DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi ) { qDebug() << Q_FUNC_INFO; Q_ASSERT( !source().isNull() ); int deleted = 0; QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); TomahawkSqlQuery delquery = dbi->newquery(); QString lastPath; if ( !m_dir.path().isEmpty() && source()->isLocal() ) { qDebug() << "Deleting" << m_dir.path() << "from db for localsource" << srcid; TomahawkSqlQuery dirquery = dbi->newquery(); dirquery.prepare( QString( "SELECT id, url FROM file WHERE source %1 AND url LIKE ?" ) .arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ) ); delquery.prepare( QString( "DELETE FROM file WHERE source %1 AND id = ?" ) .arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ) ); dirquery.bindValue( 0, "file://" + m_dir.canonicalPath() + "/%" ); dirquery.exec(); while ( dirquery.next() ) { QFileInfo fi( dirquery.value( 1 ).toString().mid( 7 ) ); // remove file:// if ( fi.canonicalPath() != m_dir.canonicalPath() ) { if ( lastPath != fi.canonicalPath() ) qDebug() << "Skipping subdir:" << fi.canonicalPath(); lastPath = fi.canonicalPath(); continue; } m_ids << dirquery.value( 0 ).toUInt(); m_files << dirquery.value( 1 ).toString(); } foreach ( const QVariant& id, m_ids ) { delquery.bindValue( 0, id.toUInt() ); if( !delquery.exec() ) { qDebug() << "Failed to delete file:" << delquery.lastError().databaseText() << delquery.lastError().driverText() << delquery.boundValues(); continue; } deleted++; }
void DatabaseCommand_UpdateSearchIndex::exec( DatabaseImpl* db ) { db->m_fuzzyIndex->beginIndexing(); TomahawkSqlQuery q = db->newquery(); q.exec( "SELECT track.id, track.name, artist.name, artist.id FROM track, artist WHERE artist.id = track.artist" ); while ( q.next() ) { IndexData ida; ida.id = q.value( 0 ).toUInt(); ida.artistId = q.value( 3 ).toUInt(); ida.track = q.value( 1 ).toString(); ida.artist = q.value( 2 ).toString(); db->m_fuzzyIndex->appendFields( ida ); } q.exec( "SELECT album.id, album.name FROM album" ); while ( q.next() ) { IndexData ida; ida.id = q.value( 0 ).toUInt(); ida.album = q.value( 1 ).toString(); db->m_fuzzyIndex->appendFields( ida ); } tDebug( LOGVERBOSE ) << "Building index finished."; db->m_fuzzyIndex->endIndexing(); }
void DatabaseCommand_SocialAction::exec( DatabaseImpl* dbi ) { qDebug() << Q_FUNC_INFO; Q_ASSERT( !source().isNull() ); TomahawkSqlQuery query = dbi->newquery(); QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); if ( m_artist.isNull() || m_title.isEmpty() || m_action.isEmpty() ) return; int artid = dbi->artistId( m_artist, true ); if ( artid < 1 ) return; int trkid = dbi->trackId( artid, m_title, true ); if ( trkid < 1 ) return; // update if it already exists TomahawkSqlQuery find = dbi->newquery(); find.prepare( QString( "SELECT id, k, v FROM social_attributes WHERE social_attributes.id = ? AND social_attributes.source %1 AND social_attributes.k = ?" ).arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) ); find.addBindValue( trkid ); find.addBindValue( m_action ); if ( find.exec() && find.next() ) { // update query.prepare( QString( "UPDATE social_attributes SET v = '%1', timestamp = %2 WHERE social_attributes.id = %3 AND social_attributes.source %4 AND social_attributes.k = '%5'" ) .arg( m_comment ) .arg( m_timestamp ) .arg( trkid ) .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) .arg( m_action ) ); } else { query.prepare( "INSERT INTO social_attributes(id, source, k, v, timestamp) " "VALUES (?, ?, ?, ?, ?)" ); query.bindValue( 0, trkid ); query.bindValue( 1, srcid ); query.bindValue( 2, m_action ); query.bindValue( 3, m_comment ); query.bindValue( 4, m_timestamp ); } query.exec(); }
void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) { Q_D( DatabaseCommand_LoadAllPlaylists ); TomahawkSqlQuery query = dbi->newquery(); QString orderToken, sourceToken; switch ( d->sortOrder ) { case 0: break; case ModificationTime: orderToken = "ORDER BY playlist.createdOn"; } if ( !source().isNull() ) sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); QString trackIdJoin; QString trackIdFields; if ( d->returnPlEntryIds ) { trackIdFields = ", pr.entries"; trackIdJoin = "JOIN playlist_revision pr ON pr.playlist = p.guid AND pr.guid = p.currentrevision"; } query.exec( QString( " SELECT p.guid, p.title, p.info, p.creator, p.lastmodified, p.shared, p.currentrevision, p.createdOn %6 " " FROM playlist p " " %5 " " WHERE ( ( dynplaylist = 'false' ) OR ( dynplaylist = 0 ) ) " " %1 " " %2 %3 %4 " ) .arg( sourceToken ) .arg( orderToken ) .arg( d->sortDescending ? "DESC" : QString() ) .arg( d->limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( d->limitAmount ) : QString() ) .arg( trackIdJoin ) .arg( trackIdFields ) ); QList<playlist_ptr> plists; QHash<playlist_ptr, QStringList> phash; while ( query.next() ) { playlist_ptr p( new Playlist( source(), //src query.value(6).toString(), //current rev query.value(1).toString(), //title query.value(2).toString(), //info query.value(3).toString(), //creator query.value(7).toInt(), //lastmod / createdOn query.value(5).toBool(), //shared query.value(4).toInt(), //lastmod query.value(0).toString() //GUID ), &QObject::deleteLater ); p->setWeakSelf( p.toWeakRef() ); plists.append( p ); if ( d->returnPlEntryIds ) { QStringList trackIds = TomahawkUtils::parseJson( query.value( 8 ).toByteArray() ).toStringList(); phash.insert( p, trackIds ); } } emit done( plists ); if ( d->returnPlEntryIds ) { emit done( phash ); } }
void Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND playlist.guid = '%2'" ) .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ).arg( m_plid ) ); QList<dynplaylist_ptr> plists; if( query.next() ) { dynplaylist_ptr p( new DynamicPlaylist( source(), query.value(7).toString(), //current rev query.value(1).toString(), //title query.value(2).toString(), //info query.value(3).toString(), //creator query.value(4).toUInt(), //createdOn query.value(8).toString(), // dynamic type static_cast<GeneratorMode>(query.value(9).toInt()), // dynamic mode query.value(6).toBool(), //shared query.value(5).toInt(), //lastmod query.value(0).toString() ) ); //GUID tLog() << "Loaded individual dynamic playlist:" << query.value(7).toString() //current rev << query.value(1).toString() //title << query.value(2).toString() //info << query.value(3).toString() //creator << query.value(4).toString() //createdOn << query.value(8).toString() // dynamic type << static_cast<GeneratorMode>(query.value(9).toInt()) // dynamic mode << query.value(6).toBool() //shared << query.value(5).toInt() //lastmod << query.value(0).toString(); //GUID emit dynamicPlaylistLoaded( p ); } emit done(); }
void DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); QList<Tomahawk::query_ptr> ql; QString m_orderToken, sourceToken; switch ( m_sortOrder ) { case 0: break; case Album: m_orderToken = "album.name, file_join.discnumber, file_join.albumpos"; break; case ModificationTime: m_orderToken = "file.mtime"; break; case AlbumPosition: m_orderToken = "file_join.discnumber, file_join.albumpos"; break; } if ( !m_collection.isNull() ) sourceToken = QString( "AND file.source %1" ).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) ); QString albumToken; if ( m_album ) { if ( m_album->id() == 0 ) { m_artist = m_album->artist(); albumToken = QString( "AND album.id IS NULL" ); } else albumToken = QString( "AND album.id = %1" ).arg( m_album->id() ); } QString sql = QString( "SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, " //0 "file.duration, file.bitrate, file.url, file.source, file.mtime, " //6 "file.mimetype, file_join.discnumber, file_join.albumpos, artist.id, " //11 "album.id, track.id, composer.id " //15 "FROM file, artist, track, file_join " "LEFT OUTER JOIN album " "ON file_join.album = album.id " "LEFT OUTER JOIN artist AS composer " "ON file_join.composer = composer.id " "WHERE file.id = file_join.file " "AND file_join.artist = artist.id " "AND file_join.track = track.id " "%1 " "%2 %3 " "%4 %5 %6" ).arg( sourceToken ) .arg( !m_artist ? QString() : QString( "AND artist.id = %1" ).arg( m_artist->id() ) ) .arg( !m_album ? QString() : albumToken ) .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() ) .arg( m_sortDescending ? "DESC" : QString() ) .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); query.prepare( sql ); query.exec(); while( query.next() ) { QString url = query.value( 8 ).toString(); Tomahawk::source_ptr s = SourceList::instance()->get( query.value( 9 ).toUInt() ); if ( !s ) { Q_ASSERT( false ); continue; } if ( !s->isLocal() ) url = QString( "servent://%1\t%2" ).arg( s->nodeId() ).arg( url ); QString artist, track, album, composer; artist = query.value( 1 ).toString(); album = query.value( 2 ).toString(); track = query.value( 3 ).toString(); composer = query.value( 4 ).toString(); Tomahawk::result_ptr result = Tomahawk::Result::get( url ); Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album ); Tomahawk::track_ptr t = Tomahawk::Track::get( query.value( 16 ).toUInt(), artist, track, album, query.value( 6 ).toUInt(), composer, query.value( 13 ).toUInt(), query.value( 12 ).toUInt() ); t->loadAttributes(); result->setTrack( t ); result->setSize( query.value( 5 ).toUInt() ); result->setBitrate( query.value( 7 ).toUInt() ); result->setModificationTime( query.value( 10 ).toUInt() ); result->setMimetype( query.value( 11 ).toString() ); result->setScore( 1.0 ); result->setCollection( s->dbCollection() ); QList<Tomahawk::result_ptr> results; results << result; qry->addResults( results ); qry->setResolveFinished( true ); ql << qry; } emit tracks( ql, data() ); emit tracks( ql ); emit done( m_collection ); }
void DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); QString whereToken( "WHERE 1" ); if ( !source().isNull() ) { whereToken += QString( " AND source %1" ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); } if ( m_dateFrom.year() > 1900 && m_dateTo.year() > 1900 ) { whereToken += QString( " AND playtime >= %1 AND playtime <= %2" ) .arg( QDateTime( m_dateFrom ).toUTC().toTime_t() ) .arg( QDateTime( m_dateTo.addDays( 1 ) ).toUTC().toTime_t() ); } QString sql = QString( "SELECT track, playtime, secs_played, source " "FROM playback_log " "%1 " "ORDER BY playtime DESC " "%2" ).arg( whereToken ) .arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() ); query.prepare( sql ); query.exec(); QList<Tomahawk::track_ptr> tl; QList<Tomahawk::PlaybackLog> logs; while ( query.next() ) { TomahawkSqlQuery query_track = dbi->newquery(); QString sql = QString( "SELECT track.name, artist.name " "FROM track, artist " "WHERE artist.id = track.artist " "AND track.id = %1" ).arg( query.value( 0 ).toUInt() ); query_track.prepare( sql ); query_track.exec(); if ( query_track.next() ) { Tomahawk::track_ptr track = Tomahawk::Track::get( query_track.value( 1 ).toString(), query_track.value( 0 ).toString(), QString() ); if ( !track ) continue; Tomahawk::PlaybackLog log; log.timestamp = query.value( 1 ).toUInt(); log.secsPlayed = query.value( 2 ).toUInt(); log.source = SourceList::instance()->get( query.value( 3 ).toUInt() ); logs << log; tl << track; } } emit tracks( tl, logs ); }
void DatabaseCommand_loadOps::exec( DatabaseImpl* dbi ) { QList< dbop_ptr > ops; if ( !m_since.isEmpty() ) { TomahawkSqlQuery query = dbi->newquery(); query.prepare( QString( "SELECT id FROM oplog WHERE guid = ?" ) ); query.addBindValue( m_since ); query.exec(); if ( !query.next() ) { tLog() << "Unknown oplog guid, requested, not replying:" << m_since; Q_ASSERT( false ); emit done( m_since, m_since, ops ); return; } } TomahawkSqlQuery query = dbi->newquery(); query.prepare( QString( "SELECT guid, command, json, compressed, singleton " "FROM oplog " "WHERE source %1 " "AND id > coalesce((SELECT id FROM oplog WHERE guid = ?),0) " "ORDER BY id ASC" ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ) ); query.addBindValue( m_since ); query.exec(); QString lastguid = m_since; while( query.next() ) { dbop_ptr op( new DBOp ); op->guid = query.value( 0 ).toString(); op->command = query.value( 1 ).toString(); op->payload = query.value( 2 ).toByteArray(); op->compressed = query.value( 3 ).toBool(); op->singleton = query.value( 4 ).toBool(); lastguid = op->guid; ops << op; } // qDebug() << "Loaded" << ops.length() << "ops from db"; emit done( m_since, lastguid, ops ); }