diff --git a/src/engine/database.h b/src/engine/database.h --- a/src/engine/database.h +++ b/src/engine/database.h @@ -86,6 +86,14 @@ */ QString path() const; + /** + * Copy the database to specified path + * @param destination Copy destination + * @param omitFreePages Use MDB_CP_COMPACT to omit free pages + * + * @return true if copy was successful + */ + bool copy(const QString& destination, bool omitFreePages) const; private: /** * serialize access, as open might be called from multiple threads diff --git a/src/engine/database.cpp b/src/engine/database.cpp --- a/src/engine/database.cpp +++ b/src/engine/database.cpp @@ -235,3 +235,11 @@ QMutexLocker locker(&m_mutex); return m_path; } + +bool Database::copy(const QString& destination, bool omitFreePages) const +{ + // Copying + int rc = mdb_env_copy2(m_env, destination.toLocal8Bit().data(), omitFreePages ? MDB_CP_COMPACT : 0); + Q_ASSERT_X(rc == 0, "Database::copy", mdb_strerror(rc)); + return rc == 0; +} diff --git a/src/tools/balooctl/main.cpp b/src/tools/balooctl/main.cpp --- a/src/tools/balooctl/main.cpp +++ b/src/tools/balooctl/main.cpp @@ -88,6 +88,7 @@ parser.addPositionalArgument(QStringLiteral("config"), i18n("Modify the Baloo configuration")); parser.addPositionalArgument(QStringLiteral("monitor"), i18n("Monitor the file indexer")); parser.addPositionalArgument(QStringLiteral("indexSize"), i18n("Display the disk space used by index")); + parser.addPositionalArgument(QStringLiteral("copy"), i18n("Copy the database omitting free pages")); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("format"), i18n("Output format <%1|%2|%3>.\nOnly applies to \"%4\"", QStringLiteral("json"), @@ -322,6 +323,38 @@ return mon.exec(parser); } + if (command == QStringLiteral("copy")) { + QString destination; + if (parser.positionalArguments().size() == 1) { + QTemporaryDir dir; + dir.setAutoRemove(false); + if (!dir.isValid()) { + out << "Unable to create temporary directory" << endl; + return 1; + } + destination = dir.path() + QStringLiteral("/index"); + } else { + destination = parser.positionalArguments().at(1); + } + if (QFile::exists(destination)) { + out << "File already exists" << endl; + return 1; + } + Database* db = globalDatabaseInstance(); + if (!db->open(Database::ReadOnlyDatabase)) { + out << "Baloo Index could not be opened" << endl; + return 1; + } + if (!db->copy(destination, true)) { + out << "Copy failed" << endl; + return 1; + } + out << "Index successfully copied to " << destination << endl + << "To restore the copy, overwrite the file " << db->path() << "/index" << endl + << "Make sure Baloo isn't running when doing so" << endl; + return 0; + } + /* TODO: Make separate executable if (command == QStringLiteral("checkDb")) {