Пример #1
0
        private static T ParseCollection <T>(this IRecord record, string identifier, IGraphClient graphClient)
        {
            var typeT = typeof(T).GetTypeInfo();

            if (!typeT.IsGenericType && !typeT.IsArray)
            {
                throw new InvalidOperationException($"Don't know how to handle {typeof(T).FullName}");
            }

            if (typeT.IsArray)
            {
                return(record.ParseArray <T>(identifier, graphClient));
            }

            var genericArgs = typeT.GenericTypeArguments;

            if (genericArgs.Length > 1)
            {
                throw new InvalidOperationException($"Don't know how to handle {typeof(T).FullName}");
            }

            var listType = typeof(List <>).MakeGenericType(genericArgs.Single());
            var list     = Activator.CreateInstance(listType);

            foreach (var item in (IEnumerable)record[identifier])
            {
                var internalRecord = new Neo4jClientRecord(item, identifier);
                var method         = GetParsed(genericArgs.Single());
                var parsed         = method.Invoke(null, internalRecord.AsParameters(graphClient));
                listType.GetMethod("Add")?.Invoke(list, new[] { parsed });
            }

            return((T)list);
        }
Пример #2
0
        private static dynamic ParseElementInCollectionForAnonymous(IGraphClient graphClient, dynamic item, string identifier)
        {
            var newRecord = new Neo4jClientRecord(item, identifier);
            // item o gets parsed and returned always as a list when onlyReturnData = true
            var p2 = (List <dynamic>)ParseAnonymousAsDynamic(newRecord, graphClient, true);

            // but we only need the first item
            return(p2.First());
        }
Пример #3
0
        private static T Parse <T>(this IRecord record, string identifier, IGraphClient graphClient)
        {
            var typeT = typeof(T);

            if (typeT.IsPrimitive())
            {
                return(record.ParsePrimitive <T>(identifier));
            }

            if (typeT.GetTypeInfo().ImplementedInterfaces.Any(x => x.Name == nameof(IEnumerable)) && typeT.Name != nameof(ExpandoObject))
            {
                return(record.ParseCollection <T>(identifier, graphClient));
            }

            var converters = graphClient.JsonConverters;

            converters.Reverse();
            var serializerSettings = new JsonSerializerSettings
            {
                Converters       = converters,
                ContractResolver = graphClient.JsonContractResolver
            };

            foreach (var jsonConverter in converters)
            {
                if (jsonConverter.CanConvert(typeof(T)))
                {
                    return(JsonConvert.DeserializeObject <T>(record[identifier].As <INode>().ToJsonString(), serializerSettings));
                }
            }


            var t   = ConstructNew <T>();
            var obj = record[identifier];

            if (obj is INode node)
            {
                foreach (var property in t.GetType().GetProperties())
                {
                    if (node.Properties.ContainsKey(property.Name))
                    {
                        if (property.PropertyType.IsPrimitive())
                        {
                            property.SetValue(t, Convert.ChangeType(node.Properties[property.Name], property.PropertyType));
                        }
                        else if (property.PropertyType.GetTypeInfo().ImplementedInterfaces.Any(i => i == typeof(IEnumerable)))
                        {
                            var parsed     = GetParsed(property.PropertyType);
                            var enumRecord = new Neo4jClientRecord(node.Properties[property.Name], "Enumerable");
                            var list       = parsed.Invoke(null, enumRecord.AsParameters(graphClient));

                            property.SetValue(t, list);
                        }
                        else
                        {
                            var res = JsonConvert.DeserializeObject(
                                $"\"{node.Properties[property.Name].As<string>()}\"",
                                property.PropertyType,
                                serializerSettings);
                            property.SetValue(t, res);
                        }
                    }
                }
            }
            return(t);
        }
Пример #4
0
        private static dynamic ParseAnonymousAsDynamic(this IRecord record, IGraphClient graphClient, bool onlyReturnData)
        {
            var data = new List <dynamic>();

            var inner = new List <dynamic>();

            foreach (var identifier in record.Keys)
            {
                dynamic expando = new ExpandoObject();
                var     t       = (IDictionary <string, object>)expando;
                var     obj     = record[identifier];
                if (obj == null)
                {
                    inner.Add(null);
                }
                else if (obj is IPath path)
                {
                    inner.Add(ParsePathResponse(path));
                }
                else if (obj is INode node)
                {
                    foreach (var property in node.Properties)
                    {
                        t[property.Key] = property.Value;
                    }
                    inner.Add(new Dictionary <string, dynamic> {
                        { "data", expando }
                    });
                }
                else if (obj is IEnumerable && !(obj is string))
                {
                    var count   = 0;
                    var listObj = ((IEnumerable)obj).Cast <object>().ToList();

                    var first = listObj.FirstOrDefault();
                    if (first is KeyValuePair <string, object> )
                    {
                        var     newNode  = new Neo4jClientNode(listObj.Cast <KeyValuePair <string, object> >());
                        dynamic expando2 = new ExpandoObject();
                        var     t2       = (IDictionary <string, object>)expando2;
                        foreach (var property in newNode.Properties)
                        {
                            t2[property.Key] = property.Value;
                        }
                        inner.Add(expando2);
                    }
                    else
                    {
                        foreach (var o in listObj)
                        {
                            var newRecord = new Neo4jClientRecord(o, identifier);
                            var p2        = ParseAnonymousAsDynamic(newRecord, graphClient, true);
                            inner.Add(p2);
                            count++;
                        }
                        if (count == 0)
                        {
                            inner.Add(new object[0]);
                        }
                    }
                }
                else
                {
                    var method  = typeof(StatementResultHelper).GetMethod(nameof(Parse), BindingFlags.Static | BindingFlags.NonPublic);
                    var generic = method?.MakeGenericMethod(obj.GetType());
                    var res     = generic?.Invoke(null, new object[] { record, identifier, graphClient });
                    if (res == null)
                    {
                        throw new JsonSerializationException($"Unable to serialize {obj.GetType().FullName} correctly. This is likely an error and should be reported to Neo4jClient's github page.");
                    }

                    inner.Add(res);
                }
            }

            data.Add(inner);

            if (onlyReturnData)
            {
                return(inner);
            }

            //TODO: Ugh! this is about as hacky as it can get
            dynamic output = new
            {
                columns = new List <string>(record.Keys),
                data
            };

            return(output);
        }