From 3ac196166b05ac17c81620da05e21fee117b98b6 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 18 Nov 2015 17:49:05 -0800 Subject: [PATCH] add binary query support --- parser/query_builder.cpp | 79 +++++++++++++++++++++++++++++++++------- parser/query_builder.hpp | 2 + 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/parser/query_builder.cpp b/parser/query_builder.cpp index 9039ef6b..353588e8 100644 --- a/parser/query_builder.cpp +++ b/parser/query_builder.cpp @@ -102,42 +102,81 @@ void add_bool_constraint_to_query(Query &query, Predicate::Operator operatorType void add_string_constraint_to_query(Query &query, Predicate::Operator op, Columns &&column, - StringData value) { + std::string value) { bool case_sensitive = true; - StringData sd = value; switch (op) { case Predicate::Operator::BeginsWith: - query.and_query(column.begins_with(sd, case_sensitive)); + query.and_query(column.begins_with(value, case_sensitive)); break; case Predicate::Operator::EndsWith: - query.and_query(column.ends_with(sd, case_sensitive)); + query.and_query(column.ends_with(value, case_sensitive)); break; case Predicate::Operator::Contains: - query.and_query(column.contains(sd, case_sensitive)); + query.and_query(column.contains(value, case_sensitive)); break; case Predicate::Operator::Equal: - query.and_query(column.equal(sd, case_sensitive)); + query.and_query(column.equal(value, case_sensitive)); break; case Predicate::Operator::NotEqual: - query.and_query(column.not_equal(sd, case_sensitive)); + query.and_query(column.not_equal(value, case_sensitive)); break; default: throw std::runtime_error("Unsupported operator for string queries."); } } -void add_string_constraint_to_query(realm::Query& query, +void add_string_constraint_to_query(realm::Query &query, Predicate::Operator op, - StringData value, + std::string value, Columns &&column) { bool case_sensitive = true; - StringData sd = value; switch (op) { case Predicate::Operator::Equal: - query.and_query(column.equal(sd, case_sensitive)); + query.and_query(column.equal(value, case_sensitive)); break; case Predicate::Operator::NotEqual: - query.and_query(column.not_equal(sd, case_sensitive)); + query.and_query(column.not_equal(value, case_sensitive)); + break; + default: + throw std::runtime_error("Substring comparison not supported for keypath substrings."); + } +} + +void add_binary_constraint_to_query(Query &query, + Predicate::Operator op, + Columns &&column, + std::string value) { + switch (op) { + case Predicate::Operator::BeginsWith: + query.begins_with(column.m_column, value); + break; + case Predicate::Operator::EndsWith: + query.ends_with(column.m_column, value); + break; + case Predicate::Operator::Contains: + query.contains(column.m_column, value); + break; + case Predicate::Operator::Equal: + query.equal(column.m_column, value); + break; + case Predicate::Operator::NotEqual: + query.not_equal(column.m_column, value); + break; + default: + throw std::runtime_error("Unsupported operator for binary queries."); + } +} + +void add_binary_constraint_to_query(realm::Query &query, + Predicate::Operator op, + std::string value, + Columns &&column) { + switch (op) { + case Predicate::Operator::Equal: + query.equal(column.m_column, value); + break; + case Predicate::Operator::NotEqual: + query.not_equal(column.m_column, value); break; default: throw std::runtime_error("Substring comparison not supported for keypath substrings."); @@ -274,6 +313,17 @@ struct ValueGetter { } }; +template +struct ValueGetter { + static std::string convert(TableGetter&&, const parser::Expression & value, Arguments &args) + { + if (value.type == parser::Expression::Type::Argument) { + return args.binary_for_argument(std::stoi(value.s)); + } + throw std::runtime_error("Binary properties must be compared against a binary argument."); + } +}; + template auto value_of_type_for_query(TableGetter&& tables, Value&& value, Arguments &args) { @@ -309,10 +359,13 @@ void do_add_comparison_to_query(Query &query, Schema &schema, ObjectSchema &obje value_of_type_for_query(expr.table_getter, rhs, args)); break; case PropertyTypeString: - case PropertyTypeData: add_string_constraint_to_query(query, op, value_of_type_for_query(expr.table_getter, lhs, args), value_of_type_for_query(expr.table_getter, rhs, args)); break; + case PropertyTypeData: + add_binary_constraint_to_query(query, op, value_of_type_for_query(expr.table_getter, lhs, args), + value_of_type_for_query(expr.table_getter, rhs, args)); + break; default: { throw std::runtime_error((std::string)"Object type " + string_for_property_type(type) + " not supported"); } diff --git a/parser/query_builder.hpp b/parser/query_builder.hpp index 1de648b3..2d7f9d7c 100644 --- a/parser/query_builder.hpp +++ b/parser/query_builder.hpp @@ -40,6 +40,7 @@ namespace realm { virtual float float_for_argument(size_t argument_index) = 0; virtual double double_for_argument(size_t argument_index) = 0; virtual std::string string_for_argument(size_t argument_index) = 0; + virtual std::string binary_for_argument(size_t argument_index) = 0; virtual DateTime datetime_for_argument(size_t argument_index) = 0; virtual size_t object_index_for_argument(size_t argument_index) = 0; virtual bool is_argument_null(size_t argument_index) = 0; @@ -57,6 +58,7 @@ namespace realm { virtual float float_for_argument(size_t argument_index) { return Accessor::to_float(m_ctx, argument_at(argument_index)); } virtual double double_for_argument(size_t argument_index) { return Accessor::to_double(m_ctx, argument_at(argument_index)); } virtual std::string string_for_argument(size_t argument_index) { return Accessor::to_string(m_ctx, argument_at(argument_index)); } + virtual std::string binary_for_argument(size_t argument_index) { return Accessor::to_binary(m_ctx, argument_at(argument_index)); } virtual DateTime datetime_for_argument(size_t argument_index) { return Accessor::to_datetime(m_ctx, argument_at(argument_index)); } virtual size_t object_index_for_argument(size_t argument_index) { return Accessor::to_existing_object_index(m_ctx, argument_at(argument_index)); } virtual bool is_argument_null(size_t argument_index) { return Accessor::is_null(m_ctx, argument_at(argument_index)); }