Ejemplo n.º 1
0
    void GenerateProperty(CodegenOutputFile writer, Table table, Column column)
    {
        string propertyName    = GetPropertyNameForDatabaseColumn(table, column.ColumnName);
        string privateVariable = $"_{propertyName.Substring(0, 1).ToLower()}{propertyName.Substring(1)}";

        if (TrackPropertiesChange)
        {
            writer.WriteLine($"private {GetTypeDefinitionForDatabaseColumn(table, column) ?? ""} {privateVariable};");
        }
        if (column.IsPrimaryKeyMember)
        {
            writer.WriteLine("[Key]");
        }
        // We'll decorate [Column("Name")] only if column name doesn't match property name
        if (propertyName.ToLower() != column.ColumnName.ToLower())
        {
            writer.WriteLine($"[Column(\"{column.ColumnName}\")]");
        }
        if (TrackPropertiesChange)
        {
            writer.WriteLine($@"
                public {GetTypeDefinitionForDatabaseColumn(table, column) ?? ""} {propertyName} 
                {{ 
                    get {{ return {privateVariable}; }} 
                    set {{ SetField(ref {privateVariable}, value, nameof({propertyName})); }} 
                }}");
        }
        else
        {
            writer.WriteLine($"public {GetTypeDefinitionForDatabaseColumn(table, column) ?? ""} {propertyName} {{ get; set; }}");
        }
    }
Ejemplo n.º 2
0
 void GenerateSave(CodegenOutputFile writer, Table table)
 {
     writer.WithCBlock("public void Save()", () =>
     {
         var pkCols = table.Columns
                      .Where(c => ShouldProcessColumn(table, c))
                      .Where(c => c.IsPrimaryKeyMember).OrderBy(c => c.OrdinalPosition);
         writer.WriteLine($@"
             if ({string.Join(" && ", pkCols.Select(col => GetPropertyNameForDatabaseColumn(table, col.ColumnName) + $" == {GetDefaultValue(GetTypeForDatabaseColumn(table, col))}"))})
                 Insert();
             else
                 Update();");
     });
 }
Ejemplo n.º 3
0
    void GenerateProperty(CodegenOutputFile writer, Table table, Column column)
    {
        string propertyName = GetPropertyNameForDatabaseColumn(table, column.ColumnName);

        if (column.IsPrimaryKeyMember)
        {
            writer.WriteLine("[Key]");
        }
        // We'll decorate [Column("Name")] only if column name doesn't match property name
        if (propertyName.ToLower() != column.ColumnName.ToLower())
        {
            writer.WriteLine($"[Column(\"{column.ColumnName}\")]");
        }
        writer.WriteLine($"public {GetTypeDefinitionForDatabaseColumn(table, column) ?? ""} {propertyName} {{ get; set; }}");
    }
Ejemplo n.º 4
0
 void GenerateActiveRecordInsert(CodegenOutputFile writer, Table table)
 {
     writer.WithCBlock("public void Insert()", () =>
     {
         writer.WithCBlock("using (var conn = IDbConnectionFactory.CreateConnection())", () =>
         {
             var cols = table.Columns
                        .Where(c => ShouldProcessColumn(table, c))
                        .Where(c => !c.IsIdentity)
                        .Where(c => !c.IsRowGuid)  //TODO: should be used only if they have value set (not default value)
                        .Where(c => !c.IsComputed) //TODO: should be used only if they have value set (not default value)
                        .OrderBy(c => GetPropertyNameForDatabaseColumn(table, c.ColumnName));
             writer.WithIndent($"string cmd = @\"{Environment.NewLine}INSERT INTO {(table.TableSchema == "dbo" ? "" : $"[{table.TableSchema}].")}[{table.TableName}]{Environment.NewLine}(", ")", () =>
             {
                 writer.WriteLine(string.Join($",{Environment.NewLine}", cols.Select(col => $"[{col.ColumnName}]")));
             });
Ejemplo n.º 5
0
 void GenerateInsert(CodegenOutputFile writer, Table table)
 {
     //TODO: IDbConnection cn, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?), bool logChange = true, bool logError = true
     writer.WithCBlock("public void Insert()", () =>
     {
         writer.WithCBlock("using (var conn = IDbConnectionFactory.CreateConnection())", () =>
         {
             var cols = table.Columns
                        .Where(c => ShouldProcessColumn(table, c))
                        .Where(c => !c.IsIdentity)
                        .Where(c => !c.IsRowGuid)  //TODO: should be used only if they have value set (not default value)
                        .Where(c => !c.IsComputed) //TODO: should be used only if they have value set (not default value)
                        .OrderBy(c => GetPropertyNameForDatabaseColumn(table, c.ColumnName));
             writer.WithIndent($"string cmd = @\"{Environment.NewLine}INSERT INTO {(table.TableSchema == "dbo" ? "" : $"[{table.TableSchema}].")}[{table.TableName}]{Environment.NewLine}(", ")", () =>
             {
                 writer.WriteLine(string.Join($",{Environment.NewLine}", cols.Select(col => $"[{col.ColumnName}]")));
             });
Ejemplo n.º 6
0
 void GenerateCrudExtensionsSave(CodegenOutputFile writer, Table table)
 {
     writer.WriteLine(@"
         /// <summary>
         /// Saves (if new) or Updates (if existing)
         /// </summary>");
     writer.WithCBlock($"public static void Save(this IDbConnection conn, {GetClassNameForTable(table)} e, IDbTransaction transaction = null, int? commandTimeout = null)", () =>
     {
         var pkCols = table.Columns
                      .Where(c => ShouldProcessColumn(table, c))
                      .Where(c => c.IsPrimaryKeyMember).OrderBy(c => c.OrdinalPosition);
         writer.WriteLine($@"
             if ({string.Join(" && ", pkCols.Select(col => "e." + GetPropertyNameForDatabaseColumn(table, col.ColumnName) + $" == {GetDefaultValue(GetTypeForDatabaseColumn(table, col))}"))})
                 conn.Insert(e, transaction, commandTimeout);
             else
                 conn.Update(e, transaction, commandTimeout);");
     });
 }
Ejemplo n.º 7
0
    /// <summary>
    /// Generates POCOS
    /// </summary>
    /// <param name="targetFolder">Absolute path of the target folder where files will be written</param>
    public void Generate(string targetFolder)
    {
        Console.WriteLine($"TargetFolder: {targetFolder}");

        _generatorContext = new CodegenContext();

        Console.WriteLine("Reading Schema...");

        LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(_inputJsonSchema));
        //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>();

        CodegenOutputFile writer = null;

        if (SingleFile)
        {
            writer = _generatorContext[singleFileName];
            writer
            .WriteLine(@"using System;")
            .WriteLine(@"using System.Collections.Generic;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;")
            .WriteLine(@"using System.Linq;");
            if (GenerateActiveRecord)
            {
                writer.WriteLine(@"using Dapper;");
            }
            writer
            .WriteLine()
            .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent();
        }

        if (GenerateActiveRecord)
        {
            using (var writerConnectionFactory = _generatorContext["..\\IDbConnectionFactory.cs"])
            {
                writerConnectionFactory.WriteLine($@"
                    using System;
                    using System.Data;
                    using System.Data.SqlClient;

                    namespace {Namespace}
                    {{
                        public class IDbConnectionFactory
                        {{
                            public static IDbConnection CreateConnection()
                            {{
                                string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS;
                                                Initial Catalog=AdventureWorks;
                                                Integrated Security=True;"";

                                return new SqlConnection(connectionString);
                            }}
                        }}
                    }}
                ");
            }
        }

        foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t)))
        {
            if (table.TableType == "VIEW")
            {
                continue;
            }

            GeneratePOCO(table);
        }

        if (SingleFile)
        {
            writer.DecreaseIndent().WriteLine("}"); // end of namespace
        }
        // since no errors happened, let's save all files
        _generatorContext.SaveFiles(outputFolder: targetFolder);

        Console.WriteLine("Success!");
    }
Ejemplo n.º 8
0
    void GeneratePOCO(Table table)
    {
        Console.WriteLine($"Generating {table.TableName}...");

        CodegenOutputFile writer = null;

        if (SingleFile)
        {
            writer = _generatorContext[singleFileName];
        }
        else
        {
            writer = _generatorContext[GetFileNameForTable(table)];
            writer
            .WriteLine(@"using System;")
            .WriteLine(@"using System.Collections.Generic;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;")
            .WriteLine(@"using System.Linq;");
            if (GenerateActiveRecord)
            {
                writer.WriteLine(@"using Dapper;");
            }
            writer
            .WriteLine()
            .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent();
        }

        string entityClassName = GetClassNameForTable(table);

        // We'll decorate [Table("Name")] only if schema not default or if table name doesn't match entity name
        if (table.TableSchema != "dbo") //TODO or table different than clas name?
        {
            writer.WriteLine($"[Table(\"{table.TableName}\", Schema = \"{table.TableSchema}\")]");
        }
        else if (entityClassName.ToLower() != table.TableName.ToLower())
        {
            writer.WriteLine($"[Table(\"{table.TableName}\")]");
        }

        writer.WithCBlock($"public partial class {entityClassName}", () =>
        {
            writer.WriteLine("#region Members");
            var columns = table.Columns
                          .Where(c => ShouldProcessColumn(table, c))
                          .OrderBy(c => c.IsPrimaryKeyMember ? 0 : 1)
                          .ThenBy(c => c.IsPrimaryKeyMember ? c.OrdinalPosition : 0)           // respect PK order...
                          .ThenBy(c => GetPropertyNameForDatabaseColumn(table, c.ColumnName)); // but for other columns do alphabetically;

            foreach (var column in columns)
            {
                GenerateProperty(writer, table, column);
            }

            writer.WriteLine("#endregion Members");
            if (GenerateActiveRecord && table.TableType == "TABLE" && columns.Any(c => c.IsPrimaryKeyMember))
            {
                writer.WriteLine();
                writer.WriteLine("#region ActiveRecord");
                GenerateSave(writer, table);
                GenerateInsert(writer, table);
                GenerateUpdate(writer, table);
                writer.WriteLine("#endregion ActiveRecord");
            }
            if (GenerateEqualsHashCode)
            {
                writer.WriteLine();
                writer.WriteLine("#region Equals/GetHashCode");
                GenerateEquals(writer, table);
                GenerateGetHashCode(writer, table);
                GenerateInequalityOperatorOverloads(writer, table);
                writer.WriteLine("#endregion Equals/GetHashCode");
            }
        });

        if (!SingleFile)
        {
            writer.DecreaseIndent().WriteLine("}"); // end of namespace
        }
    }
Ejemplo n.º 9
0
    /// <summary>
    /// Generates POCOS
    /// </summary>
    public void Generate()
    {
        while (string.IsNullOrEmpty(InputJsonSchema))
        {
            Console.WriteLine($"[Choose an Input JSON Schema File]");
            Console.Write($"Input file: ");
            InputJsonSchema = Console.ReadLine();
        }

        while (string.IsNullOrEmpty(TargetFolder))
        {
            Console.WriteLine($"[Choose a Target Folder]");
            Console.Write($"Target Folder: ");
            TargetFolder = Console.ReadLine();
        }

        while (string.IsNullOrEmpty(Namespace))
        {
            Console.WriteLine($"[Choose a Namespace]");
            Console.Write($"Namespace: ");
            Namespace = Console.ReadLine();
        }


        _generatorContext = new CodegenContext();

        Console.WriteLine("Reading Schema...");

        LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(InputJsonSchema));
        //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>();

        CodegenOutputFile writer = null;

        if (SingleFile)
        {
            writer = _generatorContext[singleFileName];
            writer
            .WriteLine(@"using System;")
            .WriteLine(@"using System.Collections.Generic;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;")
            .WriteLine(@"using System.Linq;");
            if (GenerateActiveRecord)
            {
                writer.WriteLine(@"using Dapper;");
            }
            if (TrackPropertiesChange)
            {
                writer.WriteLine(@"using System.ComponentModel;");
            }
            writer
            .WriteLine()
            .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent();
        }

        if (GenerateCrudExtensions)
        {
            _dbConnectionCrudExtensions = _generatorContext[CrudExtensionsFile];
            _dbConnectionCrudExtensions.Write(@"
                using Dapper;
                using System;
                using System.Collections.Generic;
                using System.Data;
                using System.Linq;
                using System.Runtime.CompilerServices;
                ");
            _dbConnectionCrudExtensions
            .WriteLine()
            .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent()
            .WriteLine($"public static class {CrudExtensionsClass}").WriteLine("{").IncreaseIndent();
        }

        if (GenerateActiveRecord)
        {
            using (var writerConnectionFactory = _generatorContext[ActiveRecordIDbConnectionFactoryFile])
            {
                writerConnectionFactory.WriteLine($@"
                    using System;
                    using System.Data;
                    using System.Data.SqlClient;

                    namespace {Namespace}
                    {{
                        public class IDbConnectionFactory
                        {{
                            public static IDbConnection CreateConnection()
                            {{
                                string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS;
                                                Initial Catalog=AdventureWorks;
                                                Integrated Security=True;"";

                                return new SqlConnection(connectionString);
                            }}
                        }}
                    }}
                ");
            }
        }

        foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t)))
        {
            if (!ShouldProcessTable(table))
            {
                continue;
            }

            GeneratePOCO(table);
        }

        if (GenerateCrudExtensions)
        {
            _dbConnectionCrudExtensions
            .DecreaseIndent().WriteLine("}")         // end of class
            .DecreaseIndent().WriteLine("}");        // end of namespace
        }
        if (SingleFile)
        {
            writer.DecreaseIndent().WriteLine("}");     // end of namespace
        }
        // since no errors happened, let's save all files
        _generatorContext.SaveFiles(outputFolder: TargetFolder);

        Console.WriteLine("Success!");
    }
Ejemplo n.º 10
0
    void GeneratePOCO(Table table)
    {
        Console.WriteLine($"Generating {table.TableName}...");

        CodegenOutputFile writer = null;

        if (SingleFile)
        {
            writer = _generatorContext[singleFileName];
        }
        else
        {
            writer = _generatorContext[GetFileNameForTable(table)];
            writer
            .WriteLine(@"using System;")
            .WriteLine(@"using System.Collections.Generic;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations;")
            .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;")
            .WriteLine(@"using System.Linq;");
            if (GenerateActiveRecord)
            {
                writer.WriteLine(@"using Dapper;");
            }
            if (TrackPropertiesChange)
            {
                writer.WriteLine(@"using System.ComponentModel;");
            }
            writer
            .WriteLine()
            .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent();
        }

        string entityClassName = GetClassNameForTable(table);

        // We'll decorate [Table("Name")] only if schema not default or if table name doesn't match entity name
        if (table.TableSchema != "dbo")     //TODO or table different than clas name?
        {
            writer.WriteLine($"[Table(\"{table.TableName}\", Schema = \"{table.TableSchema}\")]");
        }
        else if (entityClassName.ToLower() != table.TableName.ToLower())
        {
            writer.WriteLine($"[Table(\"{table.TableName}\")]");
        }

        List <string> baseClasses = new List <string>();

        if (TrackPropertiesChange)
        {
            baseClasses.Add("INotifyPropertyChanged");
        }

        writer.WithCBlock($"public partial class {entityClassName}{(baseClasses.Any() ? " : " + string.Join(", ", baseClasses) : "")}", () =>
        {
            writer.WriteLine("#region Members");
            var columns = table.Columns
                          .Where(c => ShouldProcessColumn(table, c))
                          .OrderBy(c => c.IsPrimaryKeyMember ? 0 : 1)
                          .ThenBy(c => c.IsPrimaryKeyMember ? c.OrdinalPosition : 0)           // respect PK order...
                          .ThenBy(c => GetPropertyNameForDatabaseColumn(table, c.ColumnName)); // but for other columns do alphabetically;

            foreach (var column in columns)
            {
                GenerateProperty(writer, table, column);
            }

            writer.WriteLine("#endregion Members");
            if (table.TableType == "TABLE" && columns.Any(c => c.IsPrimaryKeyMember))
            {
                if (GenerateActiveRecord)
                {
                    writer.WriteLine();
                    writer.WriteLine("#region ActiveRecord");
                    GenerateActiveRecordSave(writer, table);
                    GenerateActiveRecordInsert(writer, table);
                    GenerateActiveRecordUpdate(writer, table);
                    writer.WriteLine("#endregion ActiveRecord");
                }
                if (GenerateCrudExtensions)
                {
                    _dbConnectionCrudExtensions.WriteLine();
                    _dbConnectionCrudExtensions.WriteLine($"#region {GetClassNameForTable(table)}");
                    GenerateCrudExtensionsSave(_dbConnectionCrudExtensions, table);
                    GenerateCrudExtensionsInsert(_dbConnectionCrudExtensions, table);
                    GenerateCrudExtensionsUpdate(_dbConnectionCrudExtensions, table);
                    _dbConnectionCrudExtensions.WriteLine($"#endregion {GetClassNameForTable(table)}");
                }
            }
            if (GenerateEqualsHashCode)
            {
                writer.WriteLine();
                writer.WriteLine("#region Equals/GetHashCode");
                GenerateEquals(writer, table);
                GenerateGetHashCode(writer, table);
                GenerateInequalityOperatorOverloads(writer, table);
                writer.WriteLine("#endregion Equals/GetHashCode");
            }

            if (TrackPropertiesChange)
            {
                writer.WriteLine();
                writer.WriteLine("#region INotifyPropertyChanged/IsDirty");
                writer.WriteLine(@"
                        public HashSet<string> ChangedProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                        public void MarkAsClean()
                        {
                            ChangedProperties.Clear();
                        }
                        public virtual bool IsDirty => ChangedProperties.Any();

                        public event PropertyChangedEventHandler PropertyChanged;
                        protected void SetField<T>(ref T field, T value, string propertyName) {
                            if (!EqualityComparer<T>.Default.Equals(field, value)) {
                                field = value;
                                ChangedProperties.Add(propertyName);
                                OnPropertyChanged(propertyName);
                            }
                        }
                        protected virtual void OnPropertyChanged(string propertyName) {
                            if (PropertyChanged != null) {
                                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                            }
                        }");
                writer.WriteLine("#endregion INotifyPropertyChanged/IsDirty");
            }
        });

        if (!SingleFile)
        {
            writer.DecreaseIndent().WriteLine("}");     // end of namespace
        }
    }