File indexing completed on 2024-05-05 07:52:16
0001 /* 0002 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "modifiedfileindexer.h" 0008 #include "basicindexingjob.h" 0009 #include "fileindexerconfig.h" 0010 #include "idutils.h" 0011 0012 #include "database.h" 0013 #include "transaction.h" 0014 0015 #include <QMimeDatabase> 0016 #include <QFile> 0017 #include <QFileInfo> 0018 #include <QDateTime> 0019 0020 using namespace Baloo; 0021 0022 ModifiedFileIndexer::ModifiedFileIndexer(Database* db, const FileIndexerConfig* config, const QStringList& files) 0023 : m_db(db) 0024 , m_config(config) 0025 , m_files(files) 0026 { 0027 Q_ASSERT(m_db); 0028 Q_ASSERT(m_config); 0029 Q_ASSERT(!m_files.isEmpty()); 0030 } 0031 0032 void ModifiedFileIndexer::run() 0033 { 0034 QMimeDatabase mimeDb; 0035 BasicIndexingJob::IndexingLevel level = m_config->onlyBasicIndexing() ? BasicIndexingJob::NoLevel 0036 : BasicIndexingJob::MarkForContentIndexing; 0037 0038 Transaction tr(m_db, Transaction::ReadWrite); 0039 0040 for (const QString& filePath : std::as_const(m_files)) { 0041 Q_ASSERT(!filePath.endsWith(QLatin1Char('/'))); 0042 0043 QString fileName = filePath.mid(filePath.lastIndexOf(QLatin1Char('/')) + 1); 0044 if (!m_config->shouldFileBeIndexed(fileName)) { 0045 continue; 0046 } 0047 0048 quint64 fileId = filePathToId(QFile::encodeName(filePath)); 0049 if (!fileId) { 0050 continue; 0051 } 0052 0053 // FIXME: Using QFileInfo over here is quite expensive! 0054 QFileInfo fileInfo(filePath); 0055 if (fileInfo.isSymLink()) { 0056 continue; 0057 } 0058 0059 bool mTimeChanged; 0060 bool cTimeChanged; 0061 const bool isKnownFile = tr.hasDocument(fileId); 0062 if (isKnownFile) { 0063 DocumentTimeDB::TimeInfo timeInfo = tr.documentTimeInfo(fileId); 0064 mTimeChanged = timeInfo.mTime != fileInfo.lastModified().toSecsSinceEpoch(); 0065 cTimeChanged = timeInfo.cTime != fileInfo.metadataChangeTime().toSecsSinceEpoch(); 0066 } else { 0067 mTimeChanged = cTimeChanged = true; 0068 } 0069 0070 if (!mTimeChanged && !cTimeChanged) { 0071 continue; 0072 } 0073 0074 QString mimetype; 0075 if (fileInfo.isDir()) { 0076 // The folder ctime changes when the folder is created, when the folder is 0077 // renamed, or when the xattrs (tags, comments, ...) change 0078 if (!cTimeChanged) { 0079 continue; 0080 } 0081 mimetype = QStringLiteral("inode/directory"); 0082 0083 } else { 0084 mimetype = mimeDb.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension).name(); 0085 } 0086 0087 // Only mTime changed 0088 if (!cTimeChanged) { 0089 Document doc; 0090 doc.setId(fileId); 0091 doc.setMTime(fileInfo.lastModified().toSecsSinceEpoch()); 0092 doc.setCTime(fileInfo.metadataChangeTime().toSecsSinceEpoch()); 0093 if (level == BasicIndexingJob::MarkForContentIndexing) { 0094 doc.setContentIndexing(true); 0095 } 0096 0097 tr.replaceDocument(doc, DocumentTime); 0098 continue; 0099 } 0100 0101 BasicIndexingJob job(filePath, mimetype, level); 0102 if (!job.index()) { 0103 continue; 0104 } 0105 0106 // We can get modified events for files which do not yet exist in the database 0107 // because Baloo was not running and missed the creation events 0108 if (isKnownFile && (job.document().id() == fileId)) { 0109 tr.replaceDocument(job.document(), XAttrTerms | DocumentTime | FileNameTerms | DocumentUrl); 0110 } else { 0111 tr.addDocument(job.document()); 0112 } 0113 } 0114 0115 tr.commit(); 0116 Q_EMIT done(); 0117 } 0118 0119 #include "moc_modifiedfileindexer.cpp"