Begin 'shared' project to share code between cli and gui
This commit is contained in:
parent
f160c72d2f
commit
6b94b8f619
21
cli/cli.pro
21
cli/cli.pro
@ -32,7 +32,8 @@ SOURCES += \
|
|||||||
filesaver.cpp \
|
filesaver.cpp \
|
||||||
databasefactory.cpp \
|
databasefactory.cpp \
|
||||||
sqlitedbservice.cpp \
|
sqlitedbservice.cpp \
|
||||||
logger.cpp
|
logger.cpp \
|
||||||
|
commandsearch.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
encodingdetector.h \
|
encodingdetector.h \
|
||||||
@ -54,5 +55,21 @@ HEADERS += \
|
|||||||
filedata.h \
|
filedata.h \
|
||||||
databasefactory.h \
|
databasefactory.h \
|
||||||
sqlitedbservice.h \
|
sqlitedbservice.h \
|
||||||
logger.h
|
logger.h \
|
||||||
|
commandsearch.h
|
||||||
INCLUDEPATH += /usr/include/poppler/qt5/ /usr/include/quazip5
|
INCLUDEPATH += /usr/include/poppler/qt5/ /usr/include/quazip5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../shared/release/ -lshared
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../shared/debug/ -lshared
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../shared/ -lshared
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../shared
|
||||||
|
DEPENDPATH += $$PWD/../shared
|
||||||
|
|
||||||
|
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/release/libshared.a
|
||||||
|
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/debug/libshared.a
|
||||||
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/release/shared.lib
|
||||||
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/debug/shared.lib
|
||||||
|
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../shared/libshared.a
|
||||||
|
1
cli/commandsearch.cpp
Normal file
1
cli/commandsearch.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "commandsearch.h"
|
20
cli/commandsearch.h
Normal file
20
cli/commandsearch.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef COMMANDSEARCH_H
|
||||||
|
#define COMMANDSEARCH_H
|
||||||
|
#include "command.h"
|
||||||
|
#include "../shared/sqlitesearch.h"
|
||||||
|
|
||||||
|
class CommandSearch : public Command
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SqliteSearch searcher;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Command::Command;
|
||||||
|
|
||||||
|
int handle(QStringList arguments) override
|
||||||
|
{
|
||||||
|
return 23;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMMANDSEARCH_H
|
@ -20,6 +20,7 @@
|
|||||||
#include "commandadd.h"
|
#include "commandadd.h"
|
||||||
#include "commanddelete.h"
|
#include "commanddelete.h"
|
||||||
#include "commandupdate.h"
|
#include "commandupdate.h"
|
||||||
|
#include "commandsearch.h"
|
||||||
#include "databasefactory.h"
|
#include "databasefactory.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
void printUsage(QString argv0)
|
void printUsage(QString argv0)
|
||||||
@ -43,7 +44,9 @@ Command *commandFromName(QString name, SqliteDbService &dbService)
|
|||||||
}
|
}
|
||||||
if(name == "search")
|
if(name == "search")
|
||||||
{
|
{
|
||||||
|
return new CommandSearch(dbService);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
gui/gui.pro
13
gui/gui.pro
@ -22,7 +22,6 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
@ -47,3 +46,15 @@ INCLUDEPATH += /usr/include/poppler/qt5/
|
|||||||
LIBS += -lpoppler-qt5
|
LIBS += -lpoppler-qt5
|
||||||
QT += widgets sql
|
QT += widgets sql
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../shared/release/ -lshared
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../shared/debug/ -lshared
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../shared/ -lshared
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../shared
|
||||||
|
DEPENDPATH += $$PWD/../shared
|
||||||
|
|
||||||
|
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/release/libshared.a
|
||||||
|
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/debug/libshared.a
|
||||||
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/release/shared.lib
|
||||||
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/debug/shared.lib
|
||||||
|
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../shared/libshared.a
|
||||||
|
4
qss.pro
4
qss.pro
@ -1,2 +1,4 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
SUBDIRS = gui cli
|
SUBDIRS = gui cli \
|
||||||
|
shared
|
||||||
|
|
||||||
|
32
shared/shared.pro
Normal file
32
shared/shared.pro
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2019-04-20T23:00:36
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += sql
|
||||||
|
|
||||||
|
QT -= gui
|
||||||
|
|
||||||
|
TARGET = shared
|
||||||
|
TEMPLATE = lib
|
||||||
|
CONFIG += staticlib
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
SOURCES += sqlitesearch.cpp
|
||||||
|
|
||||||
|
HEADERS += sqlitesearch.h
|
||||||
|
unix {
|
||||||
|
target.path = /usr/lib
|
||||||
|
INSTALLS += target
|
||||||
|
}
|
158
shared/sqlitesearch.cpp
Normal file
158
shared/sqlitesearch.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <QStack>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
#include "sqlitesearch.h"
|
||||||
|
|
||||||
|
SqliteSearch::SqliteSearch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<SqliteSearch::Token> SqliteSearch::tokenize(QString expression)
|
||||||
|
{
|
||||||
|
if(!checkParanthesis(expression))
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Invalid paranthesis");
|
||||||
|
}
|
||||||
|
// TODO: merge lonewords
|
||||||
|
QVector<SqliteSearch::Token> result;
|
||||||
|
QRegularExpression rx("((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|(\\w)+)|(?<boolean>AND|OR|!)|"
|
||||||
|
"(?<bracket>\\(|\\))|(?<loneword>\\w+))");
|
||||||
|
QRegularExpressionMatchIterator i = rx.globalMatch(expression);
|
||||||
|
bool wasbool = true;
|
||||||
|
while(i.hasNext())
|
||||||
|
{
|
||||||
|
QRegularExpressionMatch m = i.next();
|
||||||
|
QString boolean = m.captured("boolean");
|
||||||
|
QString filtername = m.captured("filtername");
|
||||||
|
QString bracket = m.captured("bracket");
|
||||||
|
QString loneword = m.captured("loneword");
|
||||||
|
|
||||||
|
if(boolean != "")
|
||||||
|
{
|
||||||
|
wasbool = true;
|
||||||
|
result.append(Token(boolean));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bracket != "")
|
||||||
|
{
|
||||||
|
if(!wasbool)
|
||||||
|
{
|
||||||
|
if(bracket == "(")
|
||||||
|
{
|
||||||
|
result.append(Token("AND"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(Token(bracket));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(loneword != "")
|
||||||
|
{
|
||||||
|
if(!wasbool)
|
||||||
|
{
|
||||||
|
result.append(Token("AND"));
|
||||||
|
}
|
||||||
|
wasbool = false;
|
||||||
|
result.append(Token("path.contains", loneword));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filtername != "")
|
||||||
|
{
|
||||||
|
if(!wasbool)
|
||||||
|
{
|
||||||
|
result.append(Token("AND"));
|
||||||
|
}
|
||||||
|
wasbool = false;
|
||||||
|
QString value = m.captured("innerargs");
|
||||||
|
if(value == "")
|
||||||
|
{
|
||||||
|
value = m.captured("args");
|
||||||
|
}
|
||||||
|
result.append(Token(filtername, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqliteSearch::createSql(const SqliteSearch::Token &token)
|
||||||
|
{
|
||||||
|
QString key = token.key;
|
||||||
|
QString value = token.value;
|
||||||
|
value = value.replace("'", "\\'");
|
||||||
|
if(key == "AND" || key == "OR" || key == "(" || key == ")")
|
||||||
|
{
|
||||||
|
return " " + key + " ";
|
||||||
|
}
|
||||||
|
if(key == "!")
|
||||||
|
{
|
||||||
|
return " NOT ";
|
||||||
|
}
|
||||||
|
if(key == "path.starts")
|
||||||
|
{
|
||||||
|
return " file.path LIKE '" + value + "%' ";
|
||||||
|
}
|
||||||
|
if(key == "path.ends")
|
||||||
|
{
|
||||||
|
return " file.path LIKE '%" + value + "' ";
|
||||||
|
}
|
||||||
|
if(key == "path.contains" || key == "inpath")
|
||||||
|
{
|
||||||
|
return " file.path LIKE '%" + value + "%' ";
|
||||||
|
}
|
||||||
|
if(key == "page")
|
||||||
|
{
|
||||||
|
return " content.page = " + value;
|
||||||
|
}
|
||||||
|
if(key == "contains" || key == "c")
|
||||||
|
{
|
||||||
|
return " content.id IN (SELECT content_fts.ROWID FROM content_fts WHERE content_fts.content MATCH '" + value +
|
||||||
|
"' )";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::invalid_argument("Unknown filter: " + key.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqliteSearch::makeSql(const QVector<SqliteSearch::Token> &tokens)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
for(const Token &c : tokens)
|
||||||
|
{
|
||||||
|
result += createSql(c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqliteSearch::search(const QString &query)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SqliteSearch::checkParanthesis(QString expression)
|
||||||
|
{
|
||||||
|
QStack<QChar> open;
|
||||||
|
QStack<QChar> close;
|
||||||
|
|
||||||
|
for(QChar &c : expression)
|
||||||
|
{
|
||||||
|
if(c == '(')
|
||||||
|
{
|
||||||
|
open.push(c);
|
||||||
|
}
|
||||||
|
if(c == ')')
|
||||||
|
{
|
||||||
|
close.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(open.size() != close.size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while(!open.empty() && !close.empty())
|
||||||
|
{
|
||||||
|
QChar o = open.pop();
|
||||||
|
QChar c = close.pop();
|
||||||
|
if(o != '(' && c != ')')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
33
shared/sqlitesearch.h
Normal file
33
shared/sqlitesearch.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef SQLITESEARCH_H
|
||||||
|
#define SQLITESEARCH_H
|
||||||
|
#include <QSqlDatabase>
|
||||||
|
|
||||||
|
class SqliteSearch
|
||||||
|
{
|
||||||
|
class Token
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString key;
|
||||||
|
QString value;
|
||||||
|
|
||||||
|
Token(QString key = "", QString value = "")
|
||||||
|
{
|
||||||
|
this->key = key;
|
||||||
|
this->value = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSqlDatabase *db;
|
||||||
|
QVector<SqliteSearch::Token> tokenize(QString expression);
|
||||||
|
QString createSql(const Token &token);
|
||||||
|
QString makeSql(const QVector<Token> &tokens);
|
||||||
|
bool checkParanthesis(QString expression);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SqliteSearch();
|
||||||
|
SqliteSearch(QSqlDatabase &db);
|
||||||
|
void search(const QString &query);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SQLITESEARCH_H
|
Loading…
Reference in New Issue
Block a user