diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d7ae88e..c78ac675 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,152 +1,155 @@ # set minimum version requirements cmake_minimum_required(VERSION 3.0) set(REQUIRED_QT_VERSION 5.8.0) set(KF5_VERSION "5.45.0") # handled by release scripts set(KF5_DEP_VERSION "5.44.0") # handled by release scripts # set up project project(Baloo VERSION ${KF5_VERSION}) # set up extra-cmake-modules before trying anything else include(FeatureSummary) find_package(ECM ${KF5_DEP_VERSION} NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules" URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules" ) feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) # we found extra-cmake-modules, so use it now set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ) include(ECMSetupVersion) # set up baloo versions ecm_setup_version(PROJECT VARIABLE_PREFIX BALOO VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/baloo_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooConfigVersion.cmake" SOVERSION 5 ) # include optional and extra cmake stuff include(GenerateExportHeader) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMAddTests) include(ECMAddQch) include(ECMQtDeclareLoggingCategory) include(ECMMarkNonGuiExecutable) option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") +option(BUILD_EXPERIMENTAL "Build experimental features" OFF) +add_feature_info(EXP ${BUILD_EXPERIMENTAL} "Build experimental features") + # set up build dependencies find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Core DBus Widgets Qml Quick Test) find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS CoreAddons Config DBusAddons I18n IdleTime Solid FileMetaData Crash KIO) find_package(LMDB) set_package_properties(LMDB PROPERTIES DESCRIPTION "Lightning Memory-Mapped Database (LMDB)" URL "http://symas.com/mdb" TYPE REQUIRED ) if(${LMDB_FOUND}) include_directories(${LMDB_INCLUDE_DIRS}) endif() # compiler flags and build system add_definitions(-DQT_NO_KEYWORDS) remove_definitions(-DQT_NO_CAST_FROM_ASCII) find_package(Inotify) set_package_properties(Inotify PROPERTIES PURPOSE "Filesystem alteration notifications using inotify") set(BUILD_KINOTIFY ${Inotify_FOUND}) include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR} # we'll configure the rest here so that we don't have to # specify them in the source and test directories separately ${CMAKE_SOURCE_DIR}/src/lib ${CMAKE_BINARY_DIR}/src/lib ${CMAKE_BINARY_DIR}/src/codecs ${CMAKE_SOURCE_DIR}/src/codecs ${CMAKE_BINARY_DIR}/src/engine ${CMAKE_SOURCE_DIR}/src/engine ${CMAKE_BINARY_DIR}/src/file ${CMAKE_SOURCE_DIR}/src/file ${CMAKE_BINARY_DIR}/src/dbus ${CMAKE_SOURCE_DIR}/src/dbus ) # targets add_subdirectory(src) add_subdirectory(icons) if (BUILD_TESTING AND BUILD_KINOTIFY) add_subdirectory(tests) add_subdirectory(autotests) endif() # i18n if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() # config files set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5Baloo") if (BUILD_QCH) ecm_install_qch_export( TARGETS KF5Baloo_QCH FILE KF5BalooQchTargets.cmake DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5BalooQchTargets.cmake\")") endif() configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5BalooConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooConfig.cmake" PATH_VARS KDE_INSTALL_DBUSINTERFACEDIR INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) # install targets install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooConfigVersion.cmake" DESTINATION ${CMAKECONFIG_INSTALL_DIR} COMPONENT devel ) install(EXPORT KF5BalooTargets NAMESPACE KF5:: DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5BalooTargets.cmake) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/baloo_version.h" DESTINATION ${KF5_INCLUDE_INSTALL_DIR} COMPONENT Devel ) install(FILES baloo.categories DESTINATION ${KDE_INSTALL_CONFDIR}) # and we're done feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index 2b0f9fff..4009ae93 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -1,52 +1,55 @@ set(BALOO_ENGINE_SRCS andpostingiterator.cpp database.cpp document.cpp documentdb.cpp documentdatadb.cpp documenturldb.cpp documenttimedb.cpp documentiddb.cpp enginequery.cpp idtreedb.cpp idfilenamedb.cpp mtimedb.cpp orpostingiterator.cpp phraseanditerator.cpp positiondb.cpp postingdb.cpp postingiterator.cpp queryparser.cpp termgenerator.cpp transaction.cpp - databasesanitizer.cpp vectorpostingiterator.cpp vectorpositioninfoiterator.cpp writetransaction.cpp global.cpp fsutils.cpp ) +if(${BUILD_EXPERIMENTAL}) + set(BALOO_ENGINE_SRCS ${BALOO_ENGINE_SRCS} experimental/databasesanitizer.cpp) +endif() + add_library(KF5BalooEngine ${BALOO_ENGINE_SRCS}) add_library(KF5::BalooEngine ALIAS KF5BalooEngine) target_link_libraries(KF5BalooEngine PUBLIC Qt5::Core KF5::CoreAddons ${LMDB_LIBRARIES} PRIVATE KF5BalooCodecs KF5::I18n ) set_target_properties(KF5BalooEngine PROPERTIES VERSION ${BALOO_VERSION_STRING} SOVERSION ${BALOO_SOVERSION} EXPORT_NAME BalooEngine ) ##target_include_directories(KF5BalooEngine INTERFACE "$") generate_export_header(KF5BalooEngine BASE_NAME BALOO_ENGINE EXPORT_FILE_NAME engine_export.h) install(TARGETS KF5BalooEngine EXPORT KF5BalooTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) diff --git a/src/engine/databasesanitizer.cpp b/src/engine/experimental/databasesanitizer.cpp similarity index 100% rename from src/engine/databasesanitizer.cpp rename to src/engine/experimental/databasesanitizer.cpp diff --git a/src/engine/databasesanitizer.h b/src/engine/experimental/databasesanitizer.h similarity index 100% rename from src/engine/databasesanitizer.h rename to src/engine/experimental/databasesanitizer.h diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index db19b488..3ebc1603 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,4 +1,6 @@ add_subdirectory(baloosearch) add_subdirectory(balooshow) add_subdirectory(balooctl) -add_subdirectory(baloodb) +if(${BUILD_EXPERIMENTAL}) + add_subdirectory(experimental/baloodb) +endif() diff --git a/src/tools/baloodb/CMakeLists.txt b/src/tools/experimental/baloodb/CMakeLists.txt similarity index 100% rename from src/tools/baloodb/CMakeLists.txt rename to src/tools/experimental/baloodb/CMakeLists.txt diff --git a/src/tools/baloodb/Messages.sh b/src/tools/experimental/baloodb/Messages.sh similarity index 100% rename from src/tools/baloodb/Messages.sh rename to src/tools/experimental/baloodb/Messages.sh diff --git a/src/tools/baloodb/main.cpp b/src/tools/experimental/baloodb/main.cpp similarity index 93% rename from src/tools/baloodb/main.cpp rename to src/tools/experimental/baloodb/main.cpp index edb86fc9..fa111791 100644 --- a/src/tools/baloodb/main.cpp +++ b/src/tools/experimental/baloodb/main.cpp @@ -1,265 +1,265 @@ /* * * Copyright 2018 Michael Heidelbach * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global.h" -#include "databasesanitizer.h" +#include "experimental/databasesanitizer.h" #include #include #include #include #include #include #include #include #include using namespace Baloo; struct Command { const QString name; const QString description; const QStringList args; const QStringList options; }; const auto options = QList{ QCommandLineOption{ QStringList{QStringLiteral("i"), QStringLiteral("device-id")}, i18n("Filter by device id." "\n0 (default) does not filter and everything is printed." "\nPositive numbers are including filters printing only the mentioned device id." "\nNegative numbers are excluding filters printing everything but the mentioned device id." "\nMay be given multiple times."), i18n("integer"), 0 }, QCommandLineOption{ QStringList{QStringLiteral("D"), QStringLiteral("dry-run")}, i18n("Print results of a prune operation, but do not change anything." "\nOnly applies to \"%1\" command", QStringLiteral("prune")) }, QCommandLineOption{ - QStringList{QStringLiteral("m"), QStringLiteral("missing-only")}, + QStringList{QStringLiteral("m"), QStringLiteral("missing-only")}, i18n("List only inaccessible entries.\nOnly applies to \"%1\"", QStringLiteral("list")) } }; const auto commands = std::vector{ Command{ - QStringLiteral("list"), + QStringLiteral("list"), i18n("List database contents. Use a regular expression as argument to filter output"), QStringList{ QStringLiteral("pattern") }, QStringList{ QStringLiteral("missing-only"), QStringLiteral("device-id") } }, /*TODO: Command{ - QStringLiteral("check"), + QStringLiteral("check"), i18n("Check database contents. " "Beware this may take very long to execute"), QStringList{}, QStringList{} }, */ /*TODO: Command{ - QStringLiteral("prune"), + QStringLiteral("prune"), i18n("Remove stale database entries"), QStringList{ QStringLiteral("pattern") }, QStringList{ QStringLiteral("dry-run"), QStringLiteral("device-id") } }, */ Command{ - QStringLiteral("devices"), + QStringLiteral("devices"), i18n("List devices"), QStringList{}, QStringList{QStringLiteral("missing-only")} } }; const QStringList allowedCommands() { QStringList names; for (const auto& c : commands) { names.append(c.name); } return names; } -const QStringList getOptions(const QString& name) +const QStringList getOptions(const QString& name) { for (const auto& c : commands) { if (c.name == name) { return c.options; } } return QStringList(); } -QString createDescription() +QString createDescription() { QStringList allowedcommands; for (const auto& c: commands) { auto options = getOptions(c.name); const QString optionStr = options.isEmpty() ? QString() : QStringLiteral(" [--%1]").arg(options.join(QLatin1Literal("] [--"))); - + QString argumentStr; if (!c.args.isEmpty() ) { argumentStr = QStringLiteral(" [%1]").arg(c.args.join(QStringLiteral("] ["))); } const QString commandStr = QStringLiteral("%1%2%3") .arg(c.name) .arg(optionStr) .arg(argumentStr); - + const QString str = QStringLiteral("%1 %2") .arg(commandStr, -48) .arg(c.description); - + allowedcommands.append(str); } const QString allCommandsStr = allowedcommands.join(QStringLiteral("\n ")); return i18n("\n\nCommands:\n %1", allCommandsStr); } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); KAboutData aboutData(QStringLiteral("baloodb"), i18n("Baloo Database Sanitizer"), PROJECT_VERSION, i18n("The Baloo Database Lister & Sanitizer"), KAboutLicense::GPL, i18n("(c) 2018, Michael Heidelbach")); aboutData.addAuthor(i18n("Michael Heidelbach"), i18n("Maintainer"), QStringLiteral("ottwolt@gmail.com")); KAboutData::setApplicationData(aboutData); - + QCommandLineParser parser; parser.addOptions(options); - parser.addPositionalArgument(QStringLiteral("command"), - i18n("The command to execute"), + parser.addPositionalArgument(QStringLiteral("command"), + i18n("The command to execute"), allowedCommands().join(QStringLiteral("|")) ); - parser.addPositionalArgument(QStringLiteral("pattern"), + parser.addPositionalArgument(QStringLiteral("pattern"), i18nc("Command", "A regular expression applied to the URL of database items" "\nExample: %1" , "baloodb list '^/media/videos/series'" ) ); const QString warnExperiment = QStringLiteral( - "===\nPlease note: This is an experimental tool. Command line switches or their meaning may change.\n==="); - + "===\nPlease note: This is an experimental tool. Command line switches or their meaning may change.\n==="); + parser.setApplicationDescription(warnExperiment + createDescription()); parser.addVersionOption(); parser.addHelpOption(); parser.process(app); if (parser.positionalArguments().isEmpty()) { qDebug() << "No command"; parser.showHelp(1); } - + auto args = parser.positionalArguments(); auto command = args.at(0); args.removeFirst(); - + if(!allowedCommands().contains(command)) { qDebug() << "Unknown command" << command; parser.showHelp(1); } - + const auto optNames = parser.optionNames(); const auto allowedOptions = getOptions(command); - + QVector deviceIds; for (const auto& dev : parser.values(QStringLiteral("device-id"))) { deviceIds.append(dev.toInt()); } const bool missingOnly = parser.isSet(QStringLiteral("missing-only")); const QString pattern = args.isEmpty() ? QString() : args.at(0); - const QSharedPointer urlFilter(pattern.isEmpty() - ? nullptr + const QSharedPointer urlFilter(pattern.isEmpty() + ? nullptr : new QRegularExpression{pattern}); auto db = globalDatabaseInstance(); QTextStream err(stderr); QElapsedTimer timer; timer.start(); if (command == QStringLiteral("list")) { if (!db->open(Database::ReadOnlyDatabase)) { err << i18n("Baloo Index could not be opened") << endl; return 1; } DatabaseSanitizer san(db, Transaction::ReadOnly); err << i18n("Listing database contents...") << endl; san.printList(deviceIds, missingOnly, urlFilter); } else if (command == QStringLiteral("devices")) { if (!db->open(Database::ReadOnlyDatabase)) { err << i18n("Baloo Index could not be opened") << endl; return 1; } DatabaseSanitizer san(db, Transaction::ReadOnly); err << i18n("Listing database contents...") << endl; san.printDevices(deviceIds); - + } else if (command == QStringLiteral("clean")) { /* TODO: add prune command */ parser.showHelp(1); - + } else if (command == QStringLiteral("check")) { parser.showHelp(1); /* TODO: After check methods are improved Database *db = globalDatabaseInstance(); if (!db->open(Database::ReadOnlyDatabase)) { err << i18n("Baloo Index could not be opened") << endl; return 1; } Transaction tr(db, Transaction::ReadOnly); err << i18n("Checking file paths ... ") << endl; tr.checkFsTree(); err << i18n("Checking postings ... ") << endl; tr.checkTermsDbinPostingDb(); err << i18n("Checking terms ... ") << endl; tr.checkPostingDbinTermsDb(); */ } err << i18n("Elapsed: %1 secs", timer.nsecsElapsed() / 1000000000.0) << endl; return 0; }