1/*
2 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include "modifiedfileindexer.h"
8#include "basicindexingjob.h"
9#include "fileindexerconfig.h"
10#include "idutils.h"
11
12#include "database.h"
13#include "transaction.h"
14
15#include <QMimeDatabase>
16#include <QFile>
17#include <QFileInfo>
18#include <QDateTime>
19
20using namespace Baloo;
21
22ModifiedFileIndexer::ModifiedFileIndexer(Database* db, const FileIndexerConfig* config, const QStringList& files)
23 : m_db(db)
24 , m_config(config)
25 , m_files(files)
26{
27 Q_ASSERT(m_db);
28 Q_ASSERT(m_config);
29 Q_ASSERT(!m_files.isEmpty());
30}
31
32void ModifiedFileIndexer::run()
33{
34 QMimeDatabase mimeDb;
35 BasicIndexingJob::IndexingLevel level = m_config->onlyBasicIndexing() ? BasicIndexingJob::NoLevel
36 : BasicIndexingJob::MarkForContentIndexing;
37
38 Transaction tr(m_db, Transaction::ReadWrite);
39
40 for (const QString &path : m_files) {
41 auto filePath = path;
42 if (filePath.endsWith(c: QLatin1Char('/'))) {
43 filePath.chop(n: 1);
44 }
45
46 QString fileName = filePath.mid(position: filePath.lastIndexOf(c: QLatin1Char('/')) + 1);
47 if (!m_config->shouldFileBeIndexed(fileName)) {
48 continue;
49 }
50
51 quint64 fileId = filePathToId(filePath: QFile::encodeName(fileName: filePath));
52 if (!fileId) {
53 continue;
54 }
55
56 // FIXME: Using QFileInfo over here is quite expensive!
57 QFileInfo fileInfo(filePath);
58 if (fileInfo.isSymLink()) {
59 continue;
60 }
61
62 bool mTimeChanged;
63 bool cTimeChanged;
64 const bool isKnownFile = tr.hasDocument(id: fileId);
65 if (isKnownFile) {
66 DocumentTimeDB::TimeInfo timeInfo = tr.documentTimeInfo(id: fileId);
67 mTimeChanged = timeInfo.mTime != fileInfo.lastModified().toSecsSinceEpoch();
68 cTimeChanged = timeInfo.cTime != fileInfo.metadataChangeTime().toSecsSinceEpoch();
69 } else {
70 mTimeChanged = cTimeChanged = true;
71 }
72
73 if (!mTimeChanged && !cTimeChanged) {
74 continue;
75 }
76
77 QString mimetype;
78 if (fileInfo.isDir()) {
79 // The folder ctime changes when the folder is created, when the folder is
80 // renamed, or when the xattrs (tags, comments, ...) change
81 if (!cTimeChanged) {
82 continue;
83 }
84 mimetype = QStringLiteral("inode/directory");
85
86 } else {
87 mimetype = mimeDb.mimeTypeForFile(fileName: filePath, mode: QMimeDatabase::MatchExtension).name();
88 }
89
90 // Only mTime changed
91 if (!cTimeChanged) {
92 Document doc;
93 doc.setId(fileId);
94 doc.setMTime(fileInfo.lastModified().toSecsSinceEpoch());
95 doc.setCTime(fileInfo.metadataChangeTime().toSecsSinceEpoch());
96 if (level == BasicIndexingJob::MarkForContentIndexing) {
97 doc.setContentIndexing(true);
98 }
99
100 tr.replaceDocument(doc, operations: DocumentTime);
101 continue;
102 }
103
104 BasicIndexingJob job(filePath, mimetype, level);
105 if (!job.index()) {
106 continue;
107 }
108
109 // We can get modified events for files which do not yet exist in the database
110 // because Baloo was not running and missed the creation events
111 if (isKnownFile && (job.document().id() == fileId)) {
112 tr.replaceDocument(doc: job.document(), operations: XAttrTerms | DocumentTime | FileNameTerms | DocumentUrl);
113 } else {
114 tr.addDocument(doc: job.document());
115 }
116 }
117
118 tr.commit();
119 Q_EMIT done();
120}
121
122#include "moc_modifiedfileindexer.cpp"
123

source code of baloo/src/file/modifiedfileindexer.cpp