Skip to content

Commit

Permalink
added graph depth, direction, startvertex expression nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ra0o0f committed Oct 10, 2016
1 parent ff5ef25 commit ebce332
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/ArangoDB.Client/ArangoDB.Client.Portable.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@
<Compile Include="Query\Clause\FilterClause.cs" />
<Compile Include="Query\Clause\FilterExpressionNode.cs" />
<Compile Include="Query\Clause\GraphClause.cs" />
<Compile Include="Query\Clause\GraphDepthExpressionNode.cs" />
<Compile Include="Query\Clause\GraphDirectionExpressionNode.cs" />
<Compile Include="Query\Clause\GraphExpressionNode.cs" />
<Compile Include="Query\Clause\GraphStartVertexExpressionNode.cs" />
<Compile Include="Query\Clause\GroupByClause.cs" />
<Compile Include="Query\Clause\GroupByExpressionNode.cs" />
<Compile Include="Query\Clause\IgnoreModificationSelectExpressionNode.cs" />
Expand Down
45 changes: 37 additions & 8 deletions src/ArangoDB.Client/Extentions/QueryableExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using ArangoDB.Client.Data;
using ArangoDB.Client.Query;
using ArangoDB.Client.Query.Clause;
using ArangoDB.Client.Utility;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
Expand Down Expand Up @@ -430,40 +431,68 @@ public static ITraversalQueryable<TraversalData<TVertex, TEdge>> Depth<TVertex,
Expression.Constant(min),
Expression.Constant(max))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}

public static ITraversalQueryable<TraversalData<TVertex, TEdge>> InBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
{
return InBound(source, Utils.EdgeDirectionToString(EdgeDirection.Inbound));
}

[ExtentionIdentifier("InBound")]
public static ITraversalQueryable<TraversalData<TVertex, TEdge>> InBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
internal static ITraversalQueryable<TraversalData<TVertex, TEdge>> InBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source, string direction)
{
return source.Provider.CreateQuery<TraversalData<TVertex, TEdge>>(
Expression.Call(
FindExtention("InBound", typeof(TVertex), typeof(TEdge)),
source.Expression)) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
source.Expression,
Expression.Constant(direction))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}

public static ITraversalQueryable<TraversalData<TVertex, TEdge>> OutBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
{
return OutBound(source, Utils.EdgeDirectionToString(EdgeDirection.Outbound));
}

[ExtentionIdentifier("OutBound")]
public static ITraversalQueryable<TraversalData<TVertex, TEdge>> OutBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
internal static ITraversalQueryable<TraversalData<TVertex, TEdge>> OutBound<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source, string direction)
{
return source.Provider.CreateQuery<TraversalData<TVertex, TEdge>>(
Expression.Call(
FindExtention("OutBound", typeof(TVertex), typeof(TEdge)),
source.Expression)) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
source.Expression,
Expression.Constant(direction))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}

public static ITraversalQueryable<TraversalData<TVertex, TEdge>> AnyDirection<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
{
return AnyDirection(source, Utils.EdgeDirectionToString(EdgeDirection.Any));
}

[ExtentionIdentifier("AnyDirection")]
public static ITraversalQueryable<TraversalData<TVertex, TEdge>> AnyDirection<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source)
internal static ITraversalQueryable<TraversalData<TVertex, TEdge>> AnyDirection<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source, string direction)
{
return source.Provider.CreateQuery<TraversalData<TVertex, TEdge>>(
Expression.Call(
FindExtention("AnyDirection", typeof(TVertex), typeof(TEdge)),
source.Expression)) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
source.Expression,
Expression.Constant(direction))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}

[ExtentionIdentifier("StartVertex_Selector")]
public static ITraversalQueryable<TraversalData<TVertex, TEdge>> StartVertex<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source, Expression<Func<object>> selector)
{
return source.Provider.CreateQuery<TraversalData<TVertex, TEdge>>(
Expression.Call(
FindExtention("StartVertex_Selector", typeof(TVertex), typeof(TEdge)),
source.Expression,
Expression.Quote(selector))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}

[ExtentionIdentifier("StartVertex")]
[ExtentionIdentifier("StartVertex_Constant")]
public static ITraversalQueryable<TraversalData<TVertex, TEdge>> StartVertex<TVertex, TEdge>(this ITraversalQueryable<TraversalData<TVertex, TEdge>> source, string vertex)
{
return source.Provider.CreateQuery<TraversalData<TVertex, TEdge>>(
Expression.Call(
FindExtention("StartVertex", typeof(TVertex), typeof(TEdge)),
FindExtention("StartVertex_Constant", typeof(TVertex), typeof(TEdge)),
source.Expression,
Expression.Constant(vertex))) as ITraversalQueryable<TraversalData<TVertex, TEdge>>;
}
Expand Down
3 changes: 3 additions & 0 deletions src/ArangoDB.Client/Query/AQLParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ private IQueryParser CreateQueryParser()
customNodeTypeRegistry.Register(InModificationExpressionNode.SupportedMethods, typeof(InModificationExpressionNode));
customNodeTypeRegistry.Register(IgnoreModificationSelectExpressionNode.SupportedMethods, typeof(IgnoreModificationSelectExpressionNode));
customNodeTypeRegistry.Register(GraphExpressionNode.SupportedMethods, typeof(GraphExpressionNode));
customNodeTypeRegistry.Register(GraphDepthExpressionNode.SupportedMethods, typeof(GraphDepthExpressionNode));
customNodeTypeRegistry.Register(GraphDirectionExpressionNode.SupportedMethods, typeof(GraphDirectionExpressionNode));
customNodeTypeRegistry.Register(GraphStartVertexExpressionNode.SupportedMethods, typeof(GraphStartVertexExpressionNode));

var nodeTypeProvider = ExpressionTreeParser.CreateDefaultNodeTypeProvider();
nodeTypeProvider.InnerProviders.Insert(0, customNodeTypeRegistry);
Expand Down
14 changes: 12 additions & 2 deletions src/ArangoDB.Client/Query/ArangoModelVisitor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using ArangoDB.Client.Data;
using ArangoDB.Client.Query;
using ArangoDB.Client.Query.Clause;
using ArangoDB.Client.Utility;
using Remotion.Linq;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.Expressions;
Expand Down Expand Up @@ -84,7 +85,7 @@ public override void VisitQueryModel(QueryModel queryModel)
queryModel.MainFromClause.Accept(this, queryModel);

VisitBodyClauses(queryModel.BodyClauses, queryModel);

var modificationClause = queryModel.BodyClauses.NextBodyClause<IModificationClause>();

if (modificationClause != null && modificationClause.IgnoreSelect)
Expand Down Expand Up @@ -281,7 +282,16 @@ public void VisitTraversalClause(ITraversalClause traversalClause, QueryModel qu
LinqUtility.ResolvePropertyName($"{traversalClause.AssociatedIdentifier}Edge"),
LinqUtility.ResolvePropertyName($"{traversalClause.AssociatedIdentifier}Path"));

QueryText.AppendFormat(" graph {0} " , LinqUtility.ResolvePropertyName(traversalClause.GraphName.Value.ToString()));
if (traversalClause.Min != null && traversalClause.Max != null)
QueryText.AppendFormat(" {0}..{1} ", traversalClause.Min.Value, traversalClause.Max);

QueryText.AppendFormat(" {0} ", traversalClause.Direction != null
? traversalClause.Direction.Value
: Utils.EdgeDirectionToString(EdgeDirection.Any));

GetAqlExpression(traversalClause.StartVertex, queryModel);

QueryText.AppendFormat(" graph {0} ", LinqUtility.ResolvePropertyName(traversalClause.GraphName.Value.ToString()));
}

public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
Expand Down
8 changes: 8 additions & 0 deletions src/ArangoDB.Client/Query/Clause/GraphClause.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ public class GraphClause : IBodyClause, ITraversalClause

public string AssociatedIdentifier { get; set; }

public ConstantExpression Min { get; set; }

public ConstantExpression Max { get; set; }

public ConstantExpression Direction { get; set; }

public Expression StartVertex { get; set; }

public GraphClause(ConstantExpression graphName, string associatedIdentifier)
{
LinqUtility.CheckNotNull("graphName", graphName);
Expand Down
54 changes: 54 additions & 0 deletions src/ArangoDB.Client/Query/Clause/GraphDepthExpressionNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Remotion.Linq;
using Remotion.Linq.Parsing.Structure.IntermediateModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ArangoDB.Client.Query.Clause
{
public class GraphDepthExpressionNode : MethodCallExpressionNodeBase
{
public static readonly MethodInfo[] SupportedMethods = new[]
{
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.Depth<object,object>(null, 0, 0))
};

public ConstantExpression Min { get; private set; }

public ConstantExpression Max { get; private set; }

public GraphDepthExpressionNode(MethodCallExpressionParseInfo parseInfo,
ConstantExpression min,
ConstantExpression max)
: base(parseInfo)
{
Min = min;
Max = max;
}

public Expression Count { get; private set; }


public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("inputParameter", inputParameter);
LinqUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

return Source.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext);
}

protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("queryModel", queryModel);

var traversalClause = queryModel.BodyClauses.Last(b => b is ITraversalClause) as ITraversalClause;

traversalClause.Min = Min;
traversalClause.Max = Max;
}
}
}
48 changes: 48 additions & 0 deletions src/ArangoDB.Client/Query/Clause/GraphDirectionExpressionNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Remotion.Linq;
using Remotion.Linq.Parsing.Structure.IntermediateModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ArangoDB.Client.Query.Clause
{
public class GraphDirectionExpressionNode : MethodCallExpressionNodeBase
{
public static readonly MethodInfo[] SupportedMethods = new[]
{
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.InBound<object,object>(null, null)),
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.OutBound<object,object>(null, null)),
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.AnyDirection<object,object>(null, null))
};

public ConstantExpression Direction { get; private set; }

public GraphDirectionExpressionNode(MethodCallExpressionParseInfo parseInfo,
ConstantExpression direction)
: base(parseInfo)
{
Direction = direction;
}

public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("inputParameter", inputParameter);
LinqUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

return Source.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext);
}

protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("queryModel", queryModel);

var traversalClause = queryModel.BodyClauses.Last(b => b is ITraversalClause) as ITraversalClause;

traversalClause.Direction = Direction;
}
}
}
47 changes: 47 additions & 0 deletions src/ArangoDB.Client/Query/Clause/GraphStartVertexExpressionNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Remotion.Linq;
using Remotion.Linq.Parsing.Structure.IntermediateModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ArangoDB.Client.Query.Clause
{
public class GraphStartVertexExpressionNode : MethodCallExpressionNodeBase
{
public static readonly MethodInfo[] SupportedMethods = new[]
{
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.StartVertex<object,object>(null, "")),
LinqUtility.GetSupportedMethod(()=>QueryableExtensions.StartVertex<object,object>(null, ()=>""))
};

public Expression StartVertex { get; private set; }

public GraphStartVertexExpressionNode(MethodCallExpressionParseInfo parseInfo,
Expression startVertex)
: base(parseInfo)
{
StartVertex = startVertex;
}

public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("inputParameter", inputParameter);
LinqUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

return Source.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext);
}

protected override void ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
{
LinqUtility.CheckNotNull("queryModel", queryModel);

var traversalClause = queryModel.BodyClauses.Last(b => b is ITraversalClause) as ITraversalClause;

traversalClause.StartVertex = StartVertex;
}
}
}
8 changes: 8 additions & 0 deletions src/ArangoDB.Client/Query/Clause/ITraversalClause.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@ public interface ITraversalClause
ConstantExpression GraphName { get; set; }

string AssociatedIdentifier { get; set; }

ConstantExpression Min { get; set; }

ConstantExpression Max { get; set; }

ConstantExpression Direction { get; set; }

Expression StartVertex { get; set; }
}
}

0 comments on commit ebce332

Please sign in to comment.