2016-02-03 07:18:20 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <string>
|
2016-02-04 09:45:12 +08:00
|
|
|
#include <tuple>
|
|
|
|
#include <utility>
|
2016-02-22 05:21:15 +08:00
|
|
|
#include <unordered_map>
|
2016-02-03 07:18:20 +08:00
|
|
|
|
|
|
|
#include "cypher/cypher.h"
|
2016-02-04 09:45:12 +08:00
|
|
|
#include "cypher/tokenizer/cypher_lexer.hpp"
|
|
|
|
#include "utils/variadic/variadic.hpp"
|
2016-02-22 05:21:15 +08:00
|
|
|
#include "storage/model/properties/all.hpp"
|
|
|
|
#include "query_stripped.hpp"
|
2016-02-03 07:18:20 +08:00
|
|
|
|
2016-02-06 20:45:45 +08:00
|
|
|
#include <iostream>
|
|
|
|
|
2016-02-22 05:21:15 +08:00
|
|
|
template<class T, class V>
|
|
|
|
void store_query_param(code_args_t& arguments, V&& v)
|
|
|
|
{
|
|
|
|
arguments.emplace_back(std::make_shared<T>(std::forward<V>(v)));
|
|
|
|
}
|
|
|
|
|
2016-02-04 09:45:12 +08:00
|
|
|
template<typename ...Ts>
|
2016-02-03 07:18:20 +08:00
|
|
|
class QueryStripper
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2016-02-06 20:45:45 +08:00
|
|
|
QueryStripper(Ts&&... strip_types) :
|
|
|
|
lexer(std::make_unique<CypherLexer>()),
|
2016-02-22 05:21:15 +08:00
|
|
|
strip_types(std::make_tuple(std::forward<Ts>(strip_types)...)) {}
|
|
|
|
|
2016-02-06 20:45:45 +08:00
|
|
|
QueryStripper(QueryStripper& other) = delete;
|
2016-02-22 05:21:15 +08:00
|
|
|
|
2016-02-06 20:45:45 +08:00
|
|
|
QueryStripper(QueryStripper&& other) :
|
|
|
|
strip_types(std::move(other.strip_types)),
|
2016-02-22 05:21:15 +08:00
|
|
|
lexer(std::move(other.lexer)) {}
|
2016-02-03 07:18:20 +08:00
|
|
|
|
2016-02-22 05:21:15 +08:00
|
|
|
auto strip(const std::string& query)
|
2016-02-03 07:18:20 +08:00
|
|
|
{
|
2016-02-22 05:21:15 +08:00
|
|
|
// TODO write this more optimal (resplace string
|
|
|
|
// concatenation with something smarter)
|
|
|
|
// TODO: in place substring replacement
|
|
|
|
|
2016-02-06 20:45:45 +08:00
|
|
|
auto tokenizer = lexer->tokenize(query);
|
2016-02-22 05:21:15 +08:00
|
|
|
|
|
|
|
// TMP size of supported token types
|
2016-02-04 09:45:12 +08:00
|
|
|
constexpr auto size = std::tuple_size<decltype(strip_types)>::value;
|
2016-02-22 05:21:15 +08:00
|
|
|
|
|
|
|
int counter = 0;
|
|
|
|
code_args_t stripped_arguments;
|
|
|
|
std::string stripped_query;
|
|
|
|
stripped_query.reserve(query.size());
|
|
|
|
|
2016-02-03 07:18:20 +08:00
|
|
|
while (auto token = tokenizer.lookup())
|
|
|
|
{
|
2016-02-22 05:21:15 +08:00
|
|
|
// TODO: better implementation
|
2016-02-04 09:45:12 +08:00
|
|
|
if (_or(token.id, strip_types, std::make_index_sequence<size>{})) {
|
2016-02-22 05:21:15 +08:00
|
|
|
auto index = counter++;
|
|
|
|
switch (token.id) {
|
|
|
|
case TK_INT:
|
|
|
|
store_query_param<Int32>(stripped_arguments,
|
|
|
|
std::stoi(token.value));
|
|
|
|
break;
|
|
|
|
case TK_STR:
|
|
|
|
store_query_param<String>(stripped_arguments,
|
|
|
|
token.value);
|
|
|
|
break;
|
|
|
|
case TK_BOOL: {
|
|
|
|
bool value = token.value[0] == 'T' ||
|
|
|
|
token.value[0] == 't';
|
|
|
|
store_query_param<Bool>(stripped_arguments, value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TK_FLOAT:
|
|
|
|
store_query_param<Float>(stripped_arguments,
|
|
|
|
std::stof(token.value));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
stripped_query += std::to_string(index);
|
2016-02-03 07:18:20 +08:00
|
|
|
} else {
|
2016-02-22 05:21:15 +08:00
|
|
|
stripped_query += token.value;
|
2016-02-03 07:18:20 +08:00
|
|
|
}
|
|
|
|
}
|
2016-02-22 05:21:15 +08:00
|
|
|
|
|
|
|
return QueryStripped(std::move(stripped_query),
|
|
|
|
std::move(stripped_arguments));
|
2016-02-03 07:18:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-02-04 09:45:12 +08:00
|
|
|
std::tuple<Ts...> strip_types;
|
2016-02-06 20:45:45 +08:00
|
|
|
CypherLexer::uptr lexer;
|
2016-02-04 09:45:12 +08:00
|
|
|
|
|
|
|
template<typename Value, typename Tuple, std::size_t ...index>
|
|
|
|
bool _or(Value&& value, Tuple&& tuple, std::index_sequence<index...>)
|
|
|
|
{
|
|
|
|
return or_vargs(std::forward<Value>(value),
|
|
|
|
std::get<index>(std::forward<Tuple>(tuple))...);
|
|
|
|
}
|
2016-02-03 07:18:20 +08:00
|
|
|
};
|
2016-02-06 20:45:45 +08:00
|
|
|
|
|
|
|
template<typename ...Ts>
|
|
|
|
decltype(auto) make_query_stripper(Ts&&... ts) {
|
|
|
|
return QueryStripper<Ts...>(std::forward<Ts>(ts)...);
|
|
|
|
}
|