support for querying boolean properties

This commit is contained in:
Ari Lazier 2015-11-10 14:24:30 -08:00
parent e078b22c9a
commit b97728ba33
3 changed files with 26 additions and 24 deletions

View File

@ -23,7 +23,6 @@
#include <pegtl.hh>
#include <pegtl/analyze.hh>
#include <pegtl/trace.hh>
#include <pegtl/internal/pegtl_string.hh>
using namespace pegtl;
@ -56,6 +55,9 @@ struct int_num : plus< digit > {};
struct number : seq< minus, sor< float_num, hex_num, int_num > > {};
struct true_value : pegtl_istring_t("true") {};
struct false_value : pegtl_istring_t("false") {};
// key paths
struct key_path : list< seq< sor< alpha, one< '_' > >, star< sor< alnum, one< '_', '-' > > > >, one< '.' > > {};
@ -64,7 +66,7 @@ struct argument_index : until< at< one< '}' > >, must< digit > > {};
struct argument : seq< one< '{' >, must< argument_index >, any > {};
// expressions and operators
struct expr : sor< dq_string, sq_string, key_path, number, argument > {};
struct expr : sor< dq_string, sq_string, number, argument, true_value, false_value, key_path > {};
struct eq : sor< two< '=' >, one< '=' > > {};
struct noteq : pegtl::string< '!', '=' > {};
@ -87,8 +89,8 @@ struct comparison_pred : seq< expr, sor< padded_oper, symbolic_oper >, expr > {}
struct pred;
struct group_pred : if_must< one< '(' >, pad< pred, blank >, one< ')' > > {};
struct true_pred : sor< pegtl_istring_t("truepredicate"), pegtl_istring_t("true") > {};
struct false_pred : sor< pegtl_istring_t("falsepredicate"), pegtl_istring_t("false") > {};
struct true_pred : pegtl_istring_t("truepredicate") {};
struct false_pred : pegtl_istring_t("falsepredicate") {};
struct not_pre : sor< seq< one< '!' >, star< blank > >, seq< pegtl_istring_t("not"), plus< blank > > > {};
struct atom_pred : seq< opt< not_pre >, pad< sor< group_pred, true_pred, false_pred, comparison_pred >, blank > > {};
@ -207,6 +209,8 @@ EXPRESSION_ACTION(dq_string_content, Expression::Type::String)
EXPRESSION_ACTION(sq_string_content, Expression::Type::String)
EXPRESSION_ACTION(key_path, Expression::Type::KeyPath)
EXPRESSION_ACTION(number, Expression::Type::Number)
EXPRESSION_ACTION(true_value, Expression::Type::True)
EXPRESSION_ACTION(false_value, Expression::Type::False)
EXPRESSION_ACTION(argument_index, Expression::Type::Argument)
@ -228,7 +232,6 @@ template<> struct action< false_pred >
}
};
#define OPERATOR_ACTION(rule, oper) \
template<> struct action< rule > { \
static void apply( const input & in, ParserState & state ) { \
@ -245,7 +248,6 @@ OPERATOR_ACTION(begins, Predicate::Operator::BeginsWith)
OPERATOR_ACTION(ends, Predicate::Operator::EndsWith)
OPERATOR_ACTION(contains, Predicate::Operator::Contains)
template<> struct action< one< '(' > >
{
static void apply( const input & in, ParserState & state )

View File

@ -28,7 +28,7 @@ namespace realm {
namespace parser {
struct Expression
{
enum class Type { Number, String, KeyPath, Argument } type;
enum class Type { Number, String, KeyPath, Argument, True, False } type;
std::string s;
Expression() {}
Expression(Type t, std::string s) : type(t), s(s) {}

View File

@ -152,7 +152,7 @@ void add_string_constraint_to_query(realm::Query& query,
template <typename RequestedType, typename TableGetter>
struct ColumnOfTypeHelper {
static Columns<RequestedType> convert(TableGetter&& table, unsigned int idx)
static Columns<RequestedType> convert(TableGetter&& table, size_t idx)
{
return table()->template column<RequestedType>(idx);
}
@ -160,7 +160,7 @@ struct ColumnOfTypeHelper {
template <typename TableGetter>
struct ColumnOfTypeHelper<DateTime, TableGetter> {
static Columns<Int> convert(TableGetter&& table, unsigned int idx)
static Columns<Int> convert(TableGetter&& table, size_t idx)
{
return table()->template column<Int>(idx);
}
@ -171,7 +171,7 @@ struct ValueOfTypeHelper;
template <typename TableGetter>
struct ValueOfTypeHelper<DateTime, TableGetter> {
static Int convert(TableGetter&&, const std::string & value)
static Int convert(TableGetter&&, const parser::Expression & value)
{
assert(0);
}
@ -179,41 +179,41 @@ struct ValueOfTypeHelper<DateTime, TableGetter> {
template <typename TableGetter>
struct ValueOfTypeHelper<bool, TableGetter> {
static bool convert(TableGetter&&, const std::string & value)
static bool convert(TableGetter&&, const parser::Expression & value)
{
assert(0);
return value.type == parser::Expression::Type::True;
}
};
template <typename TableGetter>
struct ValueOfTypeHelper<Double, TableGetter> {
static Double convert(TableGetter&&, const std::string & value)
static Double convert(TableGetter&&, const parser::Expression & value)
{
return std::stod(value);
return std::stod(value.s);
}
};
template <typename TableGetter>
struct ValueOfTypeHelper<Float, TableGetter> {
static Float convert(TableGetter&&, const std::string & value)
static Float convert(TableGetter&&, const parser::Expression & value)
{
return std::stof(value);
return std::stof(value.s);
}
};
template <typename TableGetter>
struct ValueOfTypeHelper<Int, TableGetter> {
static Int convert(TableGetter&&, const std::string & value)
static Int convert(TableGetter&&, const parser::Expression & value)
{
return std::stoll(value);
return std::stoll(value.s);
}
};
template <typename TableGetter>
struct ValueOfTypeHelper<String, TableGetter> {
static std::string convert(TableGetter&&, const std::string & value)
static std::string convert(TableGetter&&, const parser::Expression & value)
{
return value;
return value.s;
}
};
@ -222,8 +222,8 @@ auto value_of_type_for_query(TableGetter&& tables, Value&& value)
{
const bool isColumnIndex = std::is_same<size_t, typename std::remove_reference<Value>::type>::value;
using helper = std::conditional_t<isColumnIndex,
ColumnOfTypeHelper<RequestedType, TableGetter>,
ValueOfTypeHelper<RequestedType, TableGetter>>;
ColumnOfTypeHelper<RequestedType, TableGetter>,
ValueOfTypeHelper<RequestedType, TableGetter>>;
return helper::convert(std::forward<TableGetter>(tables), std::forward<Value>(value));
}
@ -310,11 +310,11 @@ void add_comparison_to_query(Query &query, Predicate &pred, Schema &schema, Obje
auto t0 = cmpr.expr[0].type, t1 = cmpr.expr[1].type;
if (t0 == parser::Expression::Type::KeyPath && t1 != parser::Expression::Type::KeyPath) {
Property *prop = get_property_from_key_path(schema, object_schema, cmpr.expr[0].s, indexes);
do_add_comparison_to_query(query, schema, object_schema, prop, cmpr.op, indexes, prop->table_column, cmpr.expr[1].s);
do_add_comparison_to_query(query, schema, object_schema, prop, cmpr.op, indexes, prop->table_column, cmpr.expr[1]);
}
else if (t0 != parser::Expression::Type::KeyPath && t1 == parser::Expression::Type::KeyPath) {
Property *prop = get_property_from_key_path(schema, object_schema, cmpr.expr[1].s, indexes);
do_add_comparison_to_query(query, schema, object_schema, prop, cmpr.op, indexes, cmpr.expr[0].s, prop->table_column);
do_add_comparison_to_query(query, schema, object_schema, prop, cmpr.op, indexes, cmpr.expr[0], prop->table_column);
}
else {
throw std::runtime_error("Predicate expressions must compare a keypath and another keypath or a constant value");