Created
February 28, 2019 11:10
-
-
Save klesouza/ab02e50748c0bbab14bb0d648b4dfc96 to your computer and use it in GitHub Desktop.
C# script to generate BigQuery (BQ) schema from a C# class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.Reflection; | |
using System.Linq; | |
using Travix.AirFareDomain; | |
using System.Collections; | |
using Newtonsoft.Json; | |
using System.IO; | |
namespace bq_schema_gen_dotnet | |
{ | |
public class SearchResult<TCriteria, TResponse> | |
{ | |
public TCriteria SearchCriteria { get; set; } | |
public TResponse Response { get; set; } | |
} | |
public class schema{ | |
public string name { get; set; } | |
public string type { get; set; } | |
public string mode { get; set; } | |
public schema[] fields { get; set; } | |
} | |
public class test{ | |
public string test1 { get; set; } | |
public int? test2 { get; set; } | |
public decimal[] test3 { get; set; } | |
public List<Point> test4 { get; set; } | |
public DateTime? test5 { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var sc = new List<schema>(); | |
var t = typeof(SearchResult<AirShopRequest, AirShopResponse>); | |
// var t = typeof(test); | |
var enums = new Dictionary<string, Dictionary<int, string>>(); | |
string enumMappingHandler(Type type){ | |
if(!enums.ContainsKey(type.FullName)) | |
enums.Add(type.FullName, Enum.GetValues(type).Cast<int>().ToDictionary(x => x,x => Enum.GetName(type, x))); | |
return "INTEGER"; | |
} | |
foreach(var pi in t.GetProperties()){ | |
sc.Add(GetSchema(pi, enumMappingHandler)); | |
} | |
File.WriteAllText("schema.json", JsonConvert.SerializeObject(sc,new JsonSerializerSettings{ | |
NullValueHandling = NullValueHandling.Ignore | |
})); | |
File.WriteAllText("enum-mapping.json", JsonConvert.SerializeObject(enums,new JsonSerializerSettings{ | |
NullValueHandling = NullValueHandling.Ignore | |
})); | |
Console.WriteLine("Hello World!"); | |
} | |
public static schema GetSchema(PropertyInfo pi, Func<Type, string> enumMappingHandler) | |
{ | |
var schema = new schema(); | |
var atype = pi.PropertyType; | |
schema.name = pi.Name; | |
if(pi.PropertyType.IsArray){ | |
schema.mode = "REPEATED"; | |
atype = pi.PropertyType.GetElementType(); | |
} | |
else if(atype.IsGenericType && typeof(IEnumerable).IsAssignableFrom(atype)){ | |
schema.mode = "REPEATED"; | |
atype = pi.PropertyType.GenericTypeArguments[0]; | |
} | |
if(typeIn(atype, typeof(string))){ | |
schema.type = "STRING"; | |
} | |
else if(atype.IsEnum){ | |
schema.type = enumMappingHandler(atype); | |
} | |
else if(typeIn(atype, typeof(int), typeof(int?))){ | |
schema.type = "INTEGER"; | |
} | |
else if(typeIn(atype, typeof(decimal), typeof(decimal?), typeof(float), typeof(float?))){ | |
schema.type = "FLOAT"; | |
} | |
else if(typeIn(atype, typeof(bool), typeof(bool?))){ | |
schema.type = "BOOLEAN"; | |
} | |
else if(typeIn(atype, typeof(DateTime), typeof(DateTime?))){ | |
schema.type = "TIMESTAMP"; | |
} else { | |
schema.type = "RECORD"; | |
schema.fields = atype.GetProperties().Select(x => GetSchema(x, enumMappingHandler)).ToArray(); | |
} | |
return schema; | |
} | |
private static bool typeIn(Type t, params Type[] types){ | |
return types.Contains(t); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment