From db499fb4b302c6f53b1969e39d7758ab0761b100 Mon Sep 17 00:00:00 2001 From: Albert S Date: Sun, 7 Apr 2019 20:22:20 +0200 Subject: [PATCH] Begin delete command implementation --- cli/cli.pro | 8 +++- cli/command.cpp | 15 +++++++ cli/command.h | 1 + cli/commandadd.cpp | 2 +- cli/commanddelete.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++ cli/commanddelete.h | 13 ++++++ cli/commandupdate.cpp | 5 +++ cli/commandupdate.h | 13 ++++++ cli/main.cpp | 2 + 9 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 cli/commanddelete.cpp create mode 100644 cli/commanddelete.h create mode 100644 cli/commandupdate.cpp create mode 100644 cli/commandupdate.h diff --git a/cli/cli.pro b/cli/cli.pro index 04732bd..b738feb 100644 --- a/cli/cli.pro +++ b/cli/cli.pro @@ -27,7 +27,9 @@ SOURCES += \ odtprocessor.cpp \ utils.cpp \ odsprocessor.cpp \ - qssgeneralexception.cpp + qssgeneralexception.cpp \ + commanddelete.cpp \ + commandupdate.cpp HEADERS += \ encodingdetector.h \ @@ -42,5 +44,7 @@ HEADERS += \ odtprocessor.h \ utils.h \ odsprocessor.h \ - qssgeneralexception.h + qssgeneralexception.h \ + commanddelete.h \ + commandupdate.h INCLUDEPATH += /usr/include/poppler/qt5/ /usr/include/quazip5 diff --git a/cli/command.cpp b/cli/command.cpp index 9992995..733bb21 100644 --- a/cli/command.cpp +++ b/cli/command.cpp @@ -20,6 +20,21 @@ bool Command::fileExistsInDatabase(QSqlDatabase &db, QString path, qint64 mtime) return query.value(0).toBool(); } +bool Command::fileExistsInDatabase(QSqlDatabase &db, QString path) +{ + auto query = QSqlQuery("SELECT 1 FROM file WHERE path = ?", db); + query.addBindValue(path); + if(!query.exec()) + { + throw QSSGeneralException("Error while trying to query for file existance"); + } + if(!query.next()) + { + return false; + } + return query.value(0).toBool(); +} + QSqlDatabase Command::dbConnection() { if(dbStore.hasLocalData()) diff --git a/cli/command.h b/cli/command.h index f3ae949..e2f547e 100644 --- a/cli/command.h +++ b/cli/command.h @@ -8,6 +8,7 @@ class Command { protected: + bool fileExistsInDatabase(QSqlDatabase &db, QString path); bool fileExistsInDatabase(QSqlDatabase &db, QString path, qint64 mtime); QByteArray readFile(QString path) const; QString dbConnectionString; diff --git a/cli/commandadd.cpp b/cli/commandadd.cpp index 92397d4..ea1f722 100644 --- a/cli/commandadd.cpp +++ b/cli/commandadd.cpp @@ -183,7 +183,7 @@ int CommandAdd::handle(QStringList arguments) { if(result == SKIPPED) { - qDebug() << "SKIPPED" << path << "as it already exists in the database"; + qDebug() << "Skipped" << path << "as it already exists in the database"; } else { diff --git a/cli/commanddelete.cpp b/cli/commanddelete.cpp new file mode 100644 index 0000000..efa1cf0 --- /dev/null +++ b/cli/commanddelete.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include "commanddelete.h" + +int CommandDelete::handle(QStringList arguments) +{ + QCommandLineParser parser; + parser.addOptions({{{"v", "verbose"}, "Print path of the files while deleting them"}, + {"pattern", "Only delete files from index matching the pattern, e. g. */.git/*", "pattern"}, + {"deleted", "Delete all files from the index that don't exist anymore"}}); + + parser.addHelpOption(); + parser.addPositionalArgument("delete", "Delete paths from the index", "delete [paths...]"); + + parser.process(arguments); + bool removeNonExistant = parser.isSet("deleted"); + bool verbose = parser.isSet("verbose"); + QString pattern = parser.value("pattern"); + + // TODO: port this to QRegularExpression once >5.12 gets more widespread because of this bug + // https://bugreports.qt.io/browse/QTBUG-72539?focusedCommentId=439053&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel + + // QRegularExpression regexPattern = QRegularExpression::wildcardToRegularExpression(pattern); + + bool usePattern = !pattern.isEmpty(); + QRegExp regexPattern(pattern); + regexPattern.setPatternSyntax(QRegExp::PatternSyntax::WildcardUnix); + + QSqlDatabase db = dbConnection(); + + if(removeNonExistant) + { + // TODO: try to translate pattern to SQL WHERE + QSqlQuery pathsQuery("SELECT path FROM file", db); + if(!pathsQuery.exec()) + { + qDebug() << "Failed to query current paths"; + return 1; + } + + while(pathsQuery.next()) + { + QString path = pathsQuery.value(0).toString(); + if(usePattern && regexPattern.exactMatch(path)) + { + QFile file(path); + if(!file.exists()) + { + QSqlQuery query("DELETE FROM file WHERE path = ?", db); + query.addBindValue(path); + if(!query.exec()) + { + qDebug() << "Failed to delete " << path << query.lastError(); + return 1; + } + if(verbose) + { + qInfo() << "Deleted " << path; + } + } + } + } + } + + QStringList files = parser.positionalArguments(); + for(QString &file : files) + { + QFileInfo fileInfo(file); + QString absPath = fileInfo.absoluteFilePath(); + if(fileExistsInDatabase(db, absPath)) + { + QSqlQuery deletionQuery("DELETE FROM file WHERE path = ?", db); + deletionQuery.addBindValue(absPath); + if(deletionQuery.exec()) + { + if(verbose) + { + qInfo() << "Deleted" << absPath; + } + } + else + { + qDebug() << "Failed to delete:" << absPath << deletionQuery.lastError(); + } + } + else + { + qInfo() << "No such file in database:" << absPath; + } + } + return 0; +} diff --git a/cli/commanddelete.h b/cli/commanddelete.h new file mode 100644 index 0000000..7e5e57a --- /dev/null +++ b/cli/commanddelete.h @@ -0,0 +1,13 @@ +#ifndef COMMANDDELETE_H +#define COMMANDDELETE_H +#include "command.h" + +class CommandDelete : public Command +{ + public: + using Command::Command; + + int handle(QStringList arguments) override; +}; + +#endif // COMMANDDELETE_H diff --git a/cli/commandupdate.cpp b/cli/commandupdate.cpp new file mode 100644 index 0000000..910fb46 --- /dev/null +++ b/cli/commandupdate.cpp @@ -0,0 +1,5 @@ +#include "commandupdate.h" + +int CommandUpdate::handle(QStringList arguments) +{ +} diff --git a/cli/commandupdate.h b/cli/commandupdate.h new file mode 100644 index 0000000..b6231bd --- /dev/null +++ b/cli/commandupdate.h @@ -0,0 +1,13 @@ +#ifndef COMMANDUPDATE_H +#define COMMANDUPDATE_H +#include "command.h" + +class CommandUpdate : public Command +{ + public: + CommandUpdate(); + + int handle(QStringList arguments) override; +}; + +#endif // COMMANDUPDATE_H diff --git a/cli/main.cpp b/cli/main.cpp index 5a9138d..cddc38f 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -17,6 +17,7 @@ #include "defaulttextprocessor.h" #include "command.h" #include "commandadd.h" +#include "commanddelete.h" void printUsage(QString argv0) { qInfo() << "Usage: " << argv0 << "command"; @@ -30,6 +31,7 @@ Command *commandFromName(QString name, QString connectionstring) } if(name == "delete") { + return new CommandDelete(connectionstring); } if(name == "update") {