1/*
2 This file is part of the KDE Project
3 SPDX-FileCopyrightText: 2009-2011 Sebastian Trueg <trueg@kde.org>
4 SPDX-FileCopyrightText: 2013-2014 Vishesh Handa <vhanda@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "metadatamover.h"
10#include "database.h"
11#include "termgenerator.h"
12#include "transaction.h"
13#include "baloodebug.h"
14
15#include <QFile>
16
17using namespace Baloo;
18
19MetadataMover::MetadataMover(Database* db, QObject* parent)
20 : QObject(parent)
21 , m_db(db)
22{
23}
24
25MetadataMover::~MetadataMover()
26{
27}
28
29void MetadataMover::moveFileMetadata(const QString& from, const QString& to)
30{
31// qCDebug(BALOO) << from << to;
32 Q_ASSERT(!from.isEmpty() && from != QLatin1String("/"));
33 Q_ASSERT(!to.isEmpty() && to != QLatin1String("/"));
34
35 Transaction tr(m_db, Transaction::ReadWrite);
36
37 // We do NOT get deleted messages for overwritten files! Thus, we
38 // have to remove all metadata for overwritten files first.
39 removeMetadata(tr: &tr, url: to);
40
41 // and finally update the old statements
42 updateMetadata(tr: &tr, from, to);
43
44 tr.commit();
45}
46
47void MetadataMover::removeFileMetadata(const QString& file)
48{
49 Q_ASSERT(!file.isEmpty() && file != QLatin1String("/"));
50
51 Transaction tr(m_db, Transaction::ReadWrite);
52 removeMetadata(tr: &tr, url: file);
53 tr.commit();
54}
55
56void MetadataMover::removeMetadata(Transaction* tr, const QString& url)
57{
58 Q_ASSERT(!url.isEmpty());
59
60 quint64 id = tr->documentId(path: QFile::encodeName(fileName: url));
61 if (!id) {
62 Q_EMIT fileRemoved(path: url);
63 return;
64 }
65
66 bool isDir = url.endsWith(c: QLatin1Char('/'));
67 if (!isDir) {
68 tr->removeDocument(id);
69 } else {
70 tr->removeRecursively(parentId: id);
71 }
72
73 Q_EMIT fileRemoved(path: url);
74}
75
76void MetadataMover::updateMetadata(Transaction* tr, const QString& from, const QString& to)
77{
78 qCDebug(BALOO) << from << "->" << to;
79 Q_ASSERT(!from.isEmpty() && !to.isEmpty());
80 Q_ASSERT(to[to.size()-1] != QLatin1Char('/'));
81
82 // directory case
83 auto normalizedFrom = from;
84 if (normalizedFrom.endsWith(c: QLatin1Char('/'))) {
85 normalizedFrom.chop(n: 1);
86 }
87
88 const QByteArray fromPath = QFile::encodeName(fileName: normalizedFrom);
89 quint64 id = tr->documentId(path: fromPath);
90 if (!id) {
91 qCDebug(BALOO) << "Document not (yet) known, signaling newFile" << to;
92 Q_EMIT movedWithoutData(path: to);
93 return;
94 }
95
96 const QByteArray toPath = QFile::encodeName(fileName: to);
97 auto lastSlash = toPath.lastIndexOf(c: '/');
98 const QByteArray parentPath = toPath.left(len: lastSlash + 1);
99
100 quint64 parentId = tr->documentId(path: parentPath);
101 if (!parentId) {
102 qCDebug(BALOO) << "Parent directory not (yet) known, signaling newFile" << to;
103 Q_EMIT movedWithoutData(path: QFile::decodeName(localFileName: parentPath));
104 return;
105 }
106
107 Document doc;
108
109 const QByteArray fileName = toPath.mid(index: lastSlash + 1);
110 TermGenerator tg(doc);
111 tg.indexFileNameText(text: QFile::decodeName(localFileName: fileName));
112
113 doc.setId(id);
114 doc.setParentId(parentId);
115 doc.setUrl(toPath);
116 tr->replaceDocument(doc, operations: DocumentUrl | FileNameTerms);
117
118 // Possible scenarios
119 // 1. file moves to the same device - id is preserved
120 // 2. file moves to a different device - id is not preserved
121}
122
123#include "moc_metadatamover.cpp"
124

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