Begin 'shared' project to share code between cli and gui
此提交包含在:
32
shared/shared.pro
一般檔案
32
shared/shared.pro
一般檔案
@ -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
|
||||
}
|
162
shared/sqlitesearch.cpp
一般檔案
162
shared/sqlitesearch.cpp
一般檔案
@ -0,0 +1,162 @@
|
||||
#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;
|
||||
}
|
36
shared/sqlitesearch.h
一般檔案
36
shared/sqlitesearch.h
一般檔案
@ -0,0 +1,36 @@
|
||||
#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
|
新增問題並參考
封鎖使用者