diff --git a/autotests/unit/file/metadatamovertest.cpp b/autotests/unit/file/metadatamovertest.cpp --- a/autotests/unit/file/metadatamovertest.cpp +++ b/autotests/unit/file/metadatamovertest.cpp @@ -31,6 +31,7 @@ #include #include #include +#include using namespace Baloo; @@ -57,6 +58,31 @@ QTemporaryDir* m_tempDir; }; +class MetadataMoverTestDBusSpy : public QObject +{ + Q_OBJECT +public: + + MetadataMoverTestDBusSpy(QObject* parent = nullptr); + +Q_SIGNALS: + + void fileMetaDataChanged(QStringList fileList); + + void fileRemoved(QStringList fileList); + + void fileMoved(QStringList fileList, QString oldPath, QString newPath); + +public Q_SLOTS: + + void slotFileMetaDataChanged(QStringList fileList); + + void slotFileRemoved(QStringList fileList); + + void slotFileMoved(QStringList fileList, QString oldPath, QString newPath); + +}; + MetadataMoverTest::MetadataMoverTest(QObject* parent) : QObject(parent) , m_db(nullptr) @@ -93,6 +119,11 @@ void MetadataMoverTest::testRemoveFile() { + MetadataMoverTestDBusSpy dbusSignalSpy; + QSignalSpy fileMovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMoved); + QSignalSpy fileRemovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileRemoved); + QSignalSpy fileChangedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMetaDataChanged); + QTemporaryFile file; file.open(); QString url = file.fileName(); @@ -103,10 +134,26 @@ QVERIFY(tr.hasDocument(fid)); } + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 0); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + MetadataMover mover(m_db, this); file.remove(); mover.removeFileMetadata(url); + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 0); + QCOMPARE(fileRemovedSpy.count(), 1); + QCOMPARE(fileChangedSpy.count(), 0); + { Transaction tr(m_db, Transaction::ReadOnly); QVERIFY(!tr.hasDocument(fid)); @@ -128,6 +175,11 @@ void MetadataMoverTest::testRenameFile() { + MetadataMoverTestDBusSpy dbusSignalSpy; + QSignalSpy fileMovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMoved); + QSignalSpy fileRemovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileRemoved); + QSignalSpy fileChangedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMetaDataChanged); + QTemporaryDir dir; QString url = dir.path() + "/file"; @@ -139,11 +191,27 @@ QVERIFY(tr.hasDocument(fid)); } + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 0); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + MetadataMover mover(m_db, this); QString url2 = dir.path() + "/file2"; QFile::rename(url, url2); mover.moveFileMetadata(QFile::encodeName(url), QFile::encodeName(url2)); + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 1); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + { Transaction tr(m_db, Transaction::ReadOnly); QVERIFY(tr.hasDocument(fid)); @@ -153,6 +221,11 @@ void MetadataMoverTest::testMoveFile() { + MetadataMoverTestDBusSpy dbusSignalSpy; + QSignalSpy fileMovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMoved); + QSignalSpy fileRemovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileRemoved); + QSignalSpy fileChangedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMetaDataChanged); + QTemporaryDir dir; QDir().mkpath(dir.path() + "/a/b/c"); @@ -165,11 +238,27 @@ QVERIFY(tr.hasDocument(fid)); } + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 0); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + MetadataMover mover(m_db, this); QString url2 = dir.path() + "/file2"; QFile::rename(url, url2); mover.moveFileMetadata(QFile::encodeName(url), QFile::encodeName(url2)); + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 1); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + { Transaction tr(m_db, Transaction::ReadOnly); QVERIFY(tr.hasDocument(fid)); @@ -179,6 +268,11 @@ void MetadataMoverTest::testMoveFolder() { + MetadataMoverTestDBusSpy dbusSignalSpy; + QSignalSpy fileMovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMoved); + QSignalSpy fileRemovedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileRemoved); + QSignalSpy fileChangedSpy(&dbusSignalSpy, &MetadataMoverTestDBusSpy::fileMetaDataChanged); + QTemporaryDir dir; QString folder = dir.path() + "/folder"; @@ -195,11 +289,27 @@ QVERIFY(tr.hasDocument(fid)); } + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 0); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + QString newFolderUrl = dir.path() + "/dir"; QFile::rename(folder, newFolderUrl); MetadataMover mover(m_db, this); mover.moveFileMetadata(QFile::encodeName(folder), QFile::encodeName(newFolderUrl)); + fileMovedSpy.wait(100); + fileRemovedSpy.wait(100); + fileChangedSpy.wait(100); + + QCOMPARE(fileMovedSpy.count(), 1); + QCOMPARE(fileRemovedSpy.count(), 0); + QCOMPARE(fileChangedSpy.count(), 0); + { Transaction tr(m_db, Transaction::ReadOnly); QVERIFY(tr.hasDocument(did)); @@ -209,6 +319,37 @@ } } + + +MetadataMoverTestDBusSpy::MetadataMoverTestDBusSpy(QObject *parent) : QObject(parent) +{ + QDBusConnection con = QDBusConnection::sessionBus(); + + con.connect(QString(), QStringLiteral("/files"), QStringLiteral("org.kde"), + QStringLiteral("changed"), this, SLOT(slotFileMetaDataChanged(QStringList))); + + con.connect(QString(), QStringLiteral("/files"), QStringLiteral("org.kde"), + QStringLiteral("removed"), this, SLOT(slotFileRemoved(QStringList))); + + con.connect(QString(), QStringLiteral("/files"), QStringLiteral("org.kde"), + QStringLiteral("moved"), this, SLOT(slotFileMoved(QStringList, QString, QString))); +} + +void MetadataMoverTestDBusSpy::slotFileMetaDataChanged(QStringList fileList) +{ + Q_EMIT fileMetaDataChanged(fileList); +} + +void MetadataMoverTestDBusSpy::slotFileRemoved(QStringList fileList) +{ + Q_EMIT fileRemoved(fileList); +} + +void MetadataMoverTestDBusSpy::slotFileMoved(QStringList fileList, QString oldPath, QString newPath) +{ + Q_EMIT fileMoved(fileList, oldPath, newPath); +} + QTEST_GUILESS_MAIN(MetadataMoverTest) #include "metadatamovertest.moc" diff --git a/src/engine/transaction.h b/src/engine/transaction.h --- a/src/engine/transaction.h +++ b/src/engine/transaction.h @@ -63,6 +63,7 @@ * \p path into an id. */ quint64 documentId(const QByteArray& path) const; + QVector childrenDocumentId(quint64 parentId) const; QByteArray documentData(quint64 id) const; DocumentTimeDB::TimeInfo documentTimeInfo(quint64 id) const; diff --git a/src/engine/transaction.cpp b/src/engine/transaction.cpp --- a/src/engine/transaction.cpp +++ b/src/engine/transaction.cpp @@ -127,6 +127,13 @@ return parentId; } +QVector Transaction::childrenDocumentId(quint64 parentId) const +{ + DocumentUrlDB docUrlDB(m_dbis.idTreeDbi, m_dbis.idFilenameDbi, m_txn); + + return docUrlDB.getChildren(parentId); +} + DocumentTimeDB::TimeInfo Transaction::documentTimeInfo(quint64 id) const { Q_ASSERT(m_txn); diff --git a/src/file/metadatamover.cpp b/src/file/metadatamover.cpp --- a/src/file/metadatamover.cpp +++ b/src/file/metadatamover.cpp @@ -25,6 +25,8 @@ #include "baloodebug.h" #include +#include +#include using namespace Baloo; @@ -40,22 +42,46 @@ } +static void buildRecursiveList(quint64 parentId, QList &fileList, Transaction &tr) +{ + const auto childrenIds = tr.childrenDocumentId(parentId); + + for (const auto oneChildren : childrenIds) { + fileList.push_back(QFile::decodeName(tr.documentUrl(oneChildren))); + buildRecursiveList(oneChildren, fileList, tr); + } +} + void MetadataMover::moveFileMetadata(const QString& from, const QString& to) { // qCDebug(BALOO) << from << to; Q_ASSERT(!from.isEmpty() && from != QLatin1String("/")); Q_ASSERT(!to.isEmpty() && to != QLatin1String("/")); Transaction tr(m_db, Transaction::ReadWrite); + quint64 id = tr.documentId(QFile::encodeName(from)); + QList fileList; + if (id) { + buildRecursiveList(id, fileList, tr); + } + // We do NOT get deleted messages for overwritten files! Thus, we // have to remove all metadata for overwritten files first. removeMetadata(&tr, to); // and finally update the old statements updateMetadata(&tr, from, to); tr.commit(); + + QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/files"), + QStringLiteral("org.kde"), + QStringLiteral("moved")); + + message.setArguments({{fileList}, from, to}); + + QDBusConnection::sessionBus().send(message); } void MetadataMover::removeFileMetadata(const QString& file) @@ -77,13 +103,24 @@ return; } + QList fileList; + buildRecursiveList(id, fileList, *tr); + bool isDir = url.endsWith('/'); if (!isDir) { tr->removeDocument(id); } else { tr->removeRecursively(id); } + QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/files"), + QStringLiteral("org.kde"), + QStringLiteral("removed")); + + message.setArguments({{fileList}}); + + QDBusConnection::sessionBus().send(message); + Q_EMIT fileRemoved(url); }