static string InnerBuildCSharpClass(string className, IList <TableFieldSchema> fields, Dictionary <string, string> innerClasses, DuplicateNamingStorage namingStorage) { var props = fields.Select(x => { var name = NameConverter.ConvertSafeName(x.Name); var type = ToCSharpType(name, x.Type, x.Mode); if (x.Type == "RECORD") { var innerStoreCount = namingStorage.StoreName(name); var newName = name; if (innerStoreCount != -1) { newName += "__" + innerStoreCount; } type = newName; innerClasses[newName] = InnerBuildCSharpClass(newName, x.Fields, innerClasses, namingStorage); } return($" [ColumnName(\"{x.Name}\")]public {type} {name} {{ get; set; }}"); }); var format = @"public class {0} {{ {1} }}"; var result = string.Format(format, className, string.Join(Environment.NewLine, props)); return(result); }
public string ToClassName(bool outTablePrefixClassIfMatched) { var className = NameConverter.ConvertSafeName(TableInfo.table_id); var regex = new Regex(@"\d{8}]$"); var fullname = TableInfo.ToFullTableName(); if (outTablePrefixClassIfMatched && regex.IsMatch(fullname)) { className = regex.Replace(className + "]", "").TrimEnd('_', ']'); } return(className); }
/// <summary> /// not flatten nested table. /// </summary> public BuildCodeResult[] BuildCSharpClasses(bool outTablePrefixClassIfMatched = false, DuplicateNamingStorage namingStorage = null) { if (namingStorage == null) { namingStorage = new DuplicateNamingStorage(); } var innerClasses = new Dictionary <string, string>(); var props = Fields.Select(x => { var name = NameConverter.ConvertSafeName(x.Name); var type = ToCSharpType(name, x.Type, x.Mode); if (x.Type == "RECORD") { var innerStoreCount = namingStorage.StoreName(name); var newName = name; if (innerStoreCount != -1) { newName += "__" + innerStoreCount; } type = newName; innerClasses[newName] = InnerBuildCSharpClass(newName, x.Fields, innerClasses, namingStorage); } return($" [ColumnName(\"{x.Name}\")]public {type} {name} {{ get; set; }}"); }); var className = NameConverter.ConvertSafeName(TableInfo.table_id); var regex = new Regex(@"\d{8}]$"); var fullname = TableInfo.ToFullTableName(); bool isTable; string attr; if (outTablePrefixClassIfMatched && regex.IsMatch(fullname)) { isTable = false; attr = $"[TablePrefix(\"{regex.Replace(fullname, "]")}\")]"; className = regex.Replace(className + "]", "").TrimEnd('_', ']'); } else { isTable = true; attr = $"[TableName(\"{fullname}\")]"; } // already stored, incr naming var storeCount = namingStorage.StoreName(className); if (storeCount != -1) { className += "__" + storeCount; } var format = @"{0}{3}public class {1}{3}{{{3}{2}{3}}}"; var result = string.Format(format, attr, className, string.Join(Environment.NewLine, props), Environment.NewLine); return(new[] { new BuildCodeResult { ClassName = className, Code = result, IsTableName = isTable, IsTablePrefix = !isTable, MetaTableSchema = this } } .Concat(innerClasses.Select(x => new BuildCodeResult { ClassName = x.Key, Code = x.Value, IsRecordClass = true })) .ToArray()); }
// return namespaces public string[] CompileTo(AssemblyName assemblyToBuild, string namespaceName, out BuildCodeResult[] generatedBuildCodes) { var namespaces = new List <string>(); var generatedCodes = new List <BuildCodeResult>(); var code = new StringBuilder(); code.AppendLine("using System;"); code.AppendLine("using System.IO;"); code.AppendLine("using System.Text;"); code.AppendLine("using System.Linq;"); code.AppendLine("using System.Collections;"); code.AppendLine("using System.Collections.Generic;"); code.AppendLine("using System.Windows.Forms.DataVisualization.Charting;"); code.AppendLine("using System.Threading;"); code.AppendLine("using Google.Apis.Auth.OAuth2;"); code.AppendLine("using Google.Apis.Bigquery.v2;"); code.AppendLine("using Google.Apis.Services;"); code.AppendLine("using Google.Apis.Util.Store;"); code.AppendLine("using BigQuery.Linq;"); code.Append(BuildCustomContext(namespaceName)); foreach (var schema in Schemas.Where(x => x.GroupedMetaTableSchemas.Any())) { var namingStoragePerDataset = new DuplicateNamingStorage(); var tableCodes = schema.GroupedMetaTableSchemas .SelectMany(x => { var concat = Enumerable.Empty <BuildCodeResult[]>(); if (x.IsGrouped) { var f = x.MetaTableSchemas.First(); concat = new[] { f.BuildCSharpClasses(outTablePrefixClassIfMatched: true, namingStorage: namingStoragePerDataset) }; } return(concat.Concat(x.MetaTableSchemas.Select(y => y.BuildCSharpClasses(outTablePrefixClassIfMatched: false, namingStorage: namingStoragePerDataset)))); }) .SelectMany(xs => xs) .Distinct(x => x.ClassName) .ToArray(); var typeCode = string.Join(Environment.NewLine + Environment.NewLine, tableCodes.Select(x => x.Code)); var template = $@" namespace {namespaceName}.{NameConverter.ConvertSafeName(schema.DatasetName)} {{ {typeCode} }}"; code.Append(template); namespaces.Add($"{namespaceName}.{NameConverter.ConvertSafeName(schema.DatasetName)}"); generatedCodes.AddRange(tableCodes); } CompilerResults results; using (var codeProvider = new CSharpCodeProvider(new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } })) { var options = new CompilerParameters( new[] { "mscorlib.dll", "System.dll", "System.Core.dll", "System.Xml.dll", "System.Data.dll", "System.Windows.Forms.dll", "System.Windows.Forms.DataVisualization.dll", typeof(LINQPad.DataContextBase).Assembly.Location, typeof(BigQueryContext).Assembly.Location, typeof(BigqueryService).Assembly.Location, typeof(GoogleWebAuthorizationBroker).Assembly.Location, typeof(BaseClientService).Assembly.Location, typeof(Google.GoogleApiException).Assembly.Location, typeof(Google.Apis.Auth.JsonWebToken).Assembly.Location, typeof(FileDataStore).Assembly.Location }.Distinct().ToArray(), assemblyToBuild.CodeBase, true); results = codeProvider.CompileAssemblyFromSource(options, code.ToString()); } if (results.Errors.Count > 0) { throw new Exception ("Cannot compile typed context: " + results.Errors[0].ErrorText + " (line " + results.Errors[0].Line + ")"); } generatedBuildCodes = generatedCodes.ToArray(); return(namespaces.ToArray()); }