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 auto to = _to;
80 if (to.endsWith(c: QLatin1Char('/'))) {
81 to.chop(n: 1);
82 }
83
84 // directory case
85 auto normalizedFrom = from;
86 if (normalizedFrom.endsWith(c: QLatin1Char('/'))) {
87 normalizedFrom.chop(n: 1);
88 }
89
90 const QByteArray fromPath = QFile::encodeName(fileName: normalizedFrom);
91 quint64 id = tr->documentId(path: fromPath);
92 if (!id) {
93 qCDebug(BALOO) << "Document not (yet) known, signaling newFile" << to;
94 Q_EMIT movedWithoutData(path: to);
95 return;
96 }
97
98 const QByteArray toPath = QFile::encodeName(fileName: to);
99 auto lastSlash = toPath.lastIndexOf(ch: '/');
100 const QByteArray parentPath = toPath.left(n: lastSlash + 1);
101
102 quint64 parentId = tr->documentId(path: parentPath);
103 if (!parentId) {
104 qCDebug(BALOO) << "Parent directory not (yet) known, signaling newFile" << to;
105 Q_EMIT movedWithoutData(path: QFile::decodeName(localFileName: parentPath));
106 return;
107 }
108
109 Document doc;
110
111 const QByteArray fileName = toPath.mid(index: lastSlash + 1);
112 TermGenerator tg(doc);
113 tg.indexFileNameText(text: QFile::decodeName(localFileName: fileName));
114
115 doc.setId(id);
116 doc.setParentId(parentId);
117 doc.setUrl(toPath);
118 tr->replaceDocument(doc, operations: DocumentUrl | FileNameTerms);
119
120 // Possible scenarios
121 // 1. file moves to the same device - id is preserved
122 // 2. file moves to a different device - id is not preserved
123}
124
125#include "moc_metadatamover.cpp"
126

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