support for querying boolean properties
This commit is contained in:
parent
bb16ffa7fe
commit
3b698400b7
|
@ -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 )
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
|
|
@ -237,10 +237,10 @@ module.exports = BaseTest.extend({
|
|||
testRealmObjects: function() {
|
||||
var realm = new Realm({schema: [schemas.PersonObject]});
|
||||
realm.write(function() {
|
||||
realm.create('PersonObject', ['Ari', 10]);
|
||||
realm.create('PersonObject', ['Tim', 11]);
|
||||
realm.create('PersonObject', ['Ari', 10, false]);
|
||||
realm.create('PersonObject', ['Tim', 11, false]);
|
||||
realm.create('PersonObject', {'name': 'Bjarne', 'age': 12});
|
||||
realm.create('PersonObject', {'name': 'Alex', 'age': 12});
|
||||
realm.create('PersonObject', {'name': 'Alex', 'age': 12, 'married': true});
|
||||
});
|
||||
|
||||
TestCase.assertThrows(function() {
|
||||
|
@ -270,6 +270,8 @@ module.exports = BaseTest.extend({
|
|||
TestCase.assertEqual(realm.objects('PersonObject', 'age >= 11 && age < 13').length, 3);
|
||||
TestCase.assertEqual(realm.objects('PersonObject', 'name = "Tim"').length, 1);
|
||||
TestCase.assertEqual(realm.objects('PersonObject', 'name = \'Tim\'').length, 1);
|
||||
TestCase.assertEqual(realm.objects('PersonObject', 'married == TRUE').length, 1);
|
||||
TestCase.assertEqual(realm.objects('PersonObject', 'married == false').length, 3);
|
||||
},
|
||||
|
||||
testNotifications: function() {
|
||||
|
|
|
@ -24,8 +24,8 @@ module.exports = BaseTest.extend({
|
|||
testResultsSubscript: function() {
|
||||
var realm = new Realm({schema: [schemas.PersonObject]});
|
||||
realm.write(function() {
|
||||
realm.create('PersonObject', ['name1', 1]);
|
||||
realm.create('PersonObject', ['name2', 2]);
|
||||
realm.create('PersonObject', ['name1', 1, false]);
|
||||
realm.create('PersonObject', ['name2', 2, false]);
|
||||
});
|
||||
|
||||
var people = realm.objects('PersonObject');
|
||||
|
|
|
@ -19,6 +19,7 @@ PersonObject.prototype.schema = {
|
|||
properties: [
|
||||
{name: 'name', type: Realm.Types.STRING},
|
||||
{name: 'age', type: Realm.Types.DOUBLE},
|
||||
{name: 'married', type: Realm.Types.BOOL, default: false}
|
||||
]
|
||||
};
|
||||
PersonObject.prototype.description = function() {
|
||||
|
|
Loading…
Reference in New Issue