File indexing completed on 2024-04-21 03:51:45

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"