Skip to content

Commit 11785b7

Browse files
authored
Merge pull request #74 from danny-krueger/bugfix/use-enum-multiple-times
Resolves #64 Fixed that the same enum can be used multiple times in the schema
2 parents 0b62a6f + ba622ef commit 11785b7

File tree

2 files changed

+73
-16
lines changed

2 files changed

+73
-16
lines changed

AvroSchemaGenerator.Tests/GetSchemaTest.cs

+40
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,31 @@ public void TestEnums()
155155

156156
Assert.Equal(expectSchema, actual);
157157
}
158+
159+
[Fact]
160+
public void TestMultipleEnums()
161+
{
162+
var expectSchema = "{\"namespace\":\"AvroSchemaGenerator.Tests\",\"name\":\"MultipleEnums\",\"type\":\"record\",\"fields\":[{\"name\":\"Type\",\"type\":{\"namespace\":\"AvroSchemaGenerator.Tests\",\"type\":\"enum\",\"name\":\"MediaType\",\"symbols\":[\"Video\",\"Audio\"]}},{\"name\":\"TypeTo\",\"type\":\"MediaType\"},{\"name\":\"Month\",\"type\":{\"namespace\":\"AvroSchemaGenerator.Tests\",\"type\":\"enum\",\"name\":\"Month\",\"symbols\":[\"January\",\"February\",\"March\",\"April\",\"June\",\"July\"]}},{\"name\":\"Container\",\"type\":{\"namespace\":\"AvroSchemaGenerator.Tests\",\"type\":\"enum\",\"name\":\"MediaContainer\",\"symbols\":[\"Flv\",\"Mp3\",\"Avi\",\"Mp4\"]}},{\"name\":\"InnerAliases\",\"type\":[\"null\",{\"namespace\":\"AvroSchemaGenerator.Tests\",\"name\":\"InnerAliases\",\"type\":\"record\",\"fields\":[{\"name\":\"Container\",\"type\":[\"null\",\"MediaContainer\"]},{\"name\":\"Title\",\"type\":[\"null\",\"string\"],\"default\":null}]}]},{\"name\":\"YearlyMovies\",\"type\":{\"type\":\"map\",\"values\":{\"namespace\":\"AvroSchemaGenerator.Tests\",\"name\":\"MovieAliase\",\"type\":\"record\",\"aliases\":[\"Movies_Aliase\"],\"fields\":[{\"name\":\"Dated\",\"aliases\":[\"DateCreated\"],\"type\":\"long\"},{\"name\":\"Year\",\"aliases\":[\"ReleaseYear\"],\"type\":\"int\"},{\"name\":\"Month\",\"aliases\":[\"ReleaseMonth\"],\"type\":\"Month\"}]}},\"default\":{}}]}";
163+
var actual = typeof(MultipleEnums).GetSchema();
164+
_output.WriteLine(actual);
165+
var schema = Schema.Parse(actual);
166+
167+
Assert.Equal(expectSchema, actual);
168+
Assert.NotNull(schema);
169+
}
170+
171+
[Fact]
172+
public void TestClassWhichHasFieldsWithSameType()
173+
{
174+
var expectSchema = "{\"namespace\":\"AvroSchemaGenerator.Tests\",\"name\":\"ClassWhichHasFieldsWithSameType\",\"type\":\"record\",\"fields\":[{\"name\":\"FirstBook\",\"type\":[\"null\",{\"namespace\":\"AvroSchemaGenerator.Tests\",\"name\":\"Book\",\"type\":\"record\",\"fields\":[{\"name\":\"Author\",\"type\":[\"null\",\"string\"],\"default\":null},{\"name\":\"Title\",\"type\":[\"null\",\"string\"],\"default\":null}]}]},{\"name\":\"SecondBook\",\"type\":[\"null\",\"Book\"]}]}";
175+
var actual = typeof(ClassWhichHasFieldsWithSameType).GetSchema();
176+
_output.WriteLine(actual);
177+
var schema = Schema.Parse(actual);
178+
179+
Assert.Equal(expectSchema, actual);
180+
Assert.NotNull(schema);
181+
}
182+
158183
[Fact]
159184
public void TestAliasesList()
160185
{
@@ -503,6 +528,12 @@ public class Person
503528
public List<string> Children { get; set; }
504529
}
505530

