in Services/DataX.Flow/DataX.Flow.SchemaInference/Engine.cs [107:188]
private void GetSchemaArray(JArray jArray, Type type, string keyPath)
{
if (type == null && string.IsNullOrEmpty(_errors.Where(e => e.Contains(keyPath)).FirstOrDefault()))
{
_errors.Add($"Error in generating schema for '{keyPath}'. Result holder is null");
return;
}
if (jArray == null || jArray.Count<=0)
{
type.elementType = new Type();
(type.elementType as Type).elementType = "string";
return;
}
// This means that the array itself has children that are arrays
if(jArray.First.GetType() == typeof(JArray))
{
keyPath = keyPath + ".array";
// Check if element type already exists. If not create it. If it exists, ensure the type is as expected.
if (type.elementType == null)
{
type.elementType = new Type();
}
else if (type.elementType.GetType() != typeof(Type))
{
if (string.IsNullOrEmpty(_errors.Where(e => e.Contains($"'{keyPath}'")).FirstOrDefault()))
{
_errors.Add($"Conflict in schema. Key with path '{keyPath}' has different types");
}
return;
}
foreach (JArray arrayItem in jArray)
{
GetSchemaArray(arrayItem as JArray, type.elementType as Type, keyPath);
}
}
// This means that the array has children of type Struct objects
if(jArray.First.GetType() == typeof(JObject))
{
// Check if element type already exists. If not create it. If it exists, ensure the type is as expected.
if (type.elementType == null)
{
type.elementType = new StructObject();
}
else if (type.elementType.GetType() != typeof(StructObject))
{
if (string.IsNullOrEmpty(_errors.Where(e => e.Contains($"'{keyPath}'")).FirstOrDefault()))
{
_errors.Add($"Conflict in schema. Key with path '{keyPath}' has different types");
}
return;
}
foreach(JObject arrayItem in jArray)
{
GetSchemaStruct(arrayItem, type.elementType as StructObject, keyPath);
}
}
// This means that the array has children of simple type
if (jArray.First.GetType() == typeof(JValue))
{
string childType = GetObjectType(jArray.First);
if (type.elementType == null)
{
type.elementType = childType;
}
else if (type.elementType.GetType()!=childType.GetType() || type.elementType.ToString().ToLower() != childType.ToLower())
{
if (string.IsNullOrEmpty(_errors.Where(e => e.Contains($"'{keyPath}'")).FirstOrDefault()))
{
_errors.Add($"Conflict in schema. Key with path '{keyPath}' has different types");
}
return;
}
}
}