You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by jo...@apache.org on 2017/11/22 10:56:58 UTC

tinkerpop git commit: Gremlin .NET: Provide type coercion between IDictionary instances

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1837 [created] a895a6847


Gremlin .NET: Provide type coercion between IDictionary<K, V> instances


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/a895a684
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/a895a684
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/a895a684

Branch: refs/heads/TINKERPOP-1837
Commit: a895a6847521a8aa30a83344cf3262aaa1d8c22f
Parents: 76c42fa
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Wed Nov 22 11:44:00 2017 +0100
Committer: Jorge Bay Gondra <jo...@gmail.com>
Committed: Wed Nov 22 11:55:29 2017 +0100

----------------------------------------------------------------------
 .../Process/Traversal/DefaultTraversal.cs       | 57 +++++++++++++++++++-
 .../GraphTraversalTests.cs                      | 46 ++++++++++++++++
 2 files changed, 101 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a895a684/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs
index d9dfe10..180054e 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/DefaultTraversal.cs
@@ -24,6 +24,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Reflection;
 using System.Threading.Tasks;
 
 namespace Gremlin.Net.Process.Traversal
@@ -86,9 +87,61 @@ namespace Gremlin.Net.Process.Traversal
         }
 
         /// <inheritdoc />
-        public E Current => (E)TraverserEnumerator.Current?.Object;
+        public E Current => GetCurrent<E>();
 
-        object IEnumerator.Current => Current;
+        object IEnumerator.Current => GetCurrent();
+
+        private TReturn GetCurrent<TReturn>()
+        {
+            var value = GetCurrent();
+            var returnType = typeof(TReturn);
+            if (value == null || value.GetType() == returnType)
+            {
+                // Avoid evaluating type comparisons
+                return (TReturn) value;
+            }
+            return (TReturn) GetValue(returnType, value);
+        }
+
+        private object GetCurrent()
+        {
+            // Use dynamic to object to prevent runtime dynamic conversion evaluation
+            return TraverserEnumerator.Current?.Object;
+        }
+
+        /// <summary>
+        /// Gets the value, converting to the expected type when necessary and supported. 
+        /// </summary>
+        private static object GetValue(Type type, object value)
+        {
+            var genericType = type.GetTypeInfo().IsGenericType
+                ? type.GetTypeInfo().GetGenericTypeDefinition()
+                : null;
+            if (value is IDictionary dictValue && genericType == typeof(IDictionary<,>))
+            {
+                var keyType = type.GenericTypeArguments[0];
+                var valueType = type.GenericTypeArguments[1];
+                var mapType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
+                var result = (IDictionary) Activator.CreateInstance(mapType);
+                foreach (DictionaryEntry kv in dictValue)
+                {
+                    result.Add(GetValue(keyType, kv.Key), GetValue(valueType, kv.Value));
+                }
+                return result;
+            }
+            if (value is IEnumerable enumerableValue && genericType == typeof(IList<>))
+            {
+                var childType = type.GenericTypeArguments[0];
+                var listType = typeof(List<>).MakeGenericType(childType);
+                var result = (IList) Activator.CreateInstance(listType);
+                foreach (var itemValue in enumerableValue)
+                {
+                    result.Add(itemValue);
+                }
+                return result;
+            }
+            return value;
+        }
 
         private IEnumerator<Traverser> GetTraverserEnumerator()
         {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a895a684/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs
index 84a44a7..abd2e51 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/GraphTraversalTests.cs
@@ -142,6 +142,52 @@ namespace Gremlin.Net.IntegrationTest.Process.Traversal.DriverRemoteConnection
         }
 
         [Fact]
+        public void ValueMapTest()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var result = g.V(1).ValueMap<IList<object>>().Next();
+            Assert.Equal(
+                new Dictionary<string, IList<object>>
+                {
+                    { "age", new List<object> { 29 } },
+                    { "name", new List<object> { "marko" } }
+                },
+                result);
+        }
+
+        [Fact]
+        public void ValueMapWithListConversionTest()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var result = g.V(1).ValueMap<IList<int>>("age").Next();
+            Assert.Equal(new Dictionary<string, IList<int>>
+            {
+                { "age", new List<int> { 29 } }
+            }, result);
+        }
+
+        [Fact]
+        public void GroupedEdgePropertyConversionTest()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var result = g.V().HasLabel("software").Group<string, double>().By("name")
+                          .By(__.BothE().Values<double>("weight").Mean<double>()).Next();
+            Assert.Equal(new Dictionary<string, double>
+            {
+                { "ripple", 1D },
+                { "lop", 1d/3d }
+            }, result);
+        }
+
+        [Fact]
         public void ShouldUseBindingsInTraversal()
         {
             var graph = new Graph();