531+
public class ClassWhichHasFieldsWithSameType
532+
{
533+
public Book FirstBook { get; set; }
534+
public Book SecondBook { get; set; }
535+
}
536+
506537
[Aliases("InterLives", "CountrySide")]
507538
public sealed class ClassWithAliasesWithList
508539
{
@@ -560,7 +591,16 @@ public class MediaStream
560591
public MediaType Type { get; set; }
561592
public MediaContainer Container { get; set; }
562593
public byte[] Media { get; set; }
594+
}
563595

596+
public class MultipleEnums
597+
{
598+
public MediaType Type { get; set; }
599+
public MediaType TypeTo { get; set; }
600+
public Month Month { get; set; }
601+
public MediaContainer Container { get; set; }
602+
public InnerAliases InnerAliases { get; set; }
603+
public Dictionary<string, MovieAliase> YearlyMovies { get; set; }
564604
}
565605

566606
public enum Month

SchemaGenerator/GenerateSchema.cs

+33-16
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ private static void PropertyInfo(PropertyInfo property, Dictionary<string, objec
122122
if (p.PropertyType.GetSubTypeIfNullable().IsEnum)
123123
{
124124
var aliases = GetAliases(p);
125-
var row = GetEnumField(p);
125+
var row = GetEnumField(p, existingTypes);
126126
if (aliases != null)
127127
{
128128
var rows = row.ToList();
@@ -325,7 +325,7 @@ private static void PropertyInfo(PropertyInfo property, Dictionary<string, objec
325325
if (p.PropertyType.IsEnum)
326326
{
327327
var aliases = GetAliases(p);
328-
var row = GetEnumField(p);
328+
var row = GetEnumField(p, existingTypes);
329329
if (aliases != null)
330330
{
331331
var rows = row.ToList();
@@ -358,7 +358,7 @@ private static Dictionary<string, object> PropertyInfo(PropertyInfo property, Li
358358
if (p.PropertyType.IsEnum)
359359
{
360360
var aliases = GetAliases(p);
361-
var row = GetEnumField(p);
361+
var row = GetEnumField(p, existingTypes);
362362
if (aliases != null)
363363
{
364364
var rows = row.ToList();
@@ -549,7 +549,7 @@ private static Dictionary<string, object> PropertyInfo(PropertyInfo property, Li
549549
if (p.PropertyType.IsEnum)
550550
{
551551
var aliases = GetAliases(p);
552-
var row = GetEnumField(p);
552+
var row = GetEnumField(p, existingTypes);
553553
if (aliases != null)
554554
{
555555
var rows = row.ToList();
@@ -574,7 +574,7 @@ private static Dictionary<string, object> GetPropertyInfo(PropertyInfo property,
574574
{
575575
if (p.PropertyType.GetSubTypeIfNullable().IsEnum)
576576
{
577-
row = GetEnumField(p);
577+
row = GetEnumField(p, existingTypes);
578578
if (aliases != null)
579579
{
580580
var rows = row.ToList();
@@ -953,7 +953,7 @@ private static bool IsUserDefined(Type p)
953953
}
954954

955955
private static void GetUserDefinedProperties(PropertyInfo property, Dictionary<string, object> finalSchema,
956-
List<string> existing)
956+
List<string> existingTypes)
957957
{
958958
var schema = new Dictionary<string, object>();
959959
if (!string.IsNullOrEmpty(property.PropertyType.Namespace))
@@ -970,7 +970,7 @@ private static void GetUserDefinedProperties(PropertyInfo property, Dictionary<s
970970
{
971971
if (ShouldIgnore(p))
972972
continue;
973-
973+
974974
var customDefinition = CheckAndHandleCustomSchema(p);
975975
if (customDefinition != null)
976976
{
@@ -983,7 +983,7 @@ private static void GetUserDefinedProperties(PropertyInfo property, Dictionary<s
983983
var t = p.PropertyType.Name;
984984
var dt = p.DeclaringType?.Name;
985985
var recursive = t.Equals(dt);
986-
if (existing.Contains(t))
986+
if (existingTypes.Contains(t))
987987
{
988988
var pRequired = p.GetSchemaCustomAttributes().required;
989989
var rw = pRequired
@@ -993,26 +993,26 @@ private static void GetUserDefinedProperties(PropertyInfo property, Dictionary<s
993993
}
994994
else if (recursive)
995995
{
996-
existing.Add(t);
996+
existingTypes.Add(t);
997997
fieldProperties.Add(Reuse(p));
998998
}
999999
else if (p.PropertyType.IsEnum)
10001000
{
10011001
var pAli = GetAliases(p);
10021002
if (aliases != null)
10031003
{
1004-
var rows = GetEnumField(p).ToList();
1004+
var rows = GetEnumField(p, existingTypes).ToList();
10051005
rows.Insert(1, new KeyValuePair<string, object>("aliases", pAli));
10061006
fieldProperties.Add(rows.ToDictionary(x => x.Key, x => x.Value));
10071007
}
1008-
else fieldProperties.Add(GetEnumField(p));
1008+
else fieldProperties.Add(GetEnumField(p, existingTypes));
10091009

1010-
existing.Add(t);
1010+
existingTypes.Add(t);
10111011
}
10121012
else
10131013
{
10141014
//existing.Add(t);
1015-
var rows = PropertyInfo(p, existing, !existing.Contains(t));
1015+
var rows = PropertyInfo(p, existingTypes, !existingTypes.Contains(t));
10161016
fieldProperties.Add(rows);
10171017
}
10181018
}
@@ -1026,7 +1026,7 @@ private static void GetUserDefinedProperties(PropertyInfo property, Dictionary<s
10261026
AddReuseType(p, finalSchema);
10271027
else if (IsUserDefined(v))
10281028
{
1029-
var schem = GetGenericUserDefinedProperties(v, require, existing);
1029+
var schem = GetGenericUserDefinedProperties(v, require, existingTypes);
10301030
var row1 = require
10311031
? new Dictionary<string, object>
10321032
{
@@ -1479,8 +1479,25 @@ private static bool IsDictionary(Type t)
14791479
t.GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>));
14801480
}
14811481

1482-
private static Dictionary<string, object> GetEnumField(PropertyInfo p)
1482+
private static Dictionary<string, object> GetEnumField(PropertyInfo p, ICollection<string> existingTypes)
14831483
{
1484+
var propertyTypeName = p.PropertyType.Name;
1485+
if (existingTypes.Contains(propertyTypeName))
1486+
{
1487+
List<object> lt = null;
1488+
if (p.PropertyType.IsNullable())
1489+
{
1490+
lt = new List<object>() {"null", propertyTypeName};
1491+
}
1492+
1493+
return new Dictionary<string, object>
1494+
{
1495+
{"name", p.Name}, {"type", lt == null ? propertyTypeName : (object) lt}
1496+
};
1497+
}
1498+
1499+
existingTypes.Add(propertyTypeName);
1500+
14841501
var pt = p.PropertyType.GetSubTypeIfNullable();
14851502
var dp = new Dictionary<string, object>();
14861503
if (!string.IsNullOrEmpty(pt.Namespace)) {
@@ -1581,4 +1598,4 @@ private static object ToAvroDataType(string type, LogicalTypeKind? kind)
15811598
}
15821599
}
15831600
}
1584-
}
1601+
}

0 commit comments

Comments
 (0)