From a6f73d724abc60995144947ad790018eb0efb7d7 Mon Sep 17 00:00:00 2001 From: Albert S Date: Sun, 30 Aug 2020 18:12:42 +0200 Subject: [PATCH] CommandDelete: Rework deletion logic Allow deleting files from index which still exist on the fileystem without passing their path to "qss delete". Thus: "qss delete --deleted" deletes all files which don't exist anymore. Also, fix some bugs in offset calculation. --- cli/commanddelete.cpp | 162 +++++++++++++++++++++++------------------- cli/commanddelete.h | 8 +-- 2 files changed, 94 insertions(+), 76 deletions(-) diff --git a/cli/commanddelete.cpp b/cli/commanddelete.cpp index 8431e4c..581bf79 100644 --- a/cli/commanddelete.cpp +++ b/cli/commanddelete.cpp @@ -7,47 +7,63 @@ #include "commanddelete.h" #include "logger.h" -int CommandDelete::removeNonExistent(bool verbose, bool dryRun, QString pattern) +int CommandDelete::remove(QString pattern, bool onlyDeleted, bool verbose, bool dryRun) { - int offset = 0; - int limit = 1000; - QVector files; - int processedRows = this->dbService->getFiles(files, pattern, 0, limit); - while(processedRows > 0 ) - { - for(FileData &file : files) - { - QFileInfo fileInfo(file.absPath); - if(!fileInfo.exists()) - { - if(!dryRun) - { - if(this->dbService->deleteFile(file.absPath)) - { - if(verbose) - { - Logger::info() << "Deleted" << file.absPath << endl; - } - } - else - { - Logger::error()<< "Failed to delete:" << file.absPath << ", exiting." << endl - ; - return 1; - } - } - else - { - Logger::info() << "Would delete " << file.absPath << endl; - } - } - } + int deleted = 0; + int offset = 0; + int limit = 1000; + QVector files; + int processedRows = this->dbService->getFiles(files, pattern, 0, limit); + while(processedRows > 0 ) + { + for(FileData &file : files) + { + if(onlyDeleted && QFileInfo::exists(file.absPath)) + { + if(verbose) + { + Logger::info() << "Skipping " << file.absPath << " as the file exists on the file system" << endl; + } + } + else + { + if(!dryRun) + { + if(this->dbService->deleteFile(file.absPath)) + { + if(verbose) + { + Logger::info() << "Deleted" << file.absPath << endl; + } + ++deleted; + } + else + { + Logger::error()<< "Failed to delete:" << file.absPath << ", exiting." << endl; + return 1; + } + } + else + { + Logger::info() << "Would delete " << file.absPath << endl; + } + } + } + if(dryRun) + { + offset += limit; + } + else + { + offset = offset + limit - deleted; + } + files.clear(); + processedRows = this->dbService->getFiles(files, pattern, offset, limit); + deleted = 0; + } + return 0; +} - offset += limit; - processedRows = this->dbService->getFiles(files, pattern, offset, limit); - } - return 0; - } int CommandDelete::removePaths(const QStringList &paths, bool verbose, bool dryRun) { @@ -86,42 +102,44 @@ int CommandDelete::removePaths(const QStringList &paths, bool verbose, bool dryR int CommandDelete::handle(QStringList arguments) { - QCommandLineParser parser; - parser.addOptions({ - { { "v", "verbose" }, "Print path of the files while deleting them" }, - { { "n", "dry-run"}, "Only print which files would be deleted from the database, don't delete them"}, - { "pattern", "Only delete files from index matching the pattern, e. g. */.git/*. Only applies to --deleted or standalone.", "pattern" }, - { "deleted", "Delete all files from the index that don't exist anymore" } - }); + QCommandLineParser parser; + parser.addOptions({ + { { "v", "verbose" }, "Print path of the files while deleting them" }, + { { "n", "dry-run"}, "Only print which files would be deleted from the database, don't delete them"}, + { "pattern", "Only delete files from index matching the pattern, e. g. */.git/*. Can be used to restrict --deleted or standalone.", "pattern" }, + { "deleted", "Delete all files from the index that don't exist anymore. Can be restricted by --pattern." } + }); - parser.addHelpOption(); - parser.addPositionalArgument("delete", "Delete paths from the index", "delete [paths...]"); + parser.addHelpOption(); + parser.addPositionalArgument("delete", "Delete paths from the index", "delete [paths...]"); - parser.process(arguments); - bool verbose = parser.isSet("verbose"); - bool dryRun = parser.isSet("dry-run"); - QString pattern = parser.value("pattern"); - if(parser.isSet("deleted")) - { + parser.process(arguments); + bool verbose = parser.isSet("verbose"); + bool dryRun = parser.isSet("dry-run"); + bool deleted = parser.isSet("deleted"); + QString pattern = parser.value("pattern"); - int result = removeNonExistent(verbose, dryRun, pattern); - if(result != 0) - { - return result; - } - } - QStringList files = parser.positionalArguments(); - if(files.length() > 0) - { - int result = removePaths(files, verbose, dryRun); - if(result != 0) - { - return result; - } - } + if(deleted || ! pattern.isEmpty()) + { + int result = this->remove(pattern, deleted, verbose, dryRun); + if(result != 0) + { + Logger::error() << "Removal operation did not succeed" << endl; + return result; + } + } - return 0; + + QStringList files = parser.positionalArguments(); + if(files.length() > 0) + { + int result = removePaths(files, verbose, dryRun); + if(result != 0) + { + return result; + } + } + + return 0; } - - diff --git a/cli/commanddelete.h b/cli/commanddelete.h index e9497bb..7f745de 100644 --- a/cli/commanddelete.h +++ b/cli/commanddelete.h @@ -5,12 +5,12 @@ class CommandDelete : public Command { public: - using Command::Command; + using Command::Command; - int handle(QStringList arguments) override; + int handle(QStringList arguments) override; private: - int removeNonExistent(bool verbose, bool dryRun, QString pattern); - int removePaths(const QStringList &paths, bool verbose, bool dryRun); + int remove(QString pattern, bool onlyDeleted, bool verbose, bool dryRun); + int removePaths(const QStringList &paths, bool verbose, bool dryRun); }; #endif // COMMANDDELETE_H