Get property information from modern graph
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/71c4a8fa Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/71c4a8fa Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/71c4a8fa Branch: refs/heads/TINKERPOP-1827 Commit: 71c4a8fac1edb2a75ccbc6b74e348a26f8e9e551 Parents: d8adc29 Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> Authored: Fri Oct 27 14:18:32 2017 +0200 Committer: Jorge Bay Gondra <jorgebaygon...@gmail.com> Committed: Thu Nov 23 09:08:06 2017 +0100 ---------------------------------------------------------------------- .../ModernGraphTypeInformation.cs | 70 ++++++++++++++++++++ .../TraversalEvaluationTests.cs | 10 ++- .../TraversalEvaluation/TraversalParser.cs | 24 ++++--- 3 files changed, 92 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/71c4a8fa/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs new file mode 100644 index 0000000..bce3449 --- /dev/null +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ModernGraphTypeInformation.cs @@ -0,0 +1,70 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation +{ + internal class ModernGraphTypeInformation + { + private static readonly IDictionary<string, Type> PropertyInfos = new Dictionary<string, Type> + { + {"age", typeof(int)}, + {"name", typeof(string)}, + {"lang", typeof(string)}, + {"weight", typeof(float)} + }; + + /// <summary> + /// Gets the type argument information based on the modern graph. + /// </summary>s + public static Type GetTypeArguments(MethodInfo method, object[] parameterValues) + { + switch (method.Name) + { + case nameof(GraphTraversal<object,object>.ValueMap): + case nameof(GraphTraversal<object,object>.Values) when parameterValues.Length == 1: + // The parameter contains the element property names + var properties = ((IEnumerable) parameterValues[parameterValues.Length - 1]).Cast<string>(); + var types = properties.Select(GetElementPropertyType).ToArray(); + if (types.Distinct().Count() == 1) + { + return types[0]; + } + return typeof(object); + } + return null; + } + + private static Type GetElementPropertyType(string name) + { + PropertyInfos.TryGetValue(name, out var type); + return type; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/71c4a8fa/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs index 0949ad5..4e3ec42 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs @@ -77,15 +77,19 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation [Fact] public void GetTraversal_Should_Invoke_Traversal_Methods() { - var traversalTexts = new string[] + var traversalTexts = new [] { "g.V().count()", - "g.V().constant(123)" + "g.V().constant(123)", + "g.V().has(\"no\").count()", + "g.V().values(\"age\")", + "g.V().valueMap(\"name\", \"age\")", + "g.V().repeat(__.both()).times(5)" }; var g = new Graph().Traversal(); foreach (var text in traversalTexts) { - TraversalParser.GetTraversal(text, g); + Assert.NotNull(TraversalParser.GetTraversal(text, g)); } } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/71c4a8fa/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs index 65ca103..11283c1 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs @@ -34,7 +34,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation private static readonly IDictionary<string, Func<GraphTraversalSource, ITraversal>> FixedTranslations = new Dictionary<string, Func<GraphTraversalSource, ITraversal>> { - { "g.V().has(\"no\").count()", g => g.V().Has("no").Count() }, { "g.V().fold().count(Scope.local)", g => g.V().Fold<object>().Count(Scope.Local)} }; @@ -83,14 +82,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation { throw new InvalidOperationException($"Traversal method '{parts[i]}' not found for testing"); } - var parameters = BuildParameters(method, token, out var genericParameters); - method = BuildGenericMethod(method, genericParameters); - traversal = (ITraversal) method.Invoke(traversal, parameters); + var parameterValues = BuildParameters(method, token, out var genericParameters); + method = BuildGenericMethod(method, genericParameters, parameterValues); + traversal = (ITraversal) method.Invoke(traversal, parameterValues); } return traversal; } - private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters) + private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters, + object[] parameterValues) { if (!method.IsGenericMethod) { @@ -101,17 +101,19 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation for (var i = 0; i < genericArgs.Length; i++) { var name = genericArgs[i].Name; - if (genericParameters.TryGetValue(name, out var type)) + Type type; + if (!genericParameters.TryGetValue(name, out type)) { - types[i] = type; + // Try to infer it from the name based on modern graph + type = ModernGraphTypeInformation.GetTypeArguments(method, parameterValues); } - //TODO: Try to infer it from the name based on modern schema - else + if (type == null) { throw new InvalidOperationException( $"Can not build traversal to test as '{method.Name}()' method is generic and type '{name}'" + $" can not be inferred"); } + types[i] = type; } return method.MakeGenericMethod(types); } @@ -138,6 +140,10 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation // if we have the type of value we have the type of E2. genericParameterTypes.Add(info.ParameterType.Name, tokenParameter.GetParameterType()); } + else if (info.ParameterType == typeof(object[])) + { + value = new [] {value}; + } } parameters[i] = value ?? GetDefault(info.ParameterType); }