Skip to content

Commit 12d18e1

Browse files
craiggwilsonrstam
authored andcommitted
CSHARP-1608: Added support for $reverseArray.
1 parent 37a1556 commit 12d18e1

File tree

8 files changed

+133
-0
lines changed

8 files changed

+133
-0
lines changed

src/MongoDB.Driver/Linq/Expressions/ExtensionExpressionType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ internal enum ExtensionExpressionType
3030
Intersect,
3131
Join,
3232
OrderBy,
33+
Reverse,
3334
Sample,
3435
Select,
3536
SelectMany,

src/MongoDB.Driver/Linq/Expressions/ExtensionExpressionVisitor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ protected internal virtual ResultOperator VisitResultOperator(ResultOperator res
170170
return resultOperator.Update(this);
171171
}
172172

173+
protected internal virtual Expression VisitReverse(ReverseExpression node)
174+
{
175+
return node.Update(Visit(node.Source));
176+
}
177+
173178
protected internal virtual Expression VisitSample(SampleExpression node)
174179
{
175180
return node.Update(
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* Copyright 2015 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Linq.Expressions;
18+
using MongoDB.Driver.Core.Misc;
19+
20+
namespace MongoDB.Driver.Linq.Expressions
21+
{
22+
internal sealed class ReverseExpression : ExtensionExpression, ISourcedExpression
23+
{
24+
private readonly Expression _source;
25+
26+
public ReverseExpression(Expression source)
27+
{
28+
_source = Ensure.IsNotNull(source, nameof(source));
29+
}
30+
31+
public override ExtensionExpressionType ExtensionType
32+
{
33+
get { return ExtensionExpressionType.Reverse; }
34+
}
35+
36+
public Expression Source
37+
{
38+
get { return _source; }
39+
}
40+
41+
public override Type Type
42+
{
43+
get { return _source.Type; }
44+
}
45+
46+
public override string ToString()
47+
{
48+
return string.Format("{0}.Reverse()", _source.ToString());
49+
}
50+
51+
public ReverseExpression Update(Expression source)
52+
{
53+
if (source != _source)
54+
{
55+
return new ReverseExpression(source);
56+
}
57+
58+
return this;
59+
}
60+
61+
protected internal override Expression Accept(ExtensionExpressionVisitor visitor)
62+
{
63+
return visitor.VisitReverse(this);
64+
}
65+
}
66+
}

src/MongoDB.Driver/Linq/Processors/EmbeddedPipeline/EmbeddedPipelineBinder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ static EmbeddedPipelineBinder()
4343
infoBinder.Register(new MaxBinder(), MaxBinder.GetSupportedMethods());
4444
infoBinder.Register(new MinBinder(), MinBinder.GetSupportedMethods());
4545
infoBinder.Register(new OfTypeBinder(), OfTypeBinder.GetSupportedMethods());
46+
infoBinder.Register(new ReverseBinder(), ReverseBinder.GetSupportedMethods());
4647
infoBinder.Register(new SelectBinder(), SelectBinder.GetSupportedMethods());
4748
infoBinder.Register(new SkipBinder(), SkipBinder.GetSupportedMethods());
4849
infoBinder.Register(new StandardDeviationBinder(), StandardDeviationBinder.GetSupportedMethods());
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* Copyright 2015 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Linq.Expressions;
19+
using System.Reflection;
20+
using MongoDB.Driver.Linq.Expressions;
21+
22+
namespace MongoDB.Driver.Linq.Processors.EmbeddedPipeline.MethodCallBinders
23+
{
24+
internal sealed class ReverseBinder : IMethodCallBinder<EmbeddedPipelineBindingContext>
25+
{
26+
public static IEnumerable<MethodInfo> GetSupportedMethods()
27+
{
28+
yield return MethodHelper.GetMethodDefinition(() => Enumerable.Reverse<object>(null));
29+
yield return MethodHelper.GetMethodDefinition(() => Queryable.Reverse<object>(null));
30+
}
31+
32+
public Expression Bind(PipelineExpression pipeline, EmbeddedPipelineBindingContext bindingContext, MethodCallExpression node, IEnumerable<Expression> arguments)
33+
{
34+
return new PipelineExpression(
35+
new ReverseExpression(pipeline.Source),
36+
pipeline.Projector);
37+
}
38+
}
39+
}

src/MongoDB.Driver/Linq/Translators/AggregateLanguageTranslator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ private BsonValue TranslateValue(Expression node)
120120
return TranslateIntersect((IntersectExpression)node);
121121
case ExtensionExpressionType.Pipeline:
122122
return TranslatePipeline((PipelineExpression)node);
123+
case ExtensionExpressionType.Reverse:
124+
return TranslateReverse((ReverseExpression)node);
123125
case ExtensionExpressionType.Select:
124126
return TranslateSelect((SelectExpression)node);
125127
case ExtensionExpressionType.Skip:
@@ -466,6 +468,11 @@ private BsonValue TranslatePipeline(PipelineExpression node)
466468
throw new NotSupportedException(message);
467469
}
468470

471+
private BsonValue TranslateReverse(ReverseExpression node)
472+
{
473+
return new BsonDocument("$reverseArray", TranslateValue(node.Source));
474+
}
475+
469476
private BsonValue TranslateSelect(SelectExpression node)
470477
{
471478
var inputValue = TranslateValue(node.Source);

src/MongoDB.Driver/MongoDB.Driver.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
<Compile Include="Linq\Expressions\ExceptExpression.cs" />
124124
<Compile Include="Linq\Expressions\IntersectExpression.cs" />
125125
<Compile Include="Linq\Expressions\SampleExpression.cs" />
126+
<Compile Include="Linq\Expressions\ReverseExpression.cs" />
126127
<Compile Include="Linq\Expressions\UnionExpression.cs" />
127128
<Compile Include="Linq\Expressions\WhereExpression.cs" />
128129
<Compile Include="Linq\Expressions\ISerializationExpression.cs" />
@@ -165,6 +166,7 @@
165166
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\StandardDeviationBinder.cs" />
166167
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\TakeBinder.cs" />
167168
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\ToHashSetBinder.cs" />
169+
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\ReverseBinder.cs" />
168170
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\UnionBinder.cs" />
169171
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\IntersectBinder.cs" />
170172
<Compile Include="Linq\Processors\EmbeddedPipeline\MethodCallBinders\ExceptBinder.cs" />

tests/MongoDB.Driver.Tests/Linq/Translators/AggregateProjectTranslatorTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,18 @@ public void Should_translate_pow()
800800
result.Value.Result.Should().Be(161051);
801801
}
802802

803+
[SkippableFact]
804+
public void Should_translate_reverse()
805+
{
806+
RequireServer.Where(minimumVersion: "3.3.4");
807+
808+
var result = Project(x => new { Result = x.M.Reverse() });
809+
810+
result.Projection.Should().Be("{ Result: { \"$reverseArray\": \"$M\" }, _id: 0 }");
811+
812+
result.Value.Result.Should().BeEquivalentTo(5, 4, 2);
813+
}
814+
803815
[Fact]
804816
public void Should_translate_second()
805817
{

0 commit comments

Comments
 (0)