public static CreateAndMap ( |
||
context | ||
type | ||
element | JToken | |
typeMappings | IEnumerable |
|
nestingLevel | int | |
return | object |
// ReSharper disable UnusedParameter.Local IEnumerable <TResult> ParseInSingleColumnMode(DeserializationContext context, JToken root, string[] columnNames, TypeMapping[] jsonTypeMappings) // ReSharper restore UnusedParameter.Local { if (columnNames.Count() != 1) { throw new InvalidOperationException("The deserializer is running in single column mode, but the response included multiple columns which indicates a projection instead. If using the fluent Cypher interface, use the overload of Return that takes a lambda or object instead of single string. (The overload with a single string is for an identity, not raw query text: we can't map the columns back out if you just supply raw query text.)"); } var resultType = typeof(TResult); var isResultTypeANodeOrRelationshipInstance = resultType.IsGenericType && (resultType.GetGenericTypeDefinition() == typeof(Node <>) || resultType.GetGenericTypeDefinition() == typeof(RelationshipInstance <>)); var mapping = jsonTypeMappings.SingleOrDefault(m => m.ShouldTriggerForPropertyType(0, resultType)); var newType = mapping == null ? resultType : mapping.DetermineTypeToParseJsonIntoBasedOnPropertyType(resultType); var dataArray = (JArray)root["data"]; var rows = dataArray.Children(); var results = rows.Select(row => { if (!(row is JArray)) { throw new InvalidOperationException("Expected the row to be a JSON array of values, but it wasn't."); } var rowAsArray = (JArray)row; if (rowAsArray.Count != 1) { throw new InvalidOperationException(string.Format("Expected the row to only have a single array value, but it had {0}.", rowAsArray.Count)); } var elementToParse = row[0]; if (elementToParse is JObject) { var propertyNames = ((JObject)elementToParse) .Properties() .Select(p => p.Name) .ToArray(); var dataElementLooksLikeANodeOrRelationshipInstance = new[] { "data", "self", "traverse", "properties" }.All(propertyNames.Contains); if (!isResultTypeANodeOrRelationshipInstance && dataElementLooksLikeANodeOrRelationshipInstance) { elementToParse = elementToParse["data"]; } } var parsed = CommonDeserializerMethods.CreateAndMap(context, newType, elementToParse, jsonTypeMappings, 0); return((TResult)(mapping == null ? parsed : mapping.MutationCallback(parsed))); }); return(results); }
// ReSharper disable UnusedParameter.Local private IEnumerable <TResult> ParseInSingleColumnMode(DeserializationContext context, JToken root, string[] columnNames, TypeMapping[] jsonTypeMappings, bool isHttp) // ReSharper restore UnusedParameter.Local { if (columnNames.Count() != 1) { throw new InvalidOperationException("The deserializer is running in single column mode, but the response included multiple columns which indicates a projection instead. If using the fluent Cypher interface, use the overload of Return that takes a lambda or object instead of single string. (The overload with a single string is for an identity, not raw query text: we can't map the columns back out if you just supply raw query text.)"); } var resultType = typeof(TResult); var isResultTypeANodeOrRelationshipInstance = resultType.GetTypeInfo().IsGenericType&& (resultType.GetGenericTypeDefinition() == typeof(Node <>) || resultType.GetGenericTypeDefinition() == typeof(RelationshipInstance <>)); var mapping = jsonTypeMappings.SingleOrDefault(m => m.ShouldTriggerForPropertyType(0, resultType)); var newType = mapping == null ? resultType : mapping.DetermineTypeToParseJsonIntoBasedOnPropertyType(resultType); var dataArray = isHttp ? (JArray)root.SelectToken("$.results[0].data") : (JArray)root["data"]; if (dataArray == null) //Hack prior to swapping out deserialization completely. { dataArray = !isHttp ? (JArray)root.SelectToken("$.results[0].data") : (JArray)root["data"]; } var rows = dataArray.Children(); //var x = resultFormat == CypherResultFormat.Rest ? "rest" : "row"; var dataPropertyNameInTransaction = "row"; var results = rows.Select(row => { if (inTransaction || isHttp) //All HTTP messages are now in txs -- This is a temporary measure. { var rowObject = row as JObject; if (rowObject == null) { throw new InvalidOperationException("Expected the row to be a JSON object, but it wasn't."); } if (!rowObject.TryGetValue(dataPropertyNameInTransaction, out var rowProperty)) { throw new InvalidOperationException("There is no row property in the JSON object."); } row = rowProperty; } if (!(row is JArray)) { // no transaction mode and the row is not an array throw new InvalidOperationException("Expected the row to be a JSON array of values, but it wasn't."); } var rowAsArray = (JArray)row; if (rowAsArray.Count > 1) { throw new InvalidOperationException($"Expected the row to only have a single array value, but it had {rowAsArray.Count}."); } return(rowAsArray); } ) .Where(row => row.Count != 0) // No elements to parse .Select(row => { var elementToParse = row[0]; if (elementToParse is JObject) { var propertyNames = ((JObject)elementToParse) .Properties() .Select(p => p.Name) .ToArray(); var dataElementLooksLikeANodeOrRelationshipInstance = new[] { "data", "self", "traverse", "properties" }.All(propertyNames.Contains); if (!isResultTypeANodeOrRelationshipInstance && dataElementLooksLikeANodeOrRelationshipInstance) { elementToParse = elementToParse["data"]; } } var parsed = CommonDeserializerMethods.CreateAndMap(context, newType, elementToParse, jsonTypeMappings, 0); return((TResult)(mapping == null ? parsed : mapping.MutationCallback(parsed))); }); return(results); }