File indexing completed on 2025-01-05 04:25:58
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * Copyright (c) 2008 Seb Ruiz <ruiz@kde.org> * 0004 * Copyright (c) 2009-2010 Jeff Mitchell <mitchell@kde.org> * 0005 * Copyright (c) 2013 Ralf Engels <ralf-engels@gmx.de> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify it under * 0008 * the terms of the GNU General Public License as published by the Free Software * 0009 * Foundation; either version 2 of the License, or (at your option) any later * 0010 * version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0013 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0014 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License along with * 0017 * this program. If not, see <http://www.gnu.org/licenses/>. * 0018 ****************************************************************************************/ 0019 0020 #ifndef AMAROK_SQL_SCANRESULTPROCESSOR_H 0021 #define AMAROK_SQL_SCANRESULTPROCESSOR_H 0022 0023 #include "scanner/AbstractScanResultProcessor.h" 0024 #include "core-impl/collections/db/sql/SqlCollection.h" 0025 0026 /** The ScanResulProcessor class takes the results from the ScanManager and puts them into the database. 0027 */ 0028 class SqlScanResultProcessor : public AbstractScanResultProcessor 0029 { 0030 Q_OBJECT 0031 0032 public: 0033 SqlScanResultProcessor( GenericScanManager* manager, 0034 Collections::SqlCollection *collection, 0035 QObject *parent = nullptr ); 0036 ~SqlScanResultProcessor() override; 0037 0038 0039 protected Q_SLOTS: 0040 void scanStarted( GenericScanManager::ScanType type ) override; 0041 void scanSucceeded() override; 0042 0043 virtual void displayMessages(); 0044 0045 protected: 0046 void message( const QString& message ) override; 0047 0048 void commitDirectory( QSharedPointer<CollectionScanner::Directory> directory ) override; 0049 void commitAlbum( CollectionScanner::Album *album ) override; 0050 void commitTrack( CollectionScanner::Track *track, CollectionScanner::Album *srcAlbum ) override; 0051 0052 /** Deletes all directories (and it's tracks) not contained in m_foundDirectories */ 0053 void deleteDeletedDirectories() override; 0054 0055 void deleteDeletedTracksAndSubdirs( QSharedPointer<CollectionScanner::Directory> directory ) override; 0056 0057 /** Removes all tracks contained in the directory dirId that are not contained in m_foundTracks. */ 0058 virtual void deleteDeletedTracks( int directoryId ); 0059 0060 void cleanupMembers() override; 0061 0062 void blockUpdates(); 0063 void unblockUpdates(); 0064 0065 private: 0066 // to speed up the scanning we buffer the whole urls table 0067 struct UrlEntry { 0068 int id; 0069 QString path; 0070 int directoryId; 0071 QString uid; 0072 }; 0073 friend QDebug operator<<( QDebug, const UrlEntry& ); 0074 0075 /** 0076 * Finds best url id of a track identified by @param uid uniqueid in caches. If 0077 * multiple entries are found, tries to use @param path as a hint. 0078 * 0079 * @returns url id or -1 if nothing is found. 0080 */ 0081 int findBestUrlId( const QString &uid, const QString &path ); 0082 0083 /** 0084 * Directory id has changed from @param oldDirId to @param newDirId without 0085 * actual change in the absolute directory path or contents. Try to relocate 0086 * tracks to the new directory, updating necessary fields. 0087 * @return true if all tracks were successfully relocated and the old dir can be 0088 * deleted without losses, false otherwise. 0089 */ 0090 bool relocateTracksToNewDirectory( int oldDirId, int newDirId ); 0091 0092 /** 0093 * Remove track from the database. Does not touch the cache - you should probably 0094 * call urlsCacheRemove( entry ) 0095 */ 0096 void removeTrack( const UrlEntry &entry ); 0097 0098 struct DirectoryEntry { 0099 int dirId; 0100 int deviceId; 0101 QString dir; 0102 }; 0103 0104 /** 0105 * Get a list of all mounted directories from the database. 0106 */ 0107 QList<DirectoryEntry> mountedDirectories() const; 0108 0109 /** 0110 * Get a list of directories that have been physically removed during the 0111 * PartialUpdateScan. 0112 */ 0113 QList<DirectoryEntry> deletedDirectories() const; 0114 0115 Collections::SqlCollection *m_collection; 0116 0117 /** 0118 * Contains all found directories with their absolute path and id 0119 */ 0120 QHash<QString, int> m_foundDirectories; 0121 0122 /** 0123 * Contains all found tracks with the unique id and url id. QMultiHash only 0124 * because it implements contains( key, value ) 0125 */ 0126 QMultiHash<QString, int> m_foundTracks; 0127 0128 /** 0129 * In UpdateScan and PartialUpdateScan this set gets filled with directory ids 0130 * that have been (non-recursively) fully scanned (not skipped). Direct child 0131 * directories from the database that are not contained in m_foundDirectories can 0132 * be considered deleted. 0133 */ 0134 QSet<int> m_scannedDirectoryIds; 0135 0136 // never dereference they key, it might be a stale pointer in corner cases 0137 QHash<CollectionScanner::Directory*, int> m_directoryIds; 0138 QHash<CollectionScanner::Album*, int> m_albumIds; 0139 0140 void urlsCacheInit(); 0141 /** 0142 * Inserts @param entry into caches. If an entry with same url id already exists 0143 * in cache, it will be replaced. Duplicates in uidUrl and path are _not_ avoided, 0144 * m_uidCache and m_pathCache will point to most recently added entry. 0145 */ 0146 void urlsCacheInsert( const UrlEntry &entry ); 0147 void urlsCacheRemove( const UrlEntry &entry ); 0148 0149 /// maps UrlEntry id to UrlEntry 0150 QHash<int, UrlEntry> m_urlsCache; 0151 /// maps uid to UrlEntry id 0152 QMultiHash<QString, int> m_uidCache; 0153 /// maps path to UrlEntry id 0154 QHash<QString, int> m_pathCache; 0155 /// maps directory id to UrlEntry id 0156 QMultiHash<int, int> m_directoryCache; 0157 0158 QDateTime m_blockedTime; 0159 QStringList m_messages; 0160 }; 0161 0162 QDebug operator<<( QDebug dbg, const SqlScanResultProcessor::UrlEntry &entry ); 0163 0164 #endif