From 2a1ee328cc48215744e90834337468818d1a7924 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 | 107 ++++++++++++++++++++++++++++++++++++++++++ cli/commanddelete.h | 13 +++++ cli/commandupdate.cpp | 8 ++++ cli/commandupdate.h | 14 ++++++ cli/main.cpp | 3 +- 9 files changed, 167 insertions(+), 4 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 7e69df3..b4c11b2 100644 --- a/cli/command.cpp +++ b/cli/command.cpp @@ -19,6 +19,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 ffa1ae5..488d77c 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 238bf0d..3e2d0d9 100644 --- a/cli/commandadd.cpp +++ b/cli/commandadd.cpp @@ -199,7 +199,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..141d36d --- /dev/null +++ b/cli/commanddelete.cpp @@ -0,0 +1,107 @@ +#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..61eadde --- /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..de7aa18 --- /dev/null +++ b/cli/commandupdate.cpp @@ -0,0 +1,8 @@ +#include "commandupdate.h" + + + +int CommandUpdate::handle(QStringList arguments) +{ + +} diff --git a/cli/commandupdate.h b/cli/commandupdate.h new file mode 100644 index 0000000..bfd09e6 --- /dev/null +++ b/cli/commandupdate.h @@ -0,0 +1,14 @@ +#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 09c5da0..a9ad999 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,7 +31,7 @@ Command *commandFromName(QString name, QString connectionstring) } if(name == "delete") { - + return new CommandDelete(connectionstring); } if(name == "update") {