commit
071a65b449
|
@ -8,7 +8,8 @@
|
|||
* Add common Array methods to List and Results
|
||||
* Accept constructor in create() and objects() methods
|
||||
* Support relative paths when opening realms
|
||||
* Support for indexed bool, string, date, and int properties
|
||||
* Support case insensitive queries
|
||||
* Support for indexed bool, string, and int properties
|
||||
|
||||
### Bugfixes
|
||||
* Fix for crash on Android when initializing the Realm module
|
||||
|
|
|
@ -66,8 +66,9 @@ struct argument : seq< one< '$' >, must< argument_index > > {};
|
|||
|
||||
// expressions and operators
|
||||
struct expr : sor< dq_string, sq_string, number, argument, true_value, false_value, key_path > {};
|
||||
struct case_insensitive : pegtl_istring_t("[c]"){};
|
||||
|
||||
struct eq : sor< two< '=' >, one< '=' > > {};
|
||||
struct eq : seq< sor< two< '=' >, one< '=' > >, opt< case_insensitive > >{};
|
||||
struct noteq : pegtl::string< '!', '=' > {};
|
||||
struct lteq : pegtl::string< '<', '=' > {};
|
||||
struct lt : one< '<' > {};
|
||||
|
@ -80,7 +81,7 @@ struct ends : pegtl_istring_t("endswith") {};
|
|||
template<typename A, typename B>
|
||||
struct pad_plus : seq< plus< B >, A, plus< B > > {};
|
||||
|
||||
struct padded_oper : pad_plus< sor< contains, begins, ends >, blank > {};
|
||||
struct padded_oper : pad_plus< seq< sor< contains, begins, ends>, opt< case_insensitive > >, blank > {};
|
||||
struct symbolic_oper : pad< sor< eq, noteq, lteq, lt, gteq, gt >, blank > {};
|
||||
|
||||
// predicates
|
||||
|
@ -236,8 +237,7 @@ 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)
|
||||
|
||||
|
||||
|
||||
template<> struct action< true_pred >
|
||||
{
|
||||
static void apply( const input & in, ParserState & state )
|
||||
|
@ -271,7 +271,16 @@ OPERATOR_ACTION(lt, Predicate::Operator::LessThan)
|
|||
OPERATOR_ACTION(begins, Predicate::Operator::BeginsWith)
|
||||
OPERATOR_ACTION(ends, Predicate::Operator::EndsWith)
|
||||
OPERATOR_ACTION(contains, Predicate::Operator::Contains)
|
||||
|
||||
|
||||
template<> struct action< case_insensitive >
|
||||
{
|
||||
static void apply( const input & in, ParserState & state )
|
||||
{
|
||||
DEBUG_PRINT_TOKEN(in.string());
|
||||
state.last_predicate()->cmpr.option = Predicate::OperatorOption::CaseInsensitive;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct action< one< '(' > >
|
||||
{
|
||||
static void apply( const input & in, ParserState & state )
|
||||
|
|
|
@ -57,10 +57,17 @@ struct Predicate
|
|||
EndsWith,
|
||||
Contains
|
||||
};
|
||||
|
||||
enum class OperatorOption
|
||||
{
|
||||
None,
|
||||
CaseInsensitive,
|
||||
};
|
||||
|
||||
struct Comparison
|
||||
{
|
||||
Operator op = Operator::None;
|
||||
OperatorOption option = OperatorOption::None;
|
||||
Expression expr[2] = {{Expression::Type::None, ""}, {Expression::Type::None, ""}};
|
||||
};
|
||||
|
||||
|
|
|
@ -164,11 +164,11 @@ void add_bool_constraint_to_query(Query &query, Predicate::Operator operatorType
|
|||
}
|
||||
|
||||
void add_string_constraint_to_query(Query &query,
|
||||
Predicate::Operator op,
|
||||
Predicate::Comparison cmp,
|
||||
Columns<String> &&column,
|
||||
std::string &&value) {
|
||||
bool case_sensitive = true;
|
||||
switch (op) {
|
||||
bool case_sensitive = (cmp.option != Predicate::OperatorOption::CaseInsensitive);
|
||||
switch (cmp.op) {
|
||||
case Predicate::Operator::BeginsWith:
|
||||
query.and_query(column.begins_with(value, case_sensitive));
|
||||
break;
|
||||
|
@ -190,11 +190,11 @@ void add_string_constraint_to_query(Query &query,
|
|||
}
|
||||
|
||||
void add_string_constraint_to_query(realm::Query &query,
|
||||
Predicate::Operator op,
|
||||
Predicate::Comparison cmp,
|
||||
std::string &&value,
|
||||
Columns<String> &&column) {
|
||||
bool case_sensitive = true;
|
||||
switch (op) {
|
||||
bool case_sensitive = (cmp.option != Predicate::OperatorOption::CaseInsensitive);
|
||||
switch (cmp.op) {
|
||||
case Predicate::Operator::Equal:
|
||||
query.and_query(column.equal(value, case_sensitive));
|
||||
break;
|
||||
|
@ -396,42 +396,42 @@ auto value_of_type_for_query(TableGetter&& tables, Value&& value, Arguments &arg
|
|||
}
|
||||
|
||||
template <typename A, typename B>
|
||||
void do_add_comparison_to_query(Query &query, const Schema &schema, const ObjectSchema &object_schema, Predicate::Operator op,
|
||||
void do_add_comparison_to_query(Query &query, const Schema &schema, const ObjectSchema &object_schema, Predicate::Comparison cmp,
|
||||
const PropertyExpression &expr, A &lhs, B &rhs, Arguments &args)
|
||||
{
|
||||
auto type = expr.prop->type;
|
||||
switch (type) {
|
||||
case PropertyTypeBool:
|
||||
add_bool_constraint_to_query(query, op, value_of_type_for_query<bool>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<bool>(expr.table_getter, rhs, args));
|
||||
add_bool_constraint_to_query(query, cmp.op, value_of_type_for_query<bool>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<bool>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeDate:
|
||||
add_numeric_constraint_to_query(query, op, value_of_type_for_query<DateTime>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<DateTime>(expr.table_getter, rhs, args));
|
||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<DateTime>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<DateTime>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeDouble:
|
||||
add_numeric_constraint_to_query(query, op, value_of_type_for_query<Double>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Double>(expr.table_getter, rhs, args));
|
||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Double>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Double>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeFloat:
|
||||
add_numeric_constraint_to_query(query, op, value_of_type_for_query<Float>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Float>(expr.table_getter, rhs, args));
|
||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Float>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Float>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeInt:
|
||||
add_numeric_constraint_to_query(query, op, value_of_type_for_query<Int>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Int>(expr.table_getter, rhs, args));
|
||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Int>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Int>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeString:
|
||||
add_string_constraint_to_query(query, op, value_of_type_for_query<String>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<String>(expr.table_getter, rhs, args));
|
||||
add_string_constraint_to_query(query, cmp, value_of_type_for_query<String>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<String>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeData:
|
||||
add_binary_constraint_to_query(query, op, value_of_type_for_query<Binary>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Binary>(expr.table_getter, rhs, args));
|
||||
add_binary_constraint_to_query(query, cmp.op, value_of_type_for_query<Binary>(expr.table_getter, lhs, args),
|
||||
value_of_type_for_query<Binary>(expr.table_getter, rhs, args));
|
||||
break;
|
||||
case PropertyTypeObject:
|
||||
case PropertyTypeArray:
|
||||
add_link_constraint_to_query(query, op, expr, link_argument(lhs, rhs, args));
|
||||
add_link_constraint_to_query(query, cmp.op, expr, link_argument(lhs, rhs, args));
|
||||
break;
|
||||
default: {
|
||||
throw std::runtime_error((std::string)"Object type " + string_for_property_type(type) + " not supported");
|
||||
|
@ -446,11 +446,11 @@ void add_comparison_to_query(Query &query, const Predicate &pred, Arguments &arg
|
|||
auto object_schema = schema.find(type);
|
||||
if (t0 == parser::Expression::Type::KeyPath && t1 != parser::Expression::Type::KeyPath) {
|
||||
PropertyExpression expr(query, schema, object_schema, cmpr.expr[0].s);
|
||||
do_add_comparison_to_query(query, schema, *object_schema, cmpr.op, expr, expr, cmpr.expr[1], args);
|
||||
do_add_comparison_to_query(query, schema, *object_schema, cmpr, expr, expr, cmpr.expr[1], args);
|
||||
}
|
||||
else if (t0 != parser::Expression::Type::KeyPath && t1 == parser::Expression::Type::KeyPath) {
|
||||
PropertyExpression expr(query, schema, object_schema, cmpr.expr[1].s);
|
||||
do_add_comparison_to_query(query, schema, *object_schema, cmpr.op, expr, cmpr.expr[0], expr, args);
|
||||
do_add_comparison_to_query(query, schema, *object_schema, cmpr, expr, cmpr.expr[0], expr, args);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Predicate expressions must compare a keypath and another keypath or a constant value");
|
||||
|
|
|
@ -197,10 +197,10 @@
|
|||
["QueryThrows", "StringObject", "stringCol == 123"],
|
||||
["QueryThrows", "StringObject", "stringCol CONTAINS $0", 1],
|
||||
|
||||
["Disabled", "QueryCount", 3, "StringObject", "stringCol ==[c] 'a'"],
|
||||
["Disabled", "QueryCount", 5, "StringObject", "stringCol BEGINSWITH[c] 'A'"],
|
||||
["Disabled", "QueryCount", 4, "StringObject", "stringCol ENDSWITH[c] 'c'"],
|
||||
["Disabled", "QueryCount", 2, "StringObject", "stringCol CONTAINS[c] 'B'"]
|
||||
["QueryCount", 3, "StringObject", "stringCol ==[c] 'a'"],
|
||||
["QueryCount", 5, "StringObject", "stringCol BEGINSWITH[c] 'A'"],
|
||||
["QueryCount", 4, "StringObject", "stringCol ENDSWITH[c] 'c'"],
|
||||
["QueryCount", 2, "StringObject", "stringCol CONTAINS[c] 'B'"]
|
||||
]
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue