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;
        }
        // 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();
        }
        /// <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 = x.Name;
                if (ReservedIdentifiers.Contains(name))
                {
                    name = "@" + 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 = TableInfo.table_id;

            if (Regex.IsMatch(className, "^[0123456789]"))
            {
                className = "_" + className;
            }
            if (ReservedIdentifiers.Contains(className))
            {
                className = "@" + className;
            }

            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}
public class {1}
{{
{2}
}}";
            var result = string.Format(format, attr, className, string.Join(Environment.NewLine, props));

            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());
        }
        static string InnerBuildCSharpClass(string className, IList <TableFieldSchema> fields, Dictionary <string, string> innerClasses, DuplicateNamingStorage namingStorage)
        {
            var props = fields.Select(x =>
            {
                var name = x.Name;
                if (ReservedIdentifiers.Contains(name))
                {
                    name = "@" + 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);
        }
Example #5
0
        // 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}.@{schema.DatasetName.Replace("-", "_").Replace(":", "_")}
{{
{typeCode}
}}";

                code.Append(template);
                namespaces.Add($"{namespaceName}.@{schema.DatasetName.Replace("-", "_").Replace(":", "_")}");
                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());
        }
        /// <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();
        }