Apply clang-format

This commit is contained in:
Luis Ángel San Martín 2019-09-23 18:02:23 +02:00 committed by Luis Ángel San Martín
parent 9a660350d2
commit 7ccb338455
2 changed files with 135 additions and 102 deletions

View File

@ -5,23 +5,23 @@
#include <type_traits> #include <type_traits>
#include <numeric> #include <numeric>
const std::map<QueryParser::FieldType, std::vector<std::string>> QueryParser::fieldNames { const std::map<QueryParser::FieldType, std::vector<std::string>> QueryParser::fieldNames {
{FieldType::numeric, {"numpages", "number", "count", "arcnumber", "arccount"}}, { FieldType::numeric, { "numpages", "number", "count", "arcnumber", "arccount" } },
{FieldType::text, {"title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", { FieldType::text, { "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes" } },
"coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes"}}, { FieldType::boolean, { "isbis", "color" } },
{FieldType::boolean, {"isbis", "color"}}, { FieldType::date, { "date" } },
{FieldType::date, {"date"}}, { FieldType::filename, { "filename" } },
{FieldType::filename, {"filename"}}, { FieldType::folder, { "folder" } }
{FieldType::folder, {"folder"}} }; };
int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPosition) const { int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPosition) const
{
if (t == "token") { if (t == "token") {
++bindPosition; ++bindPosition;
std::ostringstream oss; std::ostringstream oss;
if (toLower(children[0].t) == "all") { if (toLower(children[0].t) == "all") {
oss << "("; oss << "(";
for (const auto& field: fieldNames.at(FieldType::text)) { for (const auto &field : fieldNames.at(FieldType::text)) {
oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR "; oss << "UPPER(ci." << field << ") LIKE UPPER(:bindPosition" << bindPosition << ") OR ";
} }
oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR "; oss << "UPPER(c.filename) LIKE UPPER(:bindPosition" << bindPosition << ") OR ";
@ -49,16 +49,17 @@ int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPositi
} }
return bindPosition; return bindPosition;
} }
int QueryParser::TreeNode::bindValues(QSqlQuery& selectQuery, int bindPosition) const { int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) const
{
if (t == "token") { if (t == "token") {
std::ostringstream oss; std::ostringstream oss;
oss << ":bindPosition" << ++bindPosition; oss << ":bindPosition" << ++bindPosition;
if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) { if (isIn(fieldType(children[0].t), FieldType::numeric, FieldType::boolean)) {
selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t)); selectQuery.bindValue(oss.str().c_str(), std::stoi(children[1].t));
} else { } else {
selectQuery.bindValue(oss.str().c_str(), ("%%"+children[1].t+"%%").c_str()); selectQuery.bindValue(oss.str().c_str(), ("%%" + children[1].t + "%%").c_str());
} }
} else if (t == "not") { } else if (t == "not") {
bindPosition = children[0].bindValues(selectQuery, bindPosition); bindPosition = children[0].bindValues(selectQuery, bindPosition);
@ -68,10 +69,11 @@ int QueryParser::TreeNode::buildSqlString(std::string& sqlString, int bindPositi
} }
return bindPosition; return bindPosition;
} }
QueryParser::QueryParser()
QueryParser::QueryParser(): lexScanner(0) { : lexScanner(0)
{
lexScanner.push("[()]", static_cast<std::underlying_type<TokenType>::type>(TokenType::opcode)); lexScanner.push("[()]", static_cast<std::underlying_type<TokenType>::type>(TokenType::opcode));
lexScanner.push("@[^:]+:[^\\\")\\s]+", static_cast<std::underlying_type<TokenType>::type>(TokenType::atWord)); lexScanner.push("@[^:]+:[^\\\")\\s]+", static_cast<std::underlying_type<TokenType>::type>(TokenType::atWord));
@ -82,7 +84,8 @@ QueryParser::QueryParser(): lexScanner(0) {
lexertl::generator::build(lexScanner, sm); lexertl::generator::build(lexScanner, sm);
} }
QueryParser::TreeNode QueryParser::parse(const std::string& expr) { QueryParser::TreeNode QueryParser::parse(const std::string &expr)
{
tokenize(expr); tokenize(expr);
auto prog = orExpression(); auto prog = orExpression();
@ -93,52 +96,60 @@ QueryParser::TreeNode QueryParser::parse(const std::string& expr) {
return prog; return prog;
} }
std::string QueryParser::toLower(const std::string& string) { std::string QueryParser::toLower(const std::string &string)
{
std::string res(string); std::string res(string);
std::transform(res.begin(), res.end(), res.begin(), ::tolower); std::transform(res.begin(), res.end(), res.begin(), ::tolower);
return res; return res;
} }
std::string QueryParser::token(bool advance) { std::string QueryParser::token(bool advance)
{
if (isEof()) { if (isEof()) {
return ""; return "";
} }
auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str();
if (advance) { if (advance) {
this->advance(); this->advance();
} }
return res; return res;
} }
std::string QueryParser::lcaseToken(bool advance) { std::string QueryParser::lcaseToken(bool advance)
{
if (isEof()) { if (isEof()) {
return ""; return "";
} }
auto res = (tokenType() == TokenType::quotedWord)?iter->substr(1,1):iter->str(); auto res = (tokenType() == TokenType::quotedWord) ? iter->substr(1, 1) : iter->str();
if (advance) { if (advance) {
this->advance(); this->advance();
} }
return toLower(res); return toLower(res);
} }
QueryParser::TokenType QueryParser::tokenType() { QueryParser::TokenType QueryParser::tokenType()
{
if (isEof()) { if (isEof()) {
return TokenType::eof; return TokenType::eof;
} }
return TokenType(iter->id); return TokenType(iter->id);
} }
bool QueryParser::isEof() const { bool QueryParser::isEof() const
{
return iter == end; return iter == end;
} }
void QueryParser::advance() { void QueryParser::advance()
{
++iter; ++iter;
if (tokenType() == TokenType::space) advance(); if (tokenType() == TokenType::space)
advance();
} }
QueryParser::FieldType QueryParser::fieldType(const std::string& str) { QueryParser::FieldType QueryParser::fieldType(const std::string &str)
for (const auto& names : fieldNames) { {
for (const auto &names : fieldNames) {
if (std::find(names.second.begin(), names.second.end(), toLower(str)) != names.second.end()) { if (std::find(names.second.begin(), names.second.end(), toLower(str)) != names.second.end()) {
return names.first; return names.first;
} }
@ -147,21 +158,24 @@ QueryParser::FieldType QueryParser::fieldType(const std::string& str) {
return FieldType::unknown; return FieldType::unknown;
} }
void QueryParser::tokenize (const std::string& expr) { void QueryParser::tokenize(const std::string &expr)
{
iter = lexertl::siterator(expr.begin(), expr.end(), sm); iter = lexertl::siterator(expr.begin(), expr.end(), sm);
} }
std::string QueryParser::join(const std::vector<std::string>& strings, const std::string& delim) { std::string QueryParser::join(const std::vector<std::string> &strings, const std::string &delim)
{
return std::accumulate(strings.begin(), strings.end(), std::string(), return std::accumulate(strings.begin(), strings.end(), std::string(),
[&delim](const std::string& a, const std::string& b) -> std::string { [&delim](const std::string &a, const std::string &b) -> std::string {
return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b; return a + (a.length() > 0 && b.length() > 0 ? delim : "") + b;
} ); });
} }
std::vector<std::string> QueryParser::split(const std::string& string, char delim) { std::vector<std::string> QueryParser::split(const std::string &string, char delim)
{
std::istringstream iss(string); std::istringstream iss(string);
std::vector<std::string> words; std::vector<std::string> words;
while(iss) { while (iss) {
std::string substr; std::string substr;
std::getline(iss, substr, delim); std::getline(iss, substr, delim);
words.push_back(substr); words.push_back(substr);
@ -169,38 +183,42 @@ std::vector<std::string> QueryParser::split(const std::string& string, char deli
return words; return words;
} }
QueryParser::TreeNode QueryParser::orExpression() { QueryParser::TreeNode QueryParser::orExpression()
{
auto lhs = andExpression(); auto lhs = andExpression();
if (lcaseToken() == "or") { if (lcaseToken() == "or") {
advance(); advance();
return {"or", {lhs, orExpression()}}; return { "or", { lhs, orExpression() } };
} }
return lhs; return lhs;
} }
QueryParser::TreeNode QueryParser::andExpression() { QueryParser::TreeNode QueryParser::andExpression()
{
auto lhs = notExpression(); auto lhs = notExpression();
if (lcaseToken() == "and") { if (lcaseToken() == "and") {
advance(); advance();
return {"and", {lhs, andExpression()}}; return { "and", { lhs, andExpression() } };
} }
if ((isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord) || token() == "(") && lcaseToken() != "or") { if ((isIn(tokenType(), TokenType::atWord, TokenType::word, TokenType::quotedWord) || token() == "(") && lcaseToken() != "or") {
return {"and", {lhs, andExpression()}}; return { "and", { lhs, andExpression() } };
} }
return lhs; return lhs;
} }
QueryParser::TreeNode QueryParser::notExpression() { QueryParser::TreeNode QueryParser::notExpression()
{
if (lcaseToken() == "not") { if (lcaseToken() == "not") {
advance(); advance();
return {"not", {notExpression()}}; return { "not", { notExpression() } };
} }
return locationExpression(); return locationExpression();
} }
QueryParser::TreeNode QueryParser::locationExpression() { QueryParser::TreeNode QueryParser::locationExpression()
{
if (tokenType() == TokenType::opcode && token() == "(") { if (tokenType() == TokenType::opcode && token() == "(") {
advance(); advance();
auto res = orExpression(); auto res = orExpression();
@ -215,9 +233,10 @@ QueryParser::TreeNode QueryParser::locationExpression() {
return baseToken(); return baseToken();
} }
QueryParser::TreeNode QueryParser::baseToken() { QueryParser::TreeNode QueryParser::baseToken()
{
if (tokenType() == TokenType::quotedWord) { if (tokenType() == TokenType::quotedWord) {
return {"token", {{"all", {}}, {token(true), {}}}}; return { "token", { { "all", {} }, { token(true), {} } } };
} }
auto words(split(token(true), ':')); auto words(split(token(true), ':'));
@ -226,9 +245,9 @@ QueryParser::TreeNode QueryParser::baseToken() {
auto loc(toLower(words[0])); auto loc(toLower(words[0]));
words.erase(words.begin()); words.erase(words.begin());
if (words.size() == 1 && tokenType() == TokenType::quotedWord) { if (words.size() == 1 && tokenType() == TokenType::quotedWord) {
return {"token", {{loc, {}}, {token(true), {}}}}; return { "token", { { loc, {} }, { token(true), {} } } };
} }
return {"token", {{loc, {}}, {join(words, ":"), {}}}}; return { "token", { { loc, {} }, { join(words, ":"), {} } } };
} }
return {"token", {{"all", {}}, {join(words, ":"), {}}}}; return { "token", { { "all", {} }, { join(words, ":"), {} } } };
} }

View File

@ -38,24 +38,29 @@
* *
* selectQuery.exec(); * selectQuery.exec();
*/ */
class QueryParser { class QueryParser
{
public: public:
enum class TokenType { eof,
enum class TokenType {eof, opcode, atWord, word, quotedWord, space}; opcode,
atWord,
word,
quotedWord,
space };
struct TreeNode { struct TreeNode {
std::string t; std::string t;
std::vector<TreeNode> children; std::vector<TreeNode> children;
int buildSqlString(std::string& sqlString, int bindPosition = 0) const; int buildSqlString(std::string &sqlString, int bindPosition = 0) const;
int bindValues(QSqlQuery& selectQuery, int bindPosition = 0) const; int bindValues(QSqlQuery &selectQuery, int bindPosition = 0) const;
}; };
explicit QueryParser(); explicit QueryParser();
TreeNode parse(const std::string& expr); TreeNode parse(const std::string &expr);
private: private:
static std::string toLower(const std::string& string); static std::string toLower(const std::string &string);
std::string token(bool advance = false); std::string token(bool advance = false);
std::string lcaseToken(bool advance = false); std::string lcaseToken(bool advance = false);
@ -63,15 +68,24 @@ private:
bool isEof() const; bool isEof() const;
void advance(); void advance();
template<typename First, typename ... T> template<typename First, typename... T>
static bool isIn(First &&first, T && ... t) {return ((first == t) || ...);} static bool isIn(First &&first, T &&... t)
{
return ((first == t) || ...);
}
enum class FieldType {unknown, numeric, text, boolean, date, folder, filename}; enum class FieldType { unknown,
static FieldType fieldType(const std::string& str); numeric,
text,
boolean,
date,
folder,
filename };
static FieldType fieldType(const std::string &str);
void tokenize (const std::string& expr); void tokenize(const std::string &expr);
static std::string join(const std::vector<std::string>& strings, const std::string& delim); static std::string join(const std::vector<std::string> &strings, const std::string &delim);
static std::vector<std::string> split(const std::string& string, char delim); static std::vector<std::string> split(const std::string &string, char delim);
TreeNode orExpression(); TreeNode orExpression();
TreeNode andExpression(); TreeNode andExpression();