mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-11 14:54:33 +00:00
Merge pull request #63 from realm/al-nullable-default
Optional property bug fixe/case insensitive queries
This commit is contained in:
commit
449c4e6519
@ -208,11 +208,13 @@ namespace realm {
|
||||
case PropertyTypeArray: {
|
||||
realm::LinkViewRef link_view = m_row.get_linklist(column);
|
||||
link_view->clear();
|
||||
if (!Accessor::is_null(ctx, value)) {
|
||||
size_t count = Accessor::list_size(ctx, value);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ValueType element = Accessor::list_value_at_index(ctx, value, i);
|
||||
link_view->add(Accessor::to_object_index(ctx, m_realm, element, property.object_type, try_update));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -310,6 +312,9 @@ namespace realm {
|
||||
if (Accessor::has_default_value_for_property(ctx, realm.get(), object_schema, prop.name)) {
|
||||
object.set_property_value_impl(ctx, prop, Accessor::default_value_for_property(ctx, realm.get(), object_schema, prop.name), try_update);
|
||||
}
|
||||
else if (prop.is_nullable || prop.type == PropertyTypeArray) {
|
||||
object.set_property_value_impl(ctx, prop, Accessor::null_value(ctx), try_update);
|
||||
}
|
||||
else {
|
||||
throw MissingPropertyValueException(object_schema.name, prop.name,
|
||||
"Missing property value for property " + prop.name);
|
||||
|
@ -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
|
||||
@ -237,7 +238,6 @@ 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 )
|
||||
@ -272,6 +272,15 @@ 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 )
|
||||
|
@ -58,9 +58,16 @@ struct Predicate
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
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…
x
Reference in New Issue
Block a user