Added Bluetooth AVRCP support via HAL/DBus
[someplayer] / src / dbstorage.cpp
1 /*
2  * SomePlayer - An alternate music player for Maemo 5
3  * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include "dbstorage.h"
21 #include <QSqlQuery>
22 #include <QSqlResult>
23 #include <QDebug>
24 #include <QFileInfo>
25
26 using namespace SomePlayer::Storage;
27 using namespace SomePlayer::DataObjects;
28
29 DbStorage::DbStorage(QString path) {
30         QString dbname = path + _DATABASE_NAME_;
31         db = QSqlDatabase::addDatabase("QSQLITE");
32         db.setDatabaseName(dbname);
33         if (!db.open()) {
34                 // throw big exception
35         }
36         // create database structure
37         _create_database_structure();
38         _prepare_queries();
39 }
40
41 void DbStorage::_prepare_queries() {
42         _get_artists_query = new QSqlQuery(db);
43         _get_artists_query->prepare("SELECT name FROM artist ORDER BY uname");
44
45         _get_albums_for_artist_sort_name_query = new QSqlQuery(db);
46         _get_albums_for_artist_sort_name_query->prepare("SELECT name, year FROM album WHERE artist_id in (SELECT id from artist WHERE uname = :uname) ORDER BY uname;");
47
48         _get_albums_for_artist_sort_year_query = new QSqlQuery(db);
49         _get_albums_for_artist_sort_year_query->prepare("SELECT name, year FROM album WHERE artist_id in (SELECT id from artist WHERE uname = :uname) ORDER BY year;");
50
51         _get_tracks_for_album_query = new QSqlQuery(db);
52         _get_tracks_for_album_query->prepare("SELECT id, title, source, count, length FROM tracks WHERE artist_id IN "
53                                                                 "(SELECT id FROM artist WHERE uname = :artist_uname) AND album_id IN "
54                                                                 "(SELECT id FROM album WHERE uname = :album_uname);");
55
56         _get_favorites_query = new QSqlQuery(db);
57         _get_favorites_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
58                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
59                                                                 "tracks JOIN artist ON tracks.artist_id = artist.id) "
60                                                                 "JOIN album ON album_id = album.id WHERE track_id IN "
61                                                                 "(SELECT track_id FROM favorites);");
62
63         _get_most_played_query = new QSqlQuery(db);
64         _get_most_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
65                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
66                                                                 "tracks JOIN artist ON tracks.artist_id = artist.id) "
67                                                                 "JOIN album ON album_id = album.id ORDER BY count DESC "
68                                                                 "LIMIT 0, :max");
69
70         _get_never_played_query = new QSqlQuery(db);
71         _get_never_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
72                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
73                                                                 "tracks JOIN artist ON tracks.artist_id = artist.id) "
74                                                                 "JOIN album ON album_id = album.id "
75                                                                 "WHERE count = 0");
76
77         _get_recently_added_query = new QSqlQuery(db);
78         _get_recently_added_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
79                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
80                                                                 "tracks JOIN artist ON tracks.artist_id = artist.id) "
81                                                                 "JOIN album ON album_id = album.id "
82                                                                 "WHERE track_id IN "
83                                                                 "(SELECT track_id FROM adding_date ORDER BY date DESC LIMIT 0, :max)");
84
85         _get_track_count_query = new QSqlQuery(db);
86         _get_track_count_query->prepare("SELECT count from tracks WHERE id = :id");
87
88         _get_tracks_by_pattern_query = new QSqlQuery(db);
89         _get_tracks_by_pattern_query->prepare("SELECT id, title, artist, album, source, count, length, year FROM "
90                                               "entire WHERE "
91                                               "utitle LIKE (SELECT '%' || :ptitle || '%') "
92                                               "ORDER BY artist_uname, year");
93
94         _get_track_id_by_source_query = new QSqlQuery(db);
95         _get_track_id_by_source_query->prepare("SELECT id FROM tracks WHERE source = :source");
96
97         _get_directories_query = new QSqlQuery(db);
98         _get_directories_query->prepare("SELECT id, path FROM directories");
99
100         _get_artists_count_query = new QSqlQuery(db);
101         _get_artists_count_query->prepare("SELECT COUNT(id) AS cnt FROM artist");
102
103         _get_albums_count_query = new QSqlQuery(db);
104         _get_albums_count_query->prepare("SELECT COUNT(id) AS cnt FROM album");
105
106         _get_tracks_count_query = new QSqlQuery(db);
107         _get_tracks_count_query->prepare("SELECT COUNT(id) AS cnt FROM tracks");
108
109         _get_tracks_source_from_query = new QSqlQuery(db);
110         _get_tracks_source_from_query->prepare("SELECT source FROM tracks WHERE directory = :directory_id");
111
112         _check_artist_query = new QSqlQuery(db);
113         _check_artist_query->prepare("SELECT id FROM artist WHERE uname = :uname");
114
115         _check_album_query = new QSqlQuery(db);
116         _check_album_query->prepare("SELECT id FROM album WHERE uname = :uname AND artist_id = :artist_id");
117
118         _check_directory_query = new QSqlQuery(db);
119         _check_directory_query->prepare("SELECT id from directories WHERE path = :path");
120
121         _insert_artist_query = new QSqlQuery(db);
122         _insert_artist_query->prepare("INSERT INTO artist (name, uname) values (:name, :uname)");
123
124         _insert_album_query = new QSqlQuery(db);
125         _insert_album_query->prepare("INSERT INTO album (name, uname, artist_id, year) values (:name, :uname, :artist_id, :year)");
126
127         _insert_track_query = new QSqlQuery(db);
128         _insert_track_query->prepare("INSERT INTO tracks (title, utitle, artist_id, album_id, source, directory, length) values (:title, :utitle, :artist_id, :album_id, :source, :directory_id, :length)");
129
130         _insert_date_query = new QSqlQuery(db);
131         _insert_date_query->prepare("INSERT INTO adding_date (track_id, date) values (:track_id, strftime('%s', 'now'))");
132
133         _insert_favorites_query = new QSqlQuery(db);
134         _insert_favorites_query->prepare("INSERT INTO favorites (track_id) values (:track_id)");
135
136         _insert_directory_query = new QSqlQuery(db);
137         _insert_directory_query->prepare("INSERT INTO directories (path) values (:path)");
138
139         _update_track_count_query = new QSqlQuery(db);
140         _update_track_count_query->prepare("UPDATE tracks SET count = :count where id = :id");
141
142         _remove_track_query = new QSqlQuery(db);
143         _remove_track_query->prepare("DELETE FROM tracks WHERE id = :id");
144
145         _remove_empty_albums_query = new QSqlQuery(db);
146         _remove_empty_albums_query->prepare("DELETE FROM album WHERE album.id IN "
147                                             "(SELECT id FROM "
148                                             "(SELECT COUNT(tracks.id) AS cnt, album.id FROM "
149                                             "album LEFT OUTER JOIN tracks ON album.id = tracks.album_id "
150                                             "GROUP BY album.id) WHERE cnt = 0)");
151
152         _remove_empty_artists_query = new QSqlQuery(db);
153         _remove_empty_artists_query->prepare("DELETE FROM artist WHERE artist.id IN "
154                                              "(SELECT id FROM "
155                                              "(SELECT COUNT(tracks.id) AS cnt, artist.id FROM "
156                                              "artist LEFT OUTER JOIN tracks ON artist.id = tracks.artist_id "
157                                              "GROUP BY artist.id) WHERE cnt = 0)");
158
159         _remove_tracks_from_query = new QSqlQuery(db);
160         _remove_tracks_from_query->prepare("DELETE FROM tracks WHERE directory = :directory_id");
161
162         _remove_directory_query = new QSqlQuery(db);
163         _remove_directory_query->prepare("DELETE FROM directories WHERE path = :path");
164
165         _remove_track_from_favorites_query = new QSqlQuery(db);
166         _remove_track_from_favorites_query->prepare("DELETE FROM favorites WHERE track_id in (SELECT id FROM tracks WHERE source = :source)");
167 }
168
169 void DbStorage::_create_database_structure() {
170         QSqlQuery *query = new QSqlQuery(db);
171         query->exec("create table artist (id integer primary key, "
172                                                                 "name text, "
173                                                                 "uname text "
174                                                                 ");");
175         query->exec("create table album (id integer primary key, "
176                                                                 "artist_id integer, "
177                                                                 "name text, "
178                                                                 "uname text, "
179                                                                 "year int, "
180                                                                 "foreign key(artist_id) references arist(id) "
181                                                                 ");");
182         query->exec("create table tracks (id integer primary key, "
183                                                                 "artist_id integer, "
184                                                                 "album_id integer, "
185                                                                 "title text, "
186                                                                 "utitle text, "
187                                                                 "source text, "
188                                                                 "directory integer, "
189                                                                 "count integer default 0, "
190                                                                 "length integer default 0, "
191                                                                 "foreign key(artist_id) references artist(id), "
192                                                                 "foreign key(album_id) references album(id) "
193                                                                 ");");
194         query->exec("create table favorites (track_id integer, "
195                                                                 "foreign key(track_id) references tracks(id) "
196                                                                 ");");
197         query->exec("create table adding_date (track_id integer, "
198                                                                 "date integer, "
199                                                                 "foreign key(track_id) references tracks(id) "
200                                                                 ");");
201         query->exec("create view entire as "
202                     "select id, title, artist_name as artist, album_name as album, source, count, length, album_year as year, utitle, artist_uname, album_uname from "
203                         "tracks left join "
204                                 "(select artist.id as aartist_id, "
205                                 "artist.uname as artist_uname, "
206                                 "artist.name as artist_name, "
207                                 "album.uname as album_uname, "
208                                 "album.year as album_year, "
209                                 "album.id as aalbum_id, "
210                                 "album.name as album_name from "
211                                         "artist "
212                                         "join album "
213                                         "on album.artist_id = artist.id) "
214                                 "on aartist_id = tracks.artist_id "
215                                 "and aalbum_id = tracks.album_id");
216
217         query->exec("create table directories (id integer primary key, path text)");
218 }
219
220 DbStorage::~DbStorage() {
221         delete _get_albums_for_artist_sort_name_query;
222         delete _get_albums_for_artist_sort_year_query;
223         delete _get_artists_query;
224         delete _get_favorites_query;
225         delete _get_most_played_query;
226         delete _get_never_played_query;
227         delete _get_recently_added_query;
228         delete _get_tracks_for_album_query;
229         delete _get_tracks_by_pattern_query;
230         delete _get_directories_query;
231         delete _get_artists_count_query;
232         delete _get_albums_count_query;
233         delete _get_tracks_count_query;
234         delete _get_tracks_source_from_query;
235         delete _check_album_query;
236         delete _check_artist_query;
237         delete _check_directory_query;
238         delete _get_track_id_by_source_query;
239         delete _insert_album_query;
240         delete _insert_artist_query;
241         delete _insert_date_query;
242         delete _insert_track_query;
243         delete _insert_favorites_query;
244         delete _insert_directory_query;
245         delete _update_track_count_query;
246         delete _remove_track_query;
247         delete _remove_directory_query;
248         delete _remove_tracks_from_query;
249         delete _remove_track_from_favorites_query;
250         db.close();
251 }
252
253 QList<QString> DbStorage::getArtists() {
254         QList<QString> artists;
255         QSqlQuery *query = _get_artists_query;
256         query->exec();
257         while (query->next()) {
258                 QString name = query->value(0).toString();
259                 artists.append(name);
260         }
261         return artists;
262 }
263
264 QMap<QString, int> DbStorage::getAlbumsForArtist(QString artist) {
265         QMap<QString, int> albums;
266         Config config;
267         QString sort = config.getValue("ui/albumsorting").toString();
268         QSqlQuery *query = NULL;
269         if (sort == "date") {
270                 query = _get_albums_for_artist_sort_year_query;
271         } else {
272                 query = _get_albums_for_artist_sort_name_query;
273         }
274         query->bindValue(":uname", artist.toUpper());
275         query->exec();
276         while (query->next()) {
277                 QString name = query->value(0).toString();
278                 albums[name] = query->value(1).toInt();
279         }
280         return albums;
281 }
282
283 QList<Track> DbStorage::getTracksForAlbum(QString album, QString artist) {
284         QList<Track> tracks;
285         QSqlQuery *query = _get_tracks_for_album_query;
286         query->bindValue(":artist_uname", artist.toUpper());
287         query->bindValue(":album_uname", album.toUpper());
288         query->exec();
289
290         while (query->next()) {
291                 QString title = query->value(1).toString();
292                 QString source = query->value(2).toString();
293                 int count = query->value(3).toInt();
294                 int length = query->value(4).toInt();
295                 TrackMetadata meta (title, artist, album, length);
296                 Track track(meta, source);
297                 track.setCount(count);
298                 tracks.append(track);
299         }
300
301         return tracks;
302 }
303
304 Playlist DbStorage::getFavorites() {
305         Playlist playlist;
306         QSqlQuery *query = _get_favorites_query;
307         query->exec();
308         while(query->next()) {
309                 QString title = query->value(1).toString();
310                 QString artist = query->value(2).toString();
311                 QString album = query->value(3).toString();
312                 QString source = query->value(4).toString();
313                 int count = query->value(5).toInt();
314                 int length = query->value(6).toInt();
315                 TrackMetadata meta(title, artist, album, length);
316                 Track track(meta, source);
317                 track.setCount(count);
318                 playlist.addTrack(track);
319                 playlist.setName("Favorites");
320         }
321         return playlist;
322 }
323
324 Playlist DbStorage::getMostPlayed() {
325         Playlist playlist;
326         QSqlQuery *query = _get_most_played_query;
327         query->bindValue(":max", _DYNAMIC_PLAYLIST_MAX_COUNT_);
328         query->exec();
329         while (query->next()) {
330                 QString title = query->value(1).toString();
331                 QString artist = query->value(2).toString();
332                 QString album = query->value(3).toString();
333                 QString source = query->value(4).toString();
334                 int count = query->value(5).toInt();
335                 int length = query->value(6).toInt();
336                 TrackMetadata meta(title, artist, album, length);
337                 Track track(meta, source);
338                 track.setCount(count);
339                 playlist.addTrack(track);
340                 playlist.setName("Most popular");
341         }
342         return playlist;
343 }
344
345 Playlist DbStorage::getNeverPlayed() {
346         Playlist playlist;
347         QSqlQuery *query = _get_never_played_query;
348         query->bindValue(":max", _DYNAMIC_PLAYLIST_MAX_COUNT_);
349         query->exec();
350         while (query->next()) {
351                 QString title = query->value(1).toString();
352                 QString artist = query->value(2).toString();
353                 QString album = query->value(3).toString();
354                 QString source = query->value(4).toString();
355                 int count = query->value(5).toInt();
356                 int length = query->value(6).toInt();
357                 TrackMetadata meta(title, artist, album, length);
358                 Track track(meta, source);
359                 track.setCount(count);
360                 playlist.addTrack(track);
361                 playlist.setName("Never played");
362         }
363         return playlist;
364 }
365
366 Playlist DbStorage::getRecentlyAdded() {
367         Playlist playlist;
368         QSqlQuery *query = _get_recently_added_query;
369         query->bindValue(":max", _DYNAMIC_PLAYLIST_MAX_COUNT_);
370         query->exec();
371         while (query->next()) {
372                 QString title = query->value(1).toString();
373                 QString artist = query->value(2).toString();
374                 QString album = query->value(3).toString();
375                 QString source = query->value(4).toString();
376                 int count = query->value(5).toInt();
377                 int length = query->value(6).toInt();
378                 TrackMetadata meta(title, artist, album, length);
379                 Track track(meta, source);
380                 track.setCount(count);
381                 playlist.addTrack(track);
382                 playlist.setName("Recently added");
383         }
384         return playlist;
385 }
386
387 void DbStorage::removeTrack(Track track) {
388         QSqlQuery *query = _get_track_id_by_source_query;
389         query->bindValue(":source", track.source());
390         query->exec();
391         if (query->next()) {
392                 int id = query->value(0).toInt();
393                 query = new QSqlQuery(db);
394                 query->prepare("DELETE FROM tracks WHERE id = :id;");
395                 query->bindValue(":id", id);
396                 query->exec();
397                 query->prepare("DELETE FROM favorites WHERE track_id = :id;");
398                 query->bindValue(":id", id);
399                 query->exec();
400                 query->prepare("DELETE FROM adding_date WHERE id = :id;");
401                 query->bindValue(":id", id);
402                 query->exec();
403         }
404 }
405
406 void DbStorage::addTrack(Track track) {
407         QString title = track.metadata().title();
408         QString artist = track.metadata().artist();
409         QString album = track.metadata().album();
410         QString source = track.source();
411         QFileInfo info(source);
412         QString path = info.canonicalPath();
413         int year = track.metadata().year();
414         int artist_id = _check_add_artist(artist);
415         int album_id = _check_add_album(album, artist_id, year);
416         if (artist_id == -1 || album_id == -1) {
417                 //big bang
418                 return;
419         }
420         QSqlQuery *query = _get_track_id_by_source_query;
421         query->bindValue(":source", source);
422         query->exec();
423         if (query->next()) {
424                 // already in datebase, skip
425                 return;
426         }
427         query = _insert_track_query;
428         query->bindValue(":title", title);
429         query->bindValue(":utitle", title.toUpper());
430         query->bindValue(":artist_id", artist_id);
431         query->bindValue(":album_id", album_id);
432         query->bindValue(":source", source);
433         query->bindValue(":directory", _check_add_directory(path));
434         query->bindValue(":length", track.metadata().length());
435         if (query->exec()) {
436                 //ok
437                 query = _get_track_id_by_source_query;
438                 query->bindValue(":source", source);
439                 query->exec();
440                 if (query->next()) {
441                         int id = query->value(0).toInt();
442                         query = _insert_date_query;
443                         query->bindValue(":track_id", id);
444                         if (query->exec()) {
445                                 // ok
446                         } else {
447                                 // big bang
448                         }
449                 } else {
450                         // big bang
451                 }
452         } else {
453                 // big bang
454         }
455 }
456
457 void DbStorage::addToFavorites(Track track) {
458         QSqlQuery *query = _get_track_id_by_source_query;
459         query->bindValue(":source", track.source());
460         query->exec();
461         if (query->next()) {
462                 int id = query->value(0).toInt();
463                 query = _insert_favorites_query;
464                 query->bindValue(":track_id", id);
465                 query->exec();
466         }
467 }
468
469 void DbStorage::updateTrackCount(Track track) {
470         QSqlQuery *query = _get_track_id_by_source_query;
471         query->bindValue(":source", track.source());
472         query->exec();
473         if (query->next()) {
474                 int id = query->value(0).toInt();
475                 query = _get_track_count_query;
476                 query->bindValue(":id", id);
477                 query->exec();
478                 if (query->next()) {
479                         int count = query->value(0).toInt();
480                         query = _update_track_count_query;
481                         query->bindValue(":count", count+1);
482                         query->bindValue(":id", id);
483                         query->exec();
484                 }
485         }
486 }
487
488 Track DbStorage::updateTrack(Track track) {
489         QSqlQuery *query = _get_track_id_by_source_query;
490         query->bindValue(":source", track.source());
491         query->exec();
492         if (query->next()) { // found track in library
493                 int id = query->value(0).toInt();
494                 query = _remove_track_query;
495                 query->bindValue(":id", id);
496                 query->exec();
497                 addTrack(track);
498                 _cleanup();
499         }
500         return track;
501 }
502
503 int DbStorage::_check_add_artist(QString artist) {
504         QSqlQuery *query = _check_artist_query;
505         query->bindValue(":uname", artist.toUpper());
506         query->exec();
507         if (query->next()) {
508                 int id = query->value(0).toInt();
509                 return id;
510         } else {
511                 query = _insert_artist_query;
512                 query->bindValue(":name", artist);
513                 query->bindValue(":uname", artist.toUpper());
514                 if (query->exec()) {
515                         return _check_add_artist(artist);
516                 } else {
517                         // big bang
518                         return -1;
519                 }
520         }
521 }
522
523 int DbStorage::_check_add_album(QString album, int artist_id, int year) {
524         QSqlQuery *query = _check_album_query;
525         query->bindValue(":uname", album.toUpper());
526         query->bindValue(":artist_id", artist_id);
527         query->exec();
528         if (query->next()) {
529                 int id = query->value(0).toInt();
530                 return id;
531         } else {
532                 query = _insert_album_query;
533                 query->bindValue(":name", album);
534                 query->bindValue(":uname", album.toUpper());
535                 query->bindValue(":artist_id", artist_id);
536                 query->bindValue(":year", year);
537                 if (query->exec()) {
538                         return _check_add_album(album, artist_id, year);
539                 } else {
540                         // big bang
541                         return -1;
542                 }
543         }
544 }
545
546 QList<Track> DbStorage::searchTracks(QString pattern) {
547         QList <Track> found;
548         QSqlQuery *query = _get_tracks_by_pattern_query;
549         query->bindValue(":ptitle", pattern.toUpper()); // with :pattern only doesn't work
550         query->exec();
551         // id, title, artist, album, source, count, length, year
552         while (query->next()) {
553                 QString title = query->value(1).toString();
554                 QString artist = query->value(2).toString();
555                 QString album = query->value(3).toString();
556                 QString source = query->value(4).toString();
557                 int count = query->value(5).toInt();
558                 int length = query->value(6).toInt();
559                 int year = query->value(7).toInt();
560                 TrackMetadata meta(title, artist, album, length);
561                 meta.setYear(year);
562                 Track track(meta, source);
563                 track.setCount(count);
564                 found.append(track);
565         }
566         return found;
567 }
568
569 void DbStorage::_cleanup() {
570         _remove_empty_albums_query->exec();
571         _remove_empty_artists_query->exec();
572 }
573
574 int DbStorage::_check_add_directory(QString path) {
575         QSqlQuery *query = _check_directory_query;
576         query->bindValue(":path", path);
577         query->exec();
578         if (query->next()) {
579                 return query->value(0).toInt();
580         } else {
581                 query = _insert_directory_query;
582                 query->bindValue(":path", path);
583                 query->exec();
584                 return _check_add_directory(path);
585         }
586 }
587
588 QList<QString> DbStorage::getDirectories() {
589         QSqlQuery *query = _get_directories_query;
590         query->exec();
591         QList<QString> directories;
592         while (query->next()) {
593                 directories.append(query->value(1).toString());
594         }
595         return directories;
596 }
597
598 int DbStorage::getArtistsCount() {
599         QSqlQuery *query = _get_artists_count_query;
600         query->exec();
601         if (query->next()) {
602                 return query->value(0).toInt();
603         }
604         return 0;
605 }
606
607 int DbStorage::getAlbumsCount() {
608         QSqlQuery *query = _get_albums_count_query;
609         query->exec();
610         if (query->next()) {
611                 return query->value(0).toInt();
612         }
613         return 0;
614 }
615
616 int DbStorage::getTracksCount() {
617         QSqlQuery *query = _get_tracks_count_query;
618         query->exec();
619         if (query->next()) {
620                 return query->value(0).toInt();
621         }
622         return 0;
623 }
624
625 void DbStorage::deleteTracksFrom(QString path) {
626         QSqlQuery *query = _check_directory_query;
627         query->bindValue(":path", path);
628         query->exec();
629         if (query->next()) {
630                 int id = query->value(0).toInt();
631                 query = _remove_tracks_from_query;
632                 query->bindValue(":directory_id", id);
633                 query->exec();
634                 query = _remove_directory_query;
635                 query->bindValue(":path", path);
636                 query->exec();
637                 _cleanup();
638         }
639 }
640
641 void DbStorage::checkTracksFrom(QString path) {
642         QSqlQuery *query = _check_directory_query;
643         query->bindValue(":path", path);
644         query->exec();
645         if (query->next()) {
646                 int id = query->value(0).toInt();
647                 query = _get_tracks_source_from_query;
648                 query->bindValue(":directory_id", id);
649                 query->exec();
650                 while (query->next()) {
651                         QString source = query->value(0).toString();
652                         if (!QFile::exists(source)) {
653                                 Track track(TrackMetadata(), source);   // removeTrack uses only source field, so
654                                 removeTrack(track);                     // we can use this method
655                         }
656                 }
657                 _cleanup();
658         }
659 }
660
661 void DbStorage::removeFromFavorites(Track track) {
662         QSqlQuery *query = _remove_track_from_favorites_query;
663         query->bindValue(":source", track.source());
664         query->exec();
665 }