Skip to content

Commit eb7c9a8

Browse files
Merge pull request #37 from matteobortolazzo/dev
Fixes PR#36.
2 parents 6724942 + 94f19c3 commit eb7c9a8

File tree

6 files changed

+112
-7
lines changed

6 files changed

+112
-7
lines changed

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
# 1.0.1 (2019-04-27)
1+
# 1.0.2 (2019-05-02)
2+
3+
## Bug Fixes
4+
* **_find:** Boolean member expressions converted to binary expressions in Where (Fix [#PR36](https://github.com/matteobortolazzo/couchdb-net/pull/36)).
5+
6+
# 1.0.1 (2019-04-27)
27

38
## Bug Fixes
49
* **Everywhere:** Flurl JSON serialization based on CouchSettings' PropertyCaseType.

LATEST_CHANGE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
## Bug Fixes
2-
* **Everywhere:** Flurl JSON serialization based on CouchSettings' PropertyCaseType.
2+
* **_find:** Boolean member expression converted to binary expression in Where (Fix [#PR36](https://github.com/matteobortolazzo/couchdb-net/pull/36)).

src/CouchDB.Driver/CouchQueryProvider.cs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using CouchDB.Driver.DTOs;
2+
using CouchDB.Driver.ExpressionVisitors;
23
using CouchDB.Driver.Helpers;
34
using CouchDB.Driver.Settings;
45
using CouchDB.Driver.Types;
@@ -59,13 +60,16 @@ public override object Execute(Expression e, bool completeResponse)
5960
var result = generic.Invoke(this, new[] { body, (object)_filterMethodInfo, _filteringExpressions });
6061
return result;
6162
}
62-
63-
private string Translate(Expression expression)
63+
64+
private string Translate(Expression e)
6465
{
65-
expression = Evaluator.PartialEval(expression);
66-
return new QueryTranslator(_settings).Translate(expression);
67-
}
66+
e = Evaluator.PartialEval(e);
67+
var whereVisitor = new WhereExpressionVisitor();
68+
e = whereVisitor.Visit(e);
6869

70+
return new QueryTranslator(_settings).Translate(e);
71+
}
72+
6973
public object GetCouchListOrFiltered<T>(string body, MethodInfo filteringMethodInfo, Expression[] filteringExpressions)
7074
{
7175
FindResult<T> result = _flurlClient
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Linq;
2+
using System.Linq.Expressions;
3+
using System.Reflection;
4+
5+
namespace CouchDB.Driver.ExpressionVisitors
6+
{
7+
internal class WhereExpressionVisitor : ExpressionVisitor
8+
{
9+
private bool _visitingWhereMethod;
10+
11+
protected override Expression VisitMethodCall(MethodCallExpression m)
12+
{
13+
_visitingWhereMethod = m.Method.Name == "Where" && m.Method.DeclaringType == typeof(Queryable);
14+
if (_visitingWhereMethod)
15+
{
16+
Expression result = base.VisitMethodCall(m);
17+
_visitingWhereMethod = false;
18+
return result;
19+
}
20+
return base.VisitMethodCall(m);
21+
}
22+
23+
protected override Expression VisitBinary(BinaryExpression expression)
24+
{
25+
if (expression.Right is ConstantExpression c && c.Type == typeof(bool) &&
26+
(expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual))
27+
{
28+
return expression;
29+
}
30+
return base.VisitBinary(expression);
31+
}
32+
33+
protected override Expression VisitMember(MemberExpression expression)
34+
{
35+
if (IsWhereBooleanExpression(expression))
36+
{
37+
return Expression.MakeBinary(ExpressionType.Equal, expression, Expression.Constant(true));
38+
}
39+
return base.VisitMember(expression);
40+
}
41+
42+
protected override Expression VisitUnary(UnaryExpression expression)
43+
{
44+
if (expression.NodeType == ExpressionType.Not && expression.Operand is MemberExpression m && IsWhereBooleanExpression(m))
45+
{
46+
return Expression.MakeBinary(ExpressionType.Equal, m, Expression.Constant(false));
47+
}
48+
return base.VisitUnary(expression);
49+
}
50+
51+
private bool IsWhereBooleanExpression(MemberExpression expression)
52+
{
53+
return _visitingWhereMethod &&
54+
expression.Member is PropertyInfo info &&
55+
info.PropertyType == typeof(bool);
56+
}
57+
}
58+
}

tests/CouchDB.Driver.UnitTests/Find/Find_Selector.cs

+37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using CouchDB.Driver.UnitTests.Models;
22
using System;
3+
using System.Linq;
34
using System.Linq.Expressions;
45
using Xunit;
56

@@ -73,5 +74,41 @@ public void GuidQuery()
7374
var json = rebels.Where(r => r.Guid == guid).ToString();
7475
Assert.Equal(@"{""selector"":{""guid"":""83c79283-f634-41e3-8aab-674bdbae3413""}}", json);
7576
}
77+
[Fact]
78+
public void Variable_Bool_True()
79+
{
80+
var json = rebels.Where(r => r.IsJedi).OrderBy(r => r.IsJedi).ToString();
81+
Assert.Equal(@"{""selector"":{""isJedi"":true},""sort"":[""isJedi""]}", json);
82+
}
83+
[Fact]
84+
public void Variable_Bool_False()
85+
{
86+
var json = rebels.Where(r => !r.IsJedi).OrderBy(r => r.IsJedi).ToString();
87+
Assert.Equal(@"{""selector"":{""isJedi"":false},""sort"":[""isJedi""]}", json);
88+
}
89+
[Fact]
90+
public void Variable_Bool_ExplicitTrue()
91+
{
92+
var json = rebels.Where(r => r.IsJedi == true).OrderBy(r => r.IsJedi).ToString();
93+
Assert.Equal(@"{""selector"":{""isJedi"":true},""sort"":[""isJedi""]}", json);
94+
}
95+
[Fact]
96+
public void Variable_Bool_ExplicitFalse()
97+
{
98+
var json = rebels.Where(r => r.IsJedi == false).OrderBy(r => r.IsJedi).ToString();
99+
Assert.Equal(@"{""selector"":{""isJedi"":false},""sort"":[""isJedi""]}", json);
100+
}
101+
[Fact]
102+
public void Variable_Bool_ExplicitNotTrue()
103+
{
104+
var json = rebels.Where(r => r.IsJedi != true).OrderBy(r => r.IsJedi).ToString();
105+
Assert.Equal(@"{""selector"":{""isJedi"":{""$ne"":true}},""sort"":[""isJedi""]}", json);
106+
}
107+
[Fact]
108+
public void Variable_Bool_ExplicitNotFalse()
109+
{
110+
var json = rebels.Where(r => r.IsJedi != false).OrderBy(r => r.IsJedi).ToString();
111+
Assert.Equal(@"{""selector"":{""isJedi"":{""$ne"":false}},""sort"":[""isJedi""]}", json);
112+
}
76113
}
77114
}

tests/CouchDB.Driver.UnitTests/_Models/Rebel.cs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Rebel : CouchDocument
1010
public string Name { get; set; }
1111
public string Surname { get; set; }
1212
public int Age { get; set; }
13+
public bool IsJedi { get; set; }
1314
public Species Species { get; set; }
1415
public Guid Guid { get; set; }
1516
public List<string> Skills { get; set; }

0 commit comments

Comments
 (0)