├── .gitignore ├── CSharp ├── App.config ├── CSharp.csproj ├── Data Access - Delete Method.ttinclude ├── Data Access - Insert Method.ttinclude ├── Data Access - Merge Method.ttinclude ├── Data Access - Select Method.ttinclude ├── Data Access - Stored Procedure - Multiple Result Sets.ttinclude ├── Data Access - Stored Procedure - No Result Set.ttinclude ├── Data Access - Stored Procedure - Single Result Set.ttinclude ├── Data Access - Update Method.ttinclude ├── Data Access Classes.ttinclude ├── Entity Classes.ttinclude ├── Main.tt ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── UNLICENSE.txt └── Utilities.ttinclude ├── FSharp ├── App.config ├── Data Access Classes.ttinclude ├── Entity Classes.ttinclude ├── FSharp.fsproj ├── Main.tt ├── Program.fs └── UNLICENSE.txt ├── README.md ├── SQL ├── App.config ├── Delete.ttinclude ├── Insert.ttinclude ├── Main.tt ├── Merge (Insert and Update).ttinclude ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── SQL.csproj ├── Select.ttinclude ├── UNLICENSE.txt ├── Update.ttinclude └── User-Defined Table Type.ttinclude ├── T4_SQL_Examples.sln ├── T4_Utilities ├── App.config ├── Program.cs ├── SQL Generator Utilities.ttinclude ├── T4_Utilities.csproj └── UNLICENSE.txt ├── UNLICENSE.txt └── Visual_Basic ├── App.config ├── Data Access Classes.ttinclude ├── Entity Classes.ttinclude ├── Main.tt ├── Module1.vb ├── My Project ├── Application.Designer.vb ├── Application.myapp ├── AssemblyInfo.vb ├── Resources.Designer.vb ├── Resources.resx ├── Settings.Designer.vb └── Settings.settings ├── UNLICENSE.txt └── Visual_Basic.vbproj /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | *.vs 16 | 17 | Main.txt 18 | Output/ 19 | Stored Procedures/ 20 | 21 | 22 | # Build results 23 | [Dd]ebug/ 24 | [Rr]elease/ 25 | x64/ 26 | *_i.c 27 | *_p.c 28 | *.ilk 29 | *.meta 30 | *.obj 31 | *.pch 32 | *.pdb 33 | *.pgc 34 | *.pgd 35 | *.rsp 36 | *.sbr 37 | *.tlb 38 | *.tli 39 | *.tlh 40 | *.tmp 41 | *.log 42 | *.vspscc 43 | *.vssscc 44 | .builds 45 | 46 | # Visual C++ cache files 47 | ipch/ 48 | *.aps 49 | *.ncb 50 | *.opensdf 51 | *.sdf 52 | 53 | # Visual Studio profiler 54 | *.psess 55 | *.vsp 56 | *.vspx 57 | 58 | # Guidance Automation Toolkit 59 | *.gpState 60 | 61 | # ReSharper is a .NET coding add-in 62 | _ReSharper* 63 | 64 | # NCrunch 65 | *.ncrunch* 66 | .*crunch*.local.xml 67 | 68 | # Installshield output folder 69 | [Ee]xpress 70 | 71 | # DocProject is a documentation generator add-in 72 | DocProject/buildhelp/ 73 | DocProject/Help/*.HxT 74 | DocProject/Help/*.HxC 75 | DocProject/Help/*.hhc 76 | DocProject/Help/*.hhk 77 | DocProject/Help/*.hhp 78 | DocProject/Help/Html2 79 | DocProject/Help/html 80 | 81 | # Click-Once directory 82 | publish 83 | 84 | # Publish Web Output 85 | *.Publish.xml 86 | 87 | # NuGet Packages Directory 88 | packages 89 | 90 | # Windows Azure Build Output 91 | csx 92 | *.build.csdef 93 | 94 | # Windows Store app package directory 95 | AppPackages/ 96 | 97 | # Others 98 | [Bb]in 99 | [Oo]bj 100 | TestResults 101 | [Tt]est[Rr]esult* 102 | *.Cache 103 | ClientBin 104 | [Ss]tyle[Cc]op.* 105 | ~$* 106 | *.dbmdl 107 | Generated_Code #added for RIA/Silverlight projects 108 | 109 | # Backup & report files from converting an old project file to a newer 110 | # Visual Studio version. Backup files are not needed, because we have git ;-) 111 | _UpgradeReport_Files/ 112 | Backup*/ 113 | UpgradeLog*.XML 114 | -------------------------------------------------------------------------------- /CSharp/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CSharp/CSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {87B5420A-9AD3-492A-B3C7-A5F307B90288} 8 | Exe 9 | Properties 10 | CSharp 11 | CSharp 12 | v4.7.2 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | False 42 | ..\..\..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Types.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | ..\..\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll 54 | 55 | 56 | ..\..\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | TextTemplatingFileGenerator 69 | Main.txt 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | True 87 | True 88 | Main.tt 89 | 90 | 91 | 92 | 99 | -------------------------------------------------------------------------------- /CSharp/Data Access - Delete Method.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteDeleteMethod(Database database, Table table) 3 | { 4 | #> 5 | public static void Delete<#= table.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), this.GetMethodParameters(table, ColumnType.PrimaryKey)); 9 | #> 10 | ) 11 | { 12 | using (var connection = new SqlConnection(_connectionString)) 13 | { 14 | connection.Open(); 15 | 16 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Delete") #>" }) 17 | { 18 | command.Parameters.Clear(); 19 | <#+ 20 | this.PushWritePop(_standardIndent.Repeat(3), this.GetSqlCommandParameters(table, ColumnType.PrimaryKey)); 21 | #> 22 | command.ExecuteNonQuery(); 23 | } 24 | } 25 | } 26 | 27 | <#+ 28 | } 29 | #> 30 | -------------------------------------------------------------------------------- /CSharp/Data Access - Insert Method.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteInsertMethod(Database database, Table table) 3 | { 4 | #> 5 | public static void Insert<#= table.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), this.GetMethodParameters(table, ColumnType.CanAppearInInsertStatement)); 9 | #> 10 | ) 11 | { 12 | using (var connection = new SqlConnection(_connectionString)) 13 | { 14 | connection.Open(); 15 | 16 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Insert") #>" }) 17 | { 18 | command.Parameters.Clear(); 19 | <#+ 20 | this.PushWritePop(_standardIndent.Repeat(3), this.GetSqlCommandParameters(table, ColumnType.CanAppearInInsertStatement)); 21 | #> 22 | command.ExecuteNonQuery(); 23 | } 24 | } 25 | } 26 | 27 | <#+ 28 | } 29 | #> 30 | -------------------------------------------------------------------------------- /CSharp/Data Access - Merge Method.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteMergeMethod(Database database, Table table) 3 | { 4 | #> 5 | public static void Merge<#= table.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), this.GetMethodParameters(table, ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList)); 9 | #> 10 | ) 11 | { 12 | using (var connection = new SqlConnection(_connectionString)) 13 | { 14 | connection.Open(); 15 | 16 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Merge") #>" }) 17 | { 18 | command.Parameters.Clear(); 19 | <#+ 20 | this.PushWritePop(_standardIndent.Repeat(3), this.GetSqlCommandParameters(table, ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList)); 21 | #> 22 | command.ExecuteNonQuery(); 23 | } 24 | } 25 | } 26 | 27 | <#+ 28 | } 29 | #> 30 | -------------------------------------------------------------------------------- /CSharp/Data Access - Select Method.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteSelectMethod(Database database, Table table) 3 | { 4 | #> 5 | public static List<<#= table.TargetLanguageIdentifier #>> Select<#= table.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), this.GetMethodParameters(table, ColumnType.PrimaryKey)); 9 | #> 10 | ) 11 | { 12 | var result = new List<<#= table.TargetLanguageIdentifier #>>(); 13 | 14 | using (var connection = new SqlConnection(_connectionString)) 15 | { 16 | connection.Open(); 17 | 18 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Select") #>" }) 19 | { 20 | command.Parameters.Clear(); 21 | <#+ 22 | this.PushWritePop(_standardIndent.Repeat(3), this.GetSqlCommandParameters(table, ColumnType.PrimaryKey)); 23 | #> 24 | 25 | using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 26 | { 27 | while (reader.Read()) 28 | { 29 | result.Add( 30 | new <#= table.TargetLanguageIdentifier #>() 31 | { 32 | <#+ 33 | this.PushWritePop(_standardIndent.Repeat(7), this.GetSqlCommandReaderAssigments(table.Columns)); 34 | #> 35 | }); 36 | } 37 | } 38 | 39 | return result; 40 | } 41 | } 42 | } 43 | 44 | <#+ 45 | } 46 | #> -------------------------------------------------------------------------------- /CSharp/Data Access - Stored Procedure - Multiple Result Sets.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteStoredProcedureMultipleResultSetsMethod(StoredProcedure storedProcedure) 3 | { 4 | #> 5 | public static <#= storedProcedure.TargetLanguageIdentifier + "_AllResultSets" #> Select<#= storedProcedure.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), storedProcedure.GetTargetLanguageMethodParameterNameAndTypes().Join("," + Environment.NewLine)); 9 | #> 10 | ) 11 | { 12 | var result = new <#= storedProcedure.TargetLanguageIdentifier + "_AllResultSets" #>(); 13 | 14 | using (var connection = new SqlConnection(_connectionString)) 15 | { 16 | connection.Open(); 17 | 18 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= storedProcedure.SqlIdentifier #>" }) 19 | { 20 | command.Parameters.Clear(); 21 | <#+ 22 | if (storedProcedure.SqlParameters.Any()) 23 | { 24 | this.PushWritePop(_standardIndent.Repeat(3), 25 | storedProcedure 26 | .SqlParameters 27 | .Select(p => String.Format("command.Parameters.Add({0});", ReflectionUtils.GetObjectInitializer(p, "DbType", "SqlValue"))) 28 | .Join()); 29 | } 30 | #> 31 | 32 | using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 33 | { 34 | <#+ 35 | var join = @" 36 | 37 | reader.NextResult();"; 38 | 39 | this.PushWritePop(_standardIndent.Repeat(3), 40 | storedProcedure 41 | .ResultSets 42 | .Select(cs => String.Format(@" 43 | while (reader.Read()) 44 | {{ 45 | result.{0} = 46 | new {0}() 47 | {{ 48 | {1} 49 | }}); 50 | }}", 51 | storedProcedure.TargetLanguageIdentifier, 52 | cs 53 | .OrderBy(column => column.Name) 54 | .Select(column => String.Format("{0} = {1}", column.TargetLanguageIdentifier, column.GetTargetLanguageDataReaderExpression("reader"))))) 55 | .Join(join)); 56 | #> 57 | } 58 | 59 | return result; 60 | } 61 | } 62 | } 63 | <#+ 64 | } 65 | #> 66 | -------------------------------------------------------------------------------- /CSharp/Data Access - Stored Procedure - No Result Set.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteStoredProcedureNoResultSetMethod(StoredProcedure storedProcedure) 3 | { 4 | #> 5 | <#+ 6 | } 7 | #> 8 | -------------------------------------------------------------------------------- /CSharp/Data Access - Stored Procedure - Single Result Set.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteStoredProcedureSingleResultSetMethod(StoredProcedure storedProcedure) 3 | { 4 | #> 5 | public static IEnumerable<<#= storedProcedure.TargetLanguageIdentifier #>> Select<#= storedProcedure.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), storedProcedure.GetTargetLanguageMethodParameterNameAndTypes().Join("," + Environment.NewLine)); 9 | #> 10 | ) 11 | { 12 | var result = new List<<#= storedProcedure.TargetLanguageIdentifier #>>(); 13 | 14 | using (var connection = new SqlConnection(_connectionString)) 15 | { 16 | connection.Open(); 17 | 18 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= storedProcedure.SqlIdentifier #>" }) 19 | { 20 | command.Parameters.Clear(); 21 | <#+ 22 | if (storedProcedure.SqlParameters.Any()) 23 | { 24 | this.PushWritePop(_standardIndent.Repeat(3), 25 | storedProcedure 26 | .SqlParameters 27 | .Select(p => String.Format("command.Parameters.Add({0});", FixupSqlParameterValue(p))) 28 | .Join()); 29 | } 30 | #> 31 | 32 | using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 33 | { 34 | while (reader.Read()) 35 | { 36 | result.Add( 37 | new <#= storedProcedure.TargetLanguageIdentifier #>() 38 | { 39 | <#+ 40 | this.PushWritePop(_standardIndent.Repeat(7), this.GetSqlCommandReaderAssigments(storedProcedure.ResultSets.First())); 41 | #> 42 | }); 43 | } 44 | } 45 | 46 | return result; 47 | } 48 | } 49 | } 50 | 51 | <#+ 52 | } 53 | #> 54 | -------------------------------------------------------------------------------- /CSharp/Data Access - Update Method.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | private void WriteUpdateMethod(Database database, Table table) 3 | { 4 | #> 5 | public static void Update<#= table.TargetLanguageIdentifier #> 6 | ( 7 | <#+ 8 | this.PushWritePop(_standardIndent.Repeat(2), this.GetMethodParameters(table, ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause)); 9 | #> 10 | ) 11 | { 12 | using (var connection = new SqlConnection(_connectionString)) 13 | { 14 | connection.Open(); 15 | 16 | using (var command = new SqlCommand() { Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Update") #>" }) 17 | { 18 | command.Parameters.Clear(); 19 | <#+ 20 | this.PushWritePop(_standardIndent.Repeat(3), this.GetSqlCommandParameters(table, ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause)); 21 | #> 22 | command.ExecuteNonQuery(); 23 | } 24 | } 25 | } 26 | 27 | <#+ 28 | } 29 | #> 30 | -------------------------------------------------------------------------------- /CSharp/Data Access Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateDataAccessClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = database.TargetLanguageIdentifier + ".DataLayer"; 8 | 9 | this.WriteDataAccessNamespaceHeader(database.TargetLanguageIdentifier + ".Entities", outputFilename); 10 | this.PushIndent(_standardIndent); 11 | 12 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 13 | { 14 | foreach (var table in schema.Tables.OrderBy(table => table.Name)) 15 | { 16 | this.WriteDataAccessClassHeader(table.TargetLanguageIdentifier + "_Methods", database.TargetLanguageIdentifier); 17 | this.PushIndent(_standardIndent); 18 | 19 | this.WriteSelectMethod(database, table); 20 | 21 | /* Views don't need insert, update and delete methods. */ 22 | if (!table.IsView) 23 | { 24 | this.WriteInsertMethod(database, table); 25 | this.WriteUpdateMethod(database, table); 26 | this.WriteMergeMethod(database, table); 27 | this.WriteDeleteMethod(database, table); 28 | } 29 | 30 | this.PopIndent(); 31 | this.WriteClosingBrace(); 32 | } // foreach table 33 | 34 | if (schema.StoredProcedures.Any()) 35 | { 36 | this.WriteDataAccessClassHeader(schema.Name + "_StoredProcedureMethods", database.TargetLanguageIdentifier); 37 | this.PushIndent(_standardIndent); 38 | 39 | foreach (var storedProcedure in schema.StoredProcedures.OrderBy(sp => sp.Name)) 40 | { 41 | if (storedProcedure.ResultSets.Count > 1) 42 | this.WriteStoredProcedureMultipleResultSetsMethod(storedProcedure); 43 | else if (storedProcedure.ResultSets.Count == 1) 44 | this.WriteStoredProcedureSingleResultSetMethod(storedProcedure); 45 | else 46 | this.WriteStoredProcedureNoResultSetMethod(storedProcedure); 47 | } 48 | 49 | this.PopIndent(); 50 | this.WriteClosingBrace(); 51 | this.WriteLine(""); 52 | } // if (schema.StoredProcedures.Any()) 53 | } // foreach schema 54 | 55 | this.PopIndent(); 56 | this.WriteClosingBrace(); 57 | 58 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".cs")); 59 | } // foreach database 60 | } 61 | 62 | private void WriteDataAccessNamespaceHeader(String entitiesUsingIdentifier, String namespaceIdentifier) 63 | { 64 | #> 65 | using System; 66 | using System.Collections.Generic; 67 | using System.Configuration; 68 | using System.Data; 69 | using System.Data.SqlClient; 70 | 71 | using <#= entitiesUsingIdentifier #>; 72 | 73 | using Utilities.Sql; 74 | 75 | namespace <#= namespaceIdentifier #> 76 | { 77 | <#+ 78 | } 79 | 80 | private void WriteDataAccessClassHeader(String className, String connectionStringIdentifier) 81 | { 82 | #> 83 | public static class <#= className #> 84 | { 85 | private static String _connectionString = ConfigurationManager.ConnectionStrings["<#= connectionStringIdentifier #>"].ConnectionString; 86 | 87 | <#+ 88 | } 89 | 90 | #> -------------------------------------------------------------------------------- /CSharp/Entity Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateEntityClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = database.TargetLanguageIdentifier + ".Entities"; 8 | 9 | this.WriteEntityNamespaceHeader(outputFilename); 10 | this.PushIndent(_standardIndent); 11 | 12 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 13 | { 14 | var tables = schema.Tables.OrderBy(table => table.Name); 15 | 16 | // Generate class definitions for the user-defined table types (udtt). 17 | // Assume the udtt's don't exist yet, so generate them using table columns. 18 | foreach (var table in tables) 19 | { 20 | this.WriteEntityClassHeader(table.TargetLanguageIdentifier + "_tabletype"); 21 | this.PushIndent(_standardIndent); 22 | this.WriteLine( 23 | table 24 | .Columns 25 | .Select(column => String.Format("public {0} {1} {{ get; set }}", column.ClrTypeName, column.TargetLanguageIdentifier)) 26 | .Join("," + Environment.NewLine)); 27 | this.PopIndent(); 28 | this.WriteClosingBrace(); 29 | this.WriteLine(""); 30 | } 31 | 32 | // Generate class definitions for the tables, and also include methods that 33 | // use the above udtt's to write multiple class instances to the database. 34 | foreach (var table in tables) 35 | { 36 | this.WriteEntityClassHeader(table.TargetLanguageIdentifier); 37 | this.PushIndent(_standardIndent); 38 | this.WriteClassPropertiesWithBackingStores(table.Columns); 39 | if (!table.IsView) 40 | { 41 | this.WriteLine(""); 42 | this.WriteGetDataTableMethod(table.TargetLanguageIdentifier, table.Columns); 43 | this.WriteLine(""); 44 | this.WriteAddDataRowMethod(table.TargetLanguageIdentifier, table.Columns); 45 | } 46 | this.PopIndent(); 47 | this.WriteClosingBrace(); 48 | this.WriteLine(""); 49 | } 50 | 51 | foreach (var storedProcedure in schema.StoredProcedures.Where(sp => sp.DoesReturnResultSet).OrderBy(sp => sp.Name)) 52 | { 53 | foreach (var columns in storedProcedure.ResultSets) 54 | { 55 | this.WriteEntityClassHeader(storedProcedure.TargetLanguageIdentifier); 56 | this.PushIndent(_standardIndent); 57 | this.WriteClassPropertiesWithBackingStores(columns); 58 | this.PopIndent(); 59 | this.WriteClosingBrace(); 60 | this.WriteLine(""); 61 | } 62 | 63 | if (storedProcedure.ResultSets.Count > 1) 64 | { 65 | this.WriteEntityClassHeader(storedProcedure.TargetLanguageIdentifier + "_AllResultSets"); 66 | this.PushIndent(_standardIndent); 67 | this.WriteLine( 68 | storedProcedure 69 | .ResultSets 70 | .OrderBy(cs => cs.SetNumber) 71 | .Select(cs => cs.TargetLanguageIdentifier + " " + cs.TargetLanguageIdentifier) 72 | .Join("," + Environment.NewLine)); 73 | this.PopIndent(); 74 | this.WriteClosingBrace(); 75 | this.WriteLine(""); 76 | } 77 | } // foreach storedProcedure 78 | } // foreach schema 79 | 80 | this.PopIndent(); 81 | this.WriteClosingBrace(); 82 | 83 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".cs")); 84 | } // foreach database 85 | } 86 | 87 | private void WriteEntityNamespaceHeader(String outputFilename) 88 | { 89 | #> 90 | namespace <#= outputFilename #> 91 | { 92 | <#+ 93 | } 94 | 95 | private void WriteEntityClassHeader(String className) 96 | { 97 | #> 98 | public partial class <#= className #> 99 | { 100 | <#+ 101 | } 102 | 103 | private void WriteClassPropertiesWithBackingStores(Columns columns) 104 | { 105 | var backingStores = columns.GetNecessaryTargetLanguageBackingStoreDeclarations(); 106 | if (backingStores.Any()) 107 | { 108 | this.WriteLine(backingStores.Join("," + Environment.NewLine)); 109 | this.WriteLine(""); 110 | } 111 | 112 | this.WriteLine(columns.GetClassPropertyDeclarations("public").Join("," + Environment.NewLine)); 113 | } 114 | 115 | private void WriteGetDataTableMethod(String className, Columns columns) 116 | { 117 | var columnDefinitions = 118 | columns 119 | .Select(c => String.Format("result.Columns.Add(new DataColumn(\"{0}\", typeof({1})));", c.TargetLanguageIdentifier, c.ClrTypeName)) 120 | .Join(); 121 | 122 | #> 123 | private static DataTable GetDataTable(IEnumerable<<#= className #>> xs) 124 | { 125 | var result = new DataTable(); 126 | 127 | <#+ 128 | this.PushIndent(_standardIndent); 129 | this.WriteLine(columnDefinitions); 130 | this.PopIndent(); 131 | #> 132 | 133 | foreach (var x in xs) 134 | AddDataRow(result, x); 135 | 136 | return result; 137 | } 138 | <#+ 139 | } 140 | 141 | private void WriteAddDataRowMethod(String className, Columns columns) 142 | { 143 | var columnDefinitions = 144 | columns 145 | .Select(c => String.Format("dataRow[\"{0}\"] = x.{0};", c.TargetLanguageIdentifier)) 146 | .Join(); 147 | 148 | #> 149 | private static void AddDataRow(DataTable dataTable, <#= className #> x) 150 | { 151 | var dataRow = dataTable.NewRow(); 152 | 153 | <#+ 154 | this.PushIndent(_standardIndent); 155 | this.WriteLine(columnDefinitions); 156 | this.PopIndent(); 157 | #> 158 | 159 | dataTable.Rows.Add(dataRow); 160 | } 161 | <#+ 162 | } 163 | 164 | #> -------------------------------------------------------------------------------- /CSharp/Main.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="true" language="C#" #> 2 | <#@ output extension=".txt" #> 3 | <#@ assembly name="System.Core" #> 4 | <#@ assembly name="System.Data" #> 5 | <#@ assembly name="System.Xml" #> 6 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\CSharp\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll" #> 7 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\CSharp\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll" #> 8 | <#@ import namespace="System.Collections.Generic" #> 9 | <#@ import namespace="System.Data" #> 10 | <#@ import namespace="System.Data.SqlClient" #> 11 | <#@ import namespace="System.IO" #> 12 | <#@ import namespace="System.Linq" #> 13 | <#@ import namespace="System.Text.RegularExpressions" #> 14 | <#@ import namespace="Utilities.Core" #> 15 | <#@ import namespace="Utilities.Sql.SqlServer" #> 16 | <#@ include file="..\T4_Utilities\SQL Generator Utilities.ttinclude" #> 17 | <#@ include file="Utilities.ttinclude" #> 18 | <#@ include file="Entity Classes.ttinclude" #> 19 | <#@ include file="Data Access Classes.ttinclude" #> 20 | <#@ include file="Data Access - Select Method.ttinclude" #> 21 | <#@ include file="Data Access - Insert Method.ttinclude" #> 22 | <#@ include file="Data Access - Update Method.ttinclude" #> 23 | <#@ include file="Data Access - Merge Method.ttinclude" #> 24 | <#@ include file="Data Access - Delete Method.ttinclude" #> 25 | <#@ include file="Data Access - Stored Procedure - Multiple Result Sets.ttinclude" #> 26 | <#@ include file="Data Access - Stored Procedure - Single Result Set.ttinclude" #> 27 | <#@ include file="Data Access - Stored Procedure - No Result Set.ttinclude" #> 28 | <# 29 | 30 | using (var connection = new SqlConnection("Data Source=(local);Initial Catalog=mvc_custom_controls;Integrated Security=true;")) 31 | { 32 | connection.Open(); 33 | 34 | var configuration = 35 | new Configuration() 36 | { 37 | Connection = connection, 38 | XmlSystem = XmlSystem.NonLinq_XmlDocument, 39 | TargetLanguage = TargetLanguage.CSharp_Latest, 40 | XmlValidationLocation = XmlValidationLocation.PropertySetter 41 | }; 42 | 43 | var outputDirectory = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath(".")), "Output"); 44 | var server = new Server(configuration); 45 | var databaseNames = new List() { "mvc_custom_controls" }; 46 | var databases = 47 | server 48 | .Databases 49 | .Where(db => databaseNames.ContainsCI(db.Name)) 50 | .OrderBy(db => db.Name); 51 | 52 | //var adventureWorks2012 = databases.GetByName("AdventureWorks2012"); 53 | 54 | //adventureWorks2012.AddStoredProcedure("dbo.uspGetManagerEmployees", new SqlParameter() { ParameterName = "@BusinessEntityID", SqlDbType = SqlDbType.Int, Value = -1 }); 55 | 56 | this.GenerateEntityClasses(databases, outputDirectory); 57 | this.GenerateDataAccessClasses(databases, outputDirectory); 58 | } 59 | 60 | #> -------------------------------------------------------------------------------- /CSharp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CSharp 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CSharp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CSharp")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("22cd80f2-53c4-4181-abb6-754201fd57b5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CSharp/UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the PUBLIC DOMAIN. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /CSharp/Utilities.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private static String _standardIndent = " ".Repeat(2); 4 | 5 | private String GetMethodParameters(Table table, ColumnType columnType) 6 | { 7 | return 8 | table 9 | .Columns 10 | .GetTargetLanguageMethodIdentifiersAndTypes(columnType) 11 | .Join("," + Environment.NewLine); 12 | } 13 | 14 | private String GetSqlCommandParameters(Table table, ColumnType columnType) 15 | { 16 | var parameters = table.Columns.GetTargetLanguageSqlParameterText(columnType); 17 | if (parameters.Any()) 18 | return 19 | parameters 20 | .Select(p => "command.Parameters.Add(" + p + ");") 21 | .Join(); 22 | else 23 | return ""; 24 | } 25 | 26 | private String GetSqlCommandReaderAssigments(Columns columns) 27 | { 28 | return 29 | columns 30 | .OrderBy(column => column.Name) 31 | .Select(column => String.Format("{0} = {1}", column.TargetLanguageIdentifier, column.GetTargetLanguageDataReaderExpression("reader"))) 32 | .Join("," + Environment.NewLine); 33 | } 34 | 35 | private void WriteClosingBrace() 36 | { 37 | this.WriteLine("}"); 38 | } 39 | 40 | private void PushWritePop(String indent, String data) 41 | { 42 | this.PushIndent(indent); 43 | this.WriteLine(data); 44 | this.PopIndent(); 45 | } 46 | 47 | #> -------------------------------------------------------------------------------- /FSharp/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /FSharp/Data Access Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateDataAccessClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".DataLayer"; 8 | 9 | #> 10 | namespace <#= outputFilename #> 11 | open System 12 | open System.Collections.Generic 13 | open System.Configuration 14 | open System.Data 15 | open System.Data.SqlClient 16 | 17 | open <#= IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".Entities" #> 18 | 19 | open Utilities.Sql 20 | <#+ 21 | 22 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 23 | { 24 | foreach (var table in schema.Tables.OrderBy(table => table.Name)) 25 | { 26 | 27 | #> 28 | 29 | type <#= table.TargetLanguageIdentifier #>Methods() = 30 | static let _connectionString = ConfigurationManager.ConnectionStrings.["<#= IdentifierHelper.GetTargetLanguageIdentifier(database.Name) #>"].ConnectionString 31 | 32 | <#+ 33 | var arguments = table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey); 34 | if (arguments.Count == 0) 35 | { 36 | #> 37 | static member Select<#= table.TargetLanguageIdentifier #>() : seq<<#= table.TargetLanguageIdentifier #>> = 38 | <#+ 39 | } 40 | else 41 | { 42 | #> 43 | static member Select<#= table.TargetLanguageIdentifier #> 44 | <#= String.Join(Environment.NewLine + " ", arguments) #> : seq<<#= table.TargetLanguageIdentifier #>> = 45 | <#+ 46 | } 47 | #> 48 | use connection = new SqlConnection(_connectionString) 49 | connection.Open() 50 | 51 | use command = new SqlCommand(Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Select") #>") 52 | command.Parameters.Clear() 53 | <#+ 54 | var parameters = table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey); 55 | if (parameters.Count > 0) 56 | { 57 | #> 58 | command.Parameters.Add(<#= String.Join(") |> ignore" + Environment.NewLine + " command.Parameters.Add(", parameters) #>) |> ignore 59 | <#+ 60 | } 61 | #> 62 | 63 | use reader = command.ExecuteReader(CommandBehavior.CloseConnection) 64 | seq { while reader.Read() do 65 | yield 66 | new <#= table.TargetLanguageIdentifier #>( 67 | <#= String.Join("," + Environment.NewLine + " ", 68 | table.Columns.OrderBy(column => column.Name) 69 | .Select(column => String.Format("{0} = {1}", column.TargetLanguageIdentifier, column.GetTargetLanguageDataReaderExpression("reader")))) #>) } 70 | 71 | <#+ 72 | 73 | /* Views don't need insert, update and delete methods. */ 74 | if (!table.IsView) 75 | { 76 | 77 | #> 78 | static member Insert<#= table.TargetLanguageIdentifier #> 79 | <#= String.Join(Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.CanAppearInInsertStatement)) #> = 80 | use connection = new SqlConnection(_connectionString) 81 | connection.Open() 82 | 83 | use command = new SqlCommand(Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Insert") #>") 84 | command.Parameters.Clear() 85 | command.Parameters.Add(<#= String.Join(") |> ignore" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.CanAppearInInsertStatement)) #>) |> ignore 86 | command.ExecuteNonQuery() 87 | 88 | static member public Update<#= table.TargetLanguageIdentifier #> 89 | <#= String.Join(Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause)) #> = 90 | use connection = new SqlConnection(_connectionString) 91 | connection.Open() 92 | 93 | use command = new SqlCommand(Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Update") #>") 94 | command.Parameters.Clear() 95 | command.Parameters.Add(<#= String.Join(") |> ignore" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause)) #>) |> ignore 96 | command.ExecuteNonQuery() 97 | 98 | static member public Merge<#= table.TargetLanguageIdentifier #> 99 | <#= String.Join(Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList)) #> = 100 | use connection = new SqlConnection(_connectionString) 101 | connection.Open() 102 | 103 | use command = new SqlCommand(Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Merge") #>") 104 | command.Parameters.Clear() 105 | command.Parameters.Add(<#= String.Join(") |> ignore" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList)) #>) |> ignore 106 | command.ExecuteNonQuery() 107 | 108 | static member public Delete<#= table.TargetLanguageIdentifier #> 109 | <#= String.Join(Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey)) #> = 110 | use connection = new SqlConnection(_connectionString) 111 | connection.Open() 112 | 113 | use command = new SqlCommand(Connection = connection, CommandType = CommandType.StoredProcedure, CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Delete") #>") 114 | command.Parameters.Clear() 115 | command.Parameters.Add(<#= String.Join(") |> ignore" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey)) #>) |> ignore 116 | command.ExecuteNonQuery() 117 | 118 | <#+ 119 | } // if 120 | } // foreach table 121 | } // foreach schema 122 | 123 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".fs")); 124 | } // foreach database 125 | } 126 | #> -------------------------------------------------------------------------------- /FSharp/Entity Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateEntityClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".Entities"; 8 | 9 | #> 10 | namespace <#= outputFilename #> 11 | 12 | <#+ 13 | 14 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 15 | { 16 | foreach (var table in schema.Tables.OrderBy(table => table.Name)) 17 | { 18 | 19 | #> 20 | type <#= table.TargetLanguageIdentifier #>() = 21 | <#= String.Join(Environment.NewLine, table.Columns.GetNecessaryTargetLanguageBackingStoreDeclarations()).Indent(4) #> 22 | 23 | <#= String.Join(Environment.NewLine, table.Columns.GetClassPropertyDeclarations("public")).Indent(4) #> 24 | 25 | <#+ 26 | } // foreach table 27 | } // foreach schema 28 | 29 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".fs")); 30 | } // foreach database 31 | } 32 | #> -------------------------------------------------------------------------------- /FSharp/FSharp.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | 99ae7570-216e-47a3-80cd-06d628b1eb09 9 | Exe 10 | FSharp 11 | FSharp 12 | v4.5.1 13 | FSharp 14 | 4.3.1.0 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | 3 25 | AnyCPU 26 | 27 | 28 | true 29 | 30 | 31 | pdbonly 32 | true 33 | true 34 | bin\Release\ 35 | TRACE 36 | 3 37 | AnyCPU 38 | bin\Release\FSharp.XML 39 | true 40 | 41 | 42 | 43 | True 44 | 45 | 46 | ..\..\..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Types.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | ..\..\..\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll 59 | 60 | 61 | ..\..\..\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 11 73 | 74 | 75 | 76 | 77 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 78 | 79 | 80 | 81 | 82 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | "C:\Program Files (x86)\Common Files\microsoft shared\TextTemplating\12.0\texttransform" "$(projectdir)main.tt" 93 | 94 | 101 | -------------------------------------------------------------------------------- /FSharp/Main.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="true" language="C#" #> 2 | <#@ output extension=".txt" #> 3 | <#@ assembly name="System.Core" #> 4 | <#@ assembly name="System.Data" #> 5 | <#@ assembly name="System.Xml" #> 6 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll" #> 7 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll" #> 8 | <#@ import namespace="System.Collections.Generic" #> 9 | <#@ import namespace="System.Data" #> 10 | <#@ import namespace="System.Data.SqlClient" #> 11 | <#@ import namespace="System.IO" #> 12 | <#@ import namespace="System.Linq" #> 13 | <#@ import namespace="System.Text.RegularExpressions" #> 14 | <#@ import namespace="Utilities.Core" #> 15 | <#@ import namespace="Utilities.Sql.SqlServer" #> 16 | <#@ include file="..\T4_Utilities\SQL Generator Utilities.ttinclude" #> 17 | <#@ include file="Entity Classes.ttinclude" #> 18 | <#@ include file="Data Access Classes.ttinclude" #> 19 | <# 20 | 21 | using (var connection = new SqlConnection("Data Source=laptop2;Initial Catalog=AdventureWorks2012;Integrated Security=true;")) 22 | { 23 | connection.Open(); 24 | 25 | var configuration = 26 | new Configuration() 27 | { 28 | Connection = connection, 29 | XmlSystem = XmlSystem.Linq_XDocument, 30 | TargetLanguage = TargetLanguage.FSharp_Latest, 31 | XmlValidationLocation = XmlValidationLocation.PropertySetter 32 | }; 33 | 34 | /* NOTE: Because Visual Studio F# projects don't support T4 templates, 35 | the standalone TextTransform.exe utility has to be used to 36 | process this template (it's called in the project's Pre-Build step). 37 | 38 | The problem is that this.Host.ResolvePath() doesn't seem to work 39 | in TextTransform.exe. ResolvePath() just returns its argument, without including any 40 | directory data. 41 | 42 | System.Environment.CurrentDirectory cannot be depended on, either. 43 | Sometimes it returns the project's directory, and sometimes it returns the 44 | project's bin/debug or bin/release directory. I'm guessing Visual Studio is 45 | altering the operating system's current directory to suit its own needs. 46 | 47 | So it looks like there's no other choice but to hardcode the 48 | outputDirectory value. */ 49 | 50 | var outputDirectory = @"C:\users\ctimmons\documents\Data\Dev\Visual Studio\T4\t4_sql_examples\FSharp\Output"; 51 | var server = new Server(configuration); 52 | var databaseNames = new List() { "AdventureWorks2012" }; 53 | var databases = 54 | server 55 | .Databases 56 | .Where(db => databaseNames.Contains(db.Name, CaseInsensitiveStringComparer.Instance)) 57 | .OrderBy(db => db.Name); 58 | 59 | this.GenerateEntityClasses(databases, outputDirectory); 60 | this.GenerateDataAccessClasses(databases, outputDirectory); 61 | } 62 | 63 | #> -------------------------------------------------------------------------------- /FSharp/Program.fs: -------------------------------------------------------------------------------- 1 | // Learn more about F# at http://fsharp.net 2 | // See the 'F# Tutorial' project for more help. 3 | 4 | module Program 5 | 6 | [] 7 | let main argv = 8 | printfn "%A" argv 9 | 0 // return an integer exit code 10 | -------------------------------------------------------------------------------- /FSharp/UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the PUBLIC DOMAIN. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | t4_sql_examples 2 | =============== 3 | 4 | (NOTE: This respository is archived. The latest versions of C# have robust string interpolation capabilities, which makes T4 templates mostly obsolete. Looked at another way, it's now easier to write a C# app that generates code than it is to write the same functionality in a set of T4 templates.) 5 | 6 | For a [variety of reasons](http://stackoverflow.com/questions/760834/how-can-i-design-a-java-web-application-without-an-orm-and-without-embedded-sql), I don't like [ORMs](http://en.wikipedia.org/wiki/Object-relational_mapping). In the absence of an ORM, the usual alternative is manually writing hundreds - or even thousands - of lines of boilerplate code to pass data back and forth between the app(s) and the database. Yuck. 7 | 8 | Fortunately there's an easier way. A code generator can quickly write all of that boilerplate at the touch of a button. The best part is that you, the programmer, have full access to both the templates and the generated source code, so you can change what gets generated at will. This is unlike an ORM, which is going to hide what it's doing under the covers, and make it hard - if not impossible - to do anything outside of that particular ORM's model (they're all a little different, and none has truly universal capabilities). 9 | 10 | I'm not aware of any commercial or open source code generators that do this for .Net apps, so I wrote my own. A .Net library that exposes the metadata for a given MS SQL server is located in the Utilities.Sql project in the [cs_Utilities](https://github.com/ctimmons/cs_utilities) repository. 11 | 12 | This Visual Studio solution contains five projects demonstrating how use that library and T4 templates to generate various kinds of database access code - TSQL, C#, F# and Visual Basic. 13 | 14 | Dependencies 15 | ------------ 16 | 17 | All of the projects depend on the Utilities.Sql project from the [cs_Utilities](https://github.com/ctimmons/cs_utilities) solution. 18 | 19 | The generated code may have dependencies on Utilities.Core, Utilities.Sql (both are in cs_Utilities), and/or Microsoft.SqlServer.Types, in addition to any assemblies you choose to generate code references to. 20 | 21 | (To get the Microsoft.SqlServer.Types assembly, go to [SQL Server 2012 SP1 Feature Pack](http://www.microsoft.com/en-us/download/details.aspx?id=35580) and expand the "Install Instructions" section. Scroll down to the section labeled "Microsoft® System CLR Types for Microsoft® SQL Server® 2012" and download and run the appropriate 32 or 64 bit installer. 22 | 23 | There are feature packs available for other versions of SQL Server. Go to [Microsoft Search](http://search.microsoft.com/) and search for "sql server feature pack".) 24 | 25 | Generated TSQL code may also reference a TSQL function called "dbo.util_Get_SqlVariant_As_NVarCharMax". This is a small function I wrote that returns the string representation of any SQL_VARIANT value. It can be found in the [tsql_utilities](https://github.com/ctimmons/tsql_utilities) repository. This is currently hardcoded in the Utilities.Sql code, but in the near future I might change it to be a configuration option. 26 | 27 | 28 | The Projects 29 | ------------ 30 | 31 | ### T4_Utilities 32 | 33 | An empty C# project whose only purpose is to serve as a home for T4 utility templates. 34 | 35 | These templates are referenced in the other projects' .tt files via the T4 include directive, e.g. <#@ include file="..\T4_Utilities\SQL Generator Utilities.ttinclude" #>. 36 | 37 | ### SQL 38 | 39 | Another empty C# project whose only purpose is to serve as a home for T4 templates that generate T-SQL code. 40 | 41 | ### CSharp and Visual_Basic 42 | 43 | Basically identical to each other. The project's Main.tt template generates code for the data entity classes and data access methods, producing either C# or VB code. 44 | 45 | ### FSharp 46 | 47 | The Main.tt template and included templates are the same structure as the CSharp and Visual_Basic projects. 48 | 49 | However, F# projects in Visual Studio do *not* support T4 templates. To get around this, the standalone TextTransform.exe template generator needs to be run separately on the Main.tt template. For .Net 4.5, this utility is found in "C:\Program Files (x86)\Common Files\microsoft shared\TextTemplating\12.0\". For previous versions of .Net, TextTransform.exe may be under the \10.0\ or \11.0\ subfolders. 50 | 51 | In the project's properties page, I've put a call to TextTransform in the project's pre-build step (open the FSharp project's properties and go to the "Build Events" tab). Just rebuild the project to run the T4 templates. 52 | 53 | ### Processing Logic 54 | 55 | Except for the T4_Utilities project, the processing logic is the same: 56 | 57 | - The Main.tt file sets up the code generation environment by loading the necessary assemblies, importing namespaces, and including any other T4 templates (*.ttinclude files) it needs. 58 | - An SqlConnection is created and opened. 59 | - A Configuration instance is created and its properties set to the desired values. 60 | - An output directory is set. 61 | - A Server instance is created. 62 | - The template functions that actually generate the code are called. 63 | 64 | 65 | Generating the Code 66 | ------------------- 67 | 68 | First, download and build the [cs_Utilities](https://github.com/ctimmons/cs_utilities) Visual Studio solution from GitHub. 69 | 70 | Then make these changes to the projects in this solution to generate the code on your system: 71 | 72 | In the Main.tt file in each project (except for the T4_Utilities project - it doesn't have a Main.tt file): 73 | 74 | 1. Alter the <#@ assembly name=...#> directive that loads Utilities.Sql.dll to point to the correct location on your system. 75 | 76 | 2. Alter the connection string to match your MS SQL server name and security credentials. 77 | 78 | 3. Optionally, change the outputDirectory variable to point to where you want the templates to put the generated files. Right now all of the projects Main.tt templates write their output files to a folder under the project's root folder. 79 | 80 | In the T4_Utilities project, there's a file named SQL Generator Utilities.ttinclude that contains a _prefixes dictionary. This dictionary is used by the GetStoredProcedureName method (right after the dictionary) to generate a uniform name for a stored procedure. Change the keys and values in the dictionary to reflect the database names on your server (the keys) and the abbreviation for each (the values). 81 | 82 | In the FSharp project, open the project's properties and go to the "Build Events" tab. As noted above, the TextTransform.exe that comes with .Net should be in a subfolder of "C:\Program Files (x86)\Common Files\microsoft shared\TextTemplating\", either the 10.0\ or 11.0\ subfolder. Make sure the call in the Pre-Build step is pointing to the correct folder. 83 | 84 | Except for the FSharp project, altering and then saving Main.tt should make Visual Studio run the template and generate the code. The template can also be run by right clicking on the Main.tt file in Visual Studio's Project Explorer and choosing "Run Custom Tool". 85 | 86 | For the FSharp project, building the project will cause the call to TextTransform.exe in the Pre-Build step to be executed. 87 | 88 | 89 | The Generated Code 90 | ------------------ 91 | 92 | The code generated by the CSharp, FSharp and Visual_Basic projects all generate two source files: one containing classes that serve as simple database entities (one per table), and a file containing access methods that perform the select, insert, update, and delete operations using those entities. 93 | 94 | The SQL project's templates iterate over all of the tables in the selected database(s) on the specified server. For each table, the templates generate a separate stored procedures for each of the SELECT, INSERT, UPDATE, MERGE, and DELETE operations on a table. This means, for example, if you've selected 4 databases, and each database has 10 tables, then the SQL project will generate 200 files (40 tables times 5 operations per table). 95 | 96 | 97 | Adding the Generated Code to the Project 98 | ---------------------------------------- 99 | 100 | For the CSharp, FSharp and Visual_Basic projects, the generated code can be added to its respective project (or any other C#, F#, or VB project) and compiled. 101 | 102 | The stored procedures produced by the SQL project can be loaded into SQL Server Management Studio and executed. 103 | 104 | 105 | What's Next 106 | ----------- 107 | 108 | The T4 templates included in this repository only scratch the surface of what's possible. Unlike ORMs, you're not limited to what the ORM author thought was the "right" way to do things. The sky really is the limit when it comes to code generation. 109 | 110 | If you have any ideas for template examples, or new functionality in the [Utilities.Sql](https://github.com/ctimmons/cs_utilities) library, please create an enhancement issue in the relevant GitHub repository. 111 | 112 | -------------------------------------------------------------------------------- /SQL/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SQL/Delete.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateDeleteStoredProcedures(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | if (table.IsView) 12 | continue; 13 | 14 | var spName = this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Delete"); 15 | 16 | #> 17 | USE [<#= database.Name #>]; 18 | GO 19 | 20 | IF OBJECT_ID(N'<#= spName #>') IS NOT NULL 21 | DROP PROCEDURE <#= spName #>; 22 | GO 23 | 24 | SET NUMERIC_ROUNDABORT OFF; 25 | SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, XACT_ABORT ON; 26 | GO 27 | 28 | CREATE PROCEDURE <#= spName #> 29 | ( 30 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetStoredProcedureParameters(ColumnType.PrimaryKey)) #> 31 | ) 32 | AS 33 | BEGIN 34 | SET NOCOUNT ON; 35 | 36 | DECLARE @crlf NCHAR(2) = CHAR(13) + CHAR(10); 37 | DECLARE @proc_name SYSNAME = COALESCE(OBJECT_NAME(@@PROCID), 'Insufficient permissions to get stored procedure name.'); 38 | DECLARE @error INT; 39 | DECLARE @rowcount INT; 40 | DECLARE @error_message NVARCHAR(MAX); 41 | 42 | DELETE FROM <#= table.SchemaNameAndTableName #> 43 | WHERE 44 | <#= String.Join(" AND" + Environment.NewLine + " ", table.Columns.GetWhereClauseColumnList(ColumnType.PrimaryKey)) #>; 45 | 46 | SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT; 47 | 48 | IF (@error <> 0) OR (@rowcount = 0) 49 | BEGIN 50 | DECLARE @parameter_values NVARCHAR(MAX) = 51 | <#= String.Join(" + @crlf + " + Environment.NewLine + " ", 52 | table 53 | .Columns 54 | .Where(column => column.ColumnType.HasFlag(ColumnType.PrimaryKey)) 55 | .Select(column => String.Format("'{0} = ' + {1}", column.SqlIdentifier, column.SqlExpressionToConvertToString))) #>; 56 | 57 | IF @error <> 0 58 | BEGIN 59 | SET @error_message = 60 | @proc_name + ': Error ' + CONVERT(NVARCHAR(MAX), @error) + ' occurred when calling DELETE FROM <#= table.SchemaNameAndTableName #>.' + @crlf + 61 | 'Parameter values:' + @crlf + @parameter_values; 62 | RAISERROR(@error_message, 16, 1); 63 | RETURN 1; 64 | END; 65 | 66 | IF @rowcount = 0 67 | BEGIN 68 | SET @error_message = 69 | @proc_name + ': No row inserted. DELETE FROM <#= table.SchemaNameAndTableName #> failed.' + @crlf + 70 | 'Parameter values:' + @crlf + @parameter_values; 71 | RAISERROR(@error_message, 16, 1); 72 | RETURN 2; 73 | END; 74 | END; 75 | 76 | SET NOCOUNT OFF; 77 | 78 | RETURN 0; 79 | END; 80 | 81 | GO 82 | <#+ 83 | 84 | this.SaveOutput(Path.Combine(outputDirectory, spName + ".sql")); 85 | } // foreach table 86 | } // foreach schema 87 | } // foreach database 88 | } 89 | #> -------------------------------------------------------------------------------- /SQL/Insert.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateInsertStoredProcedures(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | if (table.IsView) 12 | continue; 13 | 14 | var spName = this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Insert"); 15 | 16 | #> 17 | USE [<#= database.Name #>]; 18 | GO 19 | 20 | IF OBJECT_ID(N'<#= spName #>') IS NOT NULL 21 | DROP PROCEDURE <#= spName #>; 22 | GO 23 | 24 | SET NUMERIC_ROUNDABORT OFF; 25 | SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, XACT_ABORT ON; 26 | GO 27 | 28 | CREATE PROCEDURE <#= spName #> 29 | ( 30 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetStoredProcedureParameters(ColumnType.CanAppearInInsertStatement)) #> 31 | ) 32 | AS 33 | BEGIN 34 | SET NOCOUNT ON; 35 | 36 | DECLARE @crlf NCHAR(2) = CHAR(13) + CHAR(10); 37 | DECLARE @proc_name SYSNAME = COALESCE(OBJECT_NAME(@@PROCID), 'Insufficient permissions to get stored procedure name.'); 38 | DECLARE @error INT; 39 | DECLARE @rowcount INT; 40 | DECLARE @error_message NVARCHAR(MAX); 41 | 42 | INSERT INTO <#= table.SchemaNameAndTableName #> 43 | ( 44 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetInsertColumnList()) #> 45 | ) 46 | VALUES 47 | ( 48 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetInsertValuesList()) #> 49 | ); 50 | 51 | SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT; 52 | 53 | IF (@error <> 0) OR (@rowcount = 0) 54 | BEGIN 55 | DECLARE @parameter_values NVARCHAR(MAX) = 56 | <#= String.Join(" + @crlf + " + Environment.NewLine + " ", 57 | table 58 | .Columns 59 | .Where(column => column.ColumnType.HasFlag(ColumnType.CanAppearInInsertStatement)) 60 | .Select(column => String.Format("'{0} = ' + {1}", column.SqlIdentifier, column.SqlExpressionToConvertToString))) #>; 61 | 62 | IF @error <> 0 63 | BEGIN 64 | SET @error_message = 65 | @proc_name + ': Error ' + CONVERT(NVARCHAR(MAX), @error) + ' occurred when calling INSERT INTO <#= table.SchemaNameAndTableName #>.' + @crlf + 66 | 'Parameter values:' + @crlf + @parameter_values; 67 | RAISERROR(@error_message, 16, 1); 68 | RETURN 1; 69 | END; 70 | 71 | IF @rowcount = 0 72 | BEGIN 73 | SET @error_message = 74 | @proc_name + ': No row inserted. INSERT INTO <#= table.SchemaNameAndTableName #> failed.' + @crlf + 75 | 'Parameter values:' + @crlf + @parameter_values; 76 | RAISERROR(@error_message, 16, 1); 77 | RETURN 2; 78 | END; 79 | END; 80 | 81 | SET NOCOUNT OFF; 82 | 83 | RETURN 0; 84 | END; 85 | 86 | GO 87 | <#+ 88 | 89 | this.SaveOutput(Path.Combine(outputDirectory, spName + ".sql")); 90 | } // foreach table 91 | } // foreach schema 92 | } // foreach database 93 | } 94 | #> -------------------------------------------------------------------------------- /SQL/Main.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="true" language="C#" #> 2 | <#@ output extension=".txt" #> 3 | <#@ assembly name="System.Core" #> 4 | <#@ assembly name="System.Data" #> 5 | <#@ assembly name="System.Xml" #> 6 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll" #> 7 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll" #> 8 | <#@ import namespace="System.Collections.Generic" #> 9 | <#@ import namespace="System.Data" #> 10 | <#@ import namespace="System.Data.SqlClient" #> 11 | <#@ import namespace="System.IO" #> 12 | <#@ import namespace="System.Linq" #> 13 | <#@ import namespace="System.Text.RegularExpressions" #> 14 | <#@ import namespace="Utilities.Core" #> 15 | <#@ import namespace="Utilities.Sql.SqlServer" #> 16 | <#@ include file="..\T4_Utilities\SQL Generator Utilities.ttinclude" #> 17 | <#@ include file="Select.ttinclude" #> 18 | <#@ include file="Insert.ttinclude" #> 19 | <#@ include file="Update.ttinclude" #> 20 | <#@ include file="Delete.ttinclude" #> 21 | <#@ include file="Merge (Insert and Update).ttinclude" #> 22 | <#@ include file="User-Defined Table Type.ttinclude" #> 23 | <# 24 | 25 | using (var connection = new SqlConnection("Data Source=laptop2;Initial Catalog=AdventureWorks2012;Integrated Security=true;")) 26 | { 27 | connection.Open(); 28 | 29 | var configuration = 30 | new Configuration() 31 | { 32 | Connection = connection, 33 | XmlSystem = XmlSystem.Linq_XDocument, 34 | TargetLanguage = TargetLanguage.CSharp_4_0, 35 | XmlValidationLocation = XmlValidationLocation.PropertySetter 36 | }; 37 | 38 | var templateDirectory = Path.GetDirectoryName(this.Host.ResolvePath(".")); 39 | var outputDirectory = Path.Combine(templateDirectory, "Stored Procedures"); 40 | var server = new Server(configuration); 41 | var databaseNames = new List() { "AdventureWorks2012" }; 42 | var databases = 43 | server 44 | .Databases 45 | .Where(db => databaseNames.Contains(db.Name, CaseInsensitiveStringComparer.Instance)) 46 | .OrderBy(db => db.Name); 47 | 48 | this.GenerateSelectStoredProcedures(databases, outputDirectory); 49 | this.GenerateInsertStoredProcedures(databases, outputDirectory); 50 | this.GenerateUpdateStoredProcedures(databases, outputDirectory); 51 | this.GenerateDeleteStoredProcedures(databases, outputDirectory); 52 | this.GenerateMergeInsertAndUpdateStoredProcedures(databases, outputDirectory); 53 | this.GenerateTableTypes(databases, outputDirectory); 54 | } 55 | 56 | #> -------------------------------------------------------------------------------- /SQL/Merge (Insert and Update).ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateMergeInsertAndUpdateStoredProcedures(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | if (table.IsView) 12 | continue; 13 | 14 | var spName = this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Merge"); 15 | 16 | #> 17 | USE [<#= database.Name #>]; 18 | GO 19 | 20 | IF OBJECT_ID(N'<#= spName #>') IS NOT NULL 21 | DROP PROCEDURE <#= spName #>; 22 | GO 23 | 24 | SET NUMERIC_ROUNDABORT OFF; 25 | SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, XACT_ABORT ON; 26 | GO 27 | 28 | CREATE PROCEDURE <#= spName #> 29 | ( 30 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetStoredProcedureParameters(ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList)) #> 31 | ) 32 | AS 33 | BEGIN 34 | SET NOCOUNT ON; 35 | 36 | DECLARE @crlf NCHAR(2) = CHAR(13) + CHAR(10); 37 | DECLARE @proc_name SYSNAME = COALESCE(OBJECT_NAME(@@PROCID), 'Insufficient permissions to get stored procedure name.'); 38 | DECLARE @error INT; 39 | DECLARE @error_message NVARCHAR(MAX); 40 | 41 | MERGE <#= table.SchemaNameAndTableName #> AS Target 42 | USING 43 | ( 44 | SELECT 45 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetMergeSelectList()) #> 46 | ) AS Source 47 | ON 48 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetMergeTargetAndSourceMatchingExpressions()) #> 49 | WHEN MATCHED THEN 50 | UPDATE 51 | SET 52 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetMergeUpdateColumnList()) #> 53 | WHEN NOT MATCHED BY TARGET THEN 54 | INSERT 55 | ( 56 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetInsertColumnList()) #> 57 | ) 58 | VALUES 59 | ( 60 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetMergeInsertValueList()) #> 61 | ); 62 | 63 | SELECT @error = @@ERROR; 64 | 65 | IF @error <> 0 66 | BEGIN 67 | DECLARE @parameter_values NVARCHAR(MAX) = 68 | <#= String.Join(" + @crlf + " + Environment.NewLine + " ", 69 | table 70 | .Columns 71 | .Where(column => ((ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList) & column.ColumnType) > 0) 72 | .Select(column => String.Format("'{0} = ' + {1}", column.SqlIdentifier, column.SqlExpressionToConvertToString))) #>; 73 | 74 | SET @error_message = 75 | @proc_name + ': Error ' + CONVERT(NVARCHAR(MAX), @error) + ' occurred when calling MERGE <#= table.SchemaNameAndTableName #>.' + @crlf + 76 | 'Parameter values:' + @crlf + @parameter_values; 77 | RAISERROR(@error_message, 16, 1); 78 | RETURN 1; 79 | END; 80 | 81 | SET NOCOUNT OFF; 82 | 83 | RETURN 0; 84 | END; 85 | 86 | GO 87 | <#+ 88 | 89 | this.SaveOutput(Path.Combine(outputDirectory, spName + ".sql")); 90 | } // foreach table 91 | } // foreach schema 92 | } // foreach database 93 | } 94 | #> -------------------------------------------------------------------------------- /SQL/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CSharp 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SQL/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SQL")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SQL")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("51d95611-f823-4fc6-9048-c351bdc24ed0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SQL/SQL.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7419E439-0DED-49EC-ACAC-9A234DBCDBB4} 8 | Exe 9 | Properties 10 | SQL 11 | SQL 12 | v4.5.1 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | TextTemplatingFileGenerator 46 | Main.txt 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | True 58 | True 59 | Main.tt 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 77 | -------------------------------------------------------------------------------- /SQL/Select.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateSelectStoredProcedures(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | var spName = this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Select"); 12 | 13 | #> 14 | USE [<#= database.Name #>]; 15 | GO 16 | 17 | IF OBJECT_ID(N'<#= spName #>') IS NOT NULL 18 | DROP PROCEDURE <#= spName #>; 19 | GO 20 | 21 | SET NUMERIC_ROUNDABORT OFF; 22 | SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, XACT_ABORT ON; 23 | GO 24 | 25 | CREATE PROCEDURE <#= spName #> 26 | ( 27 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetStoredProcedureParameters(ColumnType.PrimaryKey)) #> 28 | ) 29 | AS 30 | BEGIN 31 | SET NOCOUNT ON; 32 | 33 | DECLARE @crlf NCHAR(2) = CHAR(13) + CHAR(10); 34 | DECLARE @proc_name SYSNAME = COALESCE(OBJECT_NAME(@@PROCID), 'Insufficient permissions to get stored procedure name.'); 35 | DECLARE @error INT; 36 | DECLARE @error_message NVARCHAR(MAX); 37 | 38 | SELECT 39 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetSelectColumnList("T")) #> 40 | FROM 41 | <#= table.SchemaNameAndTableName #> AS T 42 | WHERE 43 | <#= String.Join(Environment.NewLine + " AND ", table.Columns.GetWhereClauseColumnList(ColumnType.PrimaryKey, "T")) #>; 44 | 45 | SELECT @error = @@ERROR; 46 | 47 | IF @error <> 0 48 | BEGIN 49 | DECLARE @parameter_values NVARCHAR(MAX) = 50 | <#= String.Join(" + @crlf + " + Environment.NewLine + " ", 51 | table 52 | .Columns 53 | .Where(column => column.ColumnType.HasFlag(ColumnType.PrimaryKey)) 54 | .Select(column => String.Format("'{0} = ' + {1}", column.SqlIdentifier, column.SqlExpressionToConvertToString))) #>; 55 | SET @error_message = 56 | @proc_name + ': Error ' + CONVERT(NVARCHAR(MAX), @error) + ' occurred when calling SELECT FROM <#= table.SchemaNameAndTableName #>.' + @crlf + 57 | 'Parameter values:' + @crlf + @parameter_values; 58 | RAISERROR(@error_message, 16, 1); 59 | RETURN 1; 60 | END; 61 | 62 | SET NOCOUNT OFF; 63 | 64 | RETURN 0; 65 | END; 66 | 67 | GO 68 | <#+ 69 | 70 | this.SaveOutput(Path.Combine(outputDirectory, spName + ".sql")); 71 | } // foreach table 72 | } // foreach schema 73 | } // foreach database 74 | } 75 | 76 | #> -------------------------------------------------------------------------------- /SQL/UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the PUBLIC DOMAIN. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /SQL/Update.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateUpdateStoredProcedures(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | if (table.IsView) 12 | continue; 13 | 14 | var spName = this.GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Update"); 15 | 16 | #> 17 | USE [<#= database.Name #>]; 18 | GO 19 | 20 | IF OBJECT_ID(N'<#= spName #>') IS NOT NULL 21 | DROP PROCEDURE <#= spName #>; 22 | GO 23 | 24 | SET NUMERIC_ROUNDABORT OFF; 25 | SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, XACT_ABORT ON; 26 | GO 27 | 28 | CREATE PROCEDURE <#= spName #> 29 | ( 30 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetStoredProcedureParameters(ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause)) #> 31 | ) 32 | AS 33 | BEGIN 34 | SET NOCOUNT ON; 35 | 36 | DECLARE @crlf NCHAR(2) = CHAR(13) + CHAR(10); 37 | DECLARE @proc_name SYSNAME = COALESCE(OBJECT_NAME(@@PROCID), 'Insufficient permissions to get stored procedure name.'); 38 | DECLARE @error INT; 39 | DECLARE @rowcount INT; 40 | DECLARE @error_message NVARCHAR(MAX); 41 | 42 | UPDATE <#= table.SchemaNameAndTableName #> 43 | SET 44 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetUpdateColumnList()) #> 45 | WHERE 46 | <#= String.Join(" AND" + Environment.NewLine + " ", table.Columns.GetWhereClauseColumnList(ColumnType.PrimaryKey)) #>; 47 | 48 | SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT; 49 | 50 | IF (@error <> 0) OR (@rowcount = 0) 51 | BEGIN 52 | DECLARE @parameter_values NVARCHAR(MAX) = 53 | <#= String.Join(" + @crlf + " + Environment.NewLine + " ", 54 | table 55 | .Columns 56 | .Where(column => ((ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList) & column.ColumnType) > 0) 57 | .Select(column => String.Format("'{0} = ' + {1}", column.SqlIdentifier, column.SqlExpressionToConvertToString))) #>; 58 | 59 | IF @error <> 0 60 | BEGIN 61 | SET @error_message = 62 | @proc_name + ': Error ' + CONVERT(NVARCHAR(MAX), @error) + ' occurred when calling UPDATE <#= table.SchemaNameAndTableName #>.' + @crlf + 63 | 'Parameter values:' + @crlf + @parameter_values; 64 | RAISERROR(@error_message, 16, 1); 65 | RETURN 1; 66 | END; 67 | 68 | IF @rowcount = 0 69 | BEGIN 70 | SET @error_message = 71 | @proc_name + ': No row inserted. UPDATE <#= table.SchemaNameAndTableName #> failed.' + @crlf + 72 | 'Parameter values:' + @crlf + @parameter_values; 73 | RAISERROR(@error_message, 16, 1); 74 | RETURN 2; 75 | END; 76 | END; 77 | 78 | SET NOCOUNT OFF; 79 | 80 | RETURN 0; 81 | END; 82 | 83 | GO 84 | <#+ 85 | 86 | this.SaveOutput(Path.Combine(outputDirectory, spName + ".sql")); 87 | } // foreach table 88 | } // foreach schema 89 | } // foreach database 90 | } 91 | #> -------------------------------------------------------------------------------- /SQL/User-Defined Table Type.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateTableTypes(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | foreach (var schema in database.Schemas) 8 | { 9 | foreach (var table in schema.Tables) 10 | { 11 | var tableTypeName = table.Name + "_tabletype"; 12 | var schemaAndTableTypeName = table.Schema.Name + "." + tableTypeName; 13 | 14 | #> 15 | /* Types are impossible to remove without removing all of 16 | the type's dependencies first (e.g. stored procedures, 17 | columns, indexes, etc.) This is difficult to 18 | do programmatically, so this code is simplified to 19 | only check for the type's existence before trying to 20 | create it. 21 | 22 | Note that there is no ALTER TYPE statement in SQL Server. 23 | If the type needs to be modified, you must go through the 24 | multi-step procedure outlined in this blog entry: 25 | 26 | http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/14/bad-habits-to-kick-using-alias-types.aspx */ 27 | 28 | IF NOT EXISTS 29 | ( 30 | SELECT 31 | * 32 | FROM 33 | sys.types AS T 34 | INNER JOIN sys.schemas AS S ON S.schema_id = T.schema_id 35 | WHERE 36 | T.is_table_type = 1 37 | AND S.name = '<#= table.Schema.Name #>' 38 | AND T.name = '<#= tableTypeName #>' 39 | ) 40 | BEGIN 41 | CREATE TYPE <#= schemaAndTableTypeName #> AS TABLE 42 | ( 43 | <#= table.Columns.GetCreateTableColumnDeclarations().Join("," + Environment.NewLine).Indent(4) #> 44 | ); 45 | END; 46 | GO 47 | <#+ 48 | 49 | this.SaveOutput(Path.Combine(outputDirectory, schemaAndTableTypeName + ".sql")); 50 | } // foreach table 51 | } // foreach schema 52 | } // foreach database 53 | } 54 | 55 | #> -------------------------------------------------------------------------------- /T4_SQL_Examples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharp", "CSharp\CSharp.csproj", "{87B5420A-9AD3-492A-B3C7-A5F307B90288}" 7 | EndProject 8 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Visual_Basic", "Visual_Basic\Visual_Basic.vbproj", "{4B727A97-A002-46CA-B4ED-09C3E4A7EA25}" 9 | EndProject 10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp", "FSharp\FSharp.fsproj", "{99AE7570-216E-47A3-80CD-06D628B1EB09}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQL", "SQL\SQL.csproj", "{7419E439-0DED-49EC-ACAC-9A234DBCDBB4}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "T4_Utilities", "T4_Utilities\T4_Utilities.csproj", "{676059A0-AE5D-4A07-B1BD-CD23EB29EE90}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77AD2052-0A71-4D78-9D6F-CA28DAFAA548}" 17 | ProjectSection(SolutionItems) = preProject 18 | README.md = README.md 19 | EndProjectSection 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Release|Any CPU = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {87B5420A-9AD3-492A-B3C7-A5F307B90288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {87B5420A-9AD3-492A-B3C7-A5F307B90288}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {87B5420A-9AD3-492A-B3C7-A5F307B90288}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {87B5420A-9AD3-492A-B3C7-A5F307B90288}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {4B727A97-A002-46CA-B4ED-09C3E4A7EA25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {4B727A97-A002-46CA-B4ED-09C3E4A7EA25}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {4B727A97-A002-46CA-B4ED-09C3E4A7EA25}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {4B727A97-A002-46CA-B4ED-09C3E4A7EA25}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {99AE7570-216E-47A3-80CD-06D628B1EB09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {99AE7570-216E-47A3-80CD-06D628B1EB09}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {99AE7570-216E-47A3-80CD-06D628B1EB09}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {99AE7570-216E-47A3-80CD-06D628B1EB09}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {7419E439-0DED-49EC-ACAC-9A234DBCDBB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {7419E439-0DED-49EC-ACAC-9A234DBCDBB4}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {7419E439-0DED-49EC-ACAC-9A234DBCDBB4}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {7419E439-0DED-49EC-ACAC-9A234DBCDBB4}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {676059A0-AE5D-4A07-B1BD-CD23EB29EE90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {676059A0-AE5D-4A07-B1BD-CD23EB29EE90}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {676059A0-AE5D-4A07-B1BD-CD23EB29EE90}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {676059A0-AE5D-4A07-B1BD-CD23EB29EE90}.Release|Any CPU.Build.0 = Release|Any CPU 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /T4_Utilities/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /T4_Utilities/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CSharp 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /T4_Utilities/SQL Generator Utilities.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private readonly Dictionary _prefixes = new Dictionary(StringComparer.CurrentCultureIgnoreCase) 4 | { 5 | { "AdventureWorks2012", "adv" }, 6 | { "blog", "blog" }, 7 | { "finance", "fin" }, 8 | { "mvc_custom_controls", "mvc" }, 9 | { "nhqc", "ae" }, 10 | { "TSQL2012", "tsql" }, 11 | { "Utilities", "util" } 12 | }; 13 | 14 | private String GetStoredProcedureName(String database, String schema, String table, String operation) 15 | { 16 | /* Custom stored procedure naming scheme. 17 | 18 | The returned value serves as both a name for the stored procedure, and a valid 19 | filename for storing the stored procedure text (so it can 20 | be saved in source control). 21 | 22 | format: 23 | 24 | [schema].[prefix_sp_operation_table] 25 | 26 | where: 27 | 28 | schema = database schema name 29 | prefix = three or four letter identifier for a database 30 | operation = select, insert, update or delete 31 | table = table name 32 | 33 | examples: 34 | 35 | [dbo].[blog_sp_Select_Pages] 36 | [Person].[adv_sp_Insert_EmailAddress] 37 | 38 | */ 39 | 40 | var prefix = this._prefixes[database]; // Can throw KeyNotFoundException. 41 | 42 | return String.Format("[{0}].[{1}_sp_{2}_{3}]", schema, prefix, operation, table); 43 | } 44 | 45 | private static readonly Regex _valueRegex = new Regex(@"(Value\s*=\s*)(.*)\b", RegexOptions.Singleline); 46 | 47 | private String FixupSqlParameterValue(SqlParameter sqlParameter) 48 | { 49 | var s = ReflectionUtils.GetObjectInitializer(sqlParameter, "DbType", "SqlValue"); 50 | return _valueRegex.Replace(s, "$1" + Utilities.Sql.SqlServer.IdentifierHelper.GetTargetLanguageIdentifier(sqlParameter.ParameterName)); 51 | } 52 | 53 | private void SaveOutput(String path) 54 | { 55 | /* "this" refers to the T4 TextTransformation instance that's producing the output. 56 | See https://msdn.microsoft.com/en-us/library/Microsoft.VisualStudio.TextTemplating.TextTransformation.aspx. */ 57 | Directory.CreateDirectory(Path.GetDirectoryName(path)); 58 | File.WriteAllText(path, this.GenerationEnvironment.ToString()); 59 | this.GenerationEnvironment.Clear(); 60 | } 61 | 62 | #> 63 | -------------------------------------------------------------------------------- /T4_Utilities/T4_Utilities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {676059A0-AE5D-4A07-B1BD-CD23EB29EE90} 8 | Exe 9 | Properties 10 | T4_Utilities 11 | T4_Utilities 12 | v4.5.1 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /T4_Utilities/UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the PUBLIC DOMAIN. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Visual_Basic/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Visual_Basic/Data Access Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateDataAccessClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".DataLayer"; 8 | 9 | #> 10 | Imports System 11 | Imports System.Collections.Generic 12 | Imports System.Configuration 13 | Imports System.Data 14 | Imports System.Data.SqlClient 15 | 16 | Imports <#= IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".Entities" #> 17 | 18 | Imports Utilities.Sql 19 | 20 | Namespace <#= outputFilename #> 21 | <#+ 22 | 23 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 24 | { 25 | foreach (var table in schema.Tables.OrderBy(table => table.Name)) 26 | { 27 | 28 | #> 29 | Public Class <#= table.TargetLanguageIdentifier #>Methods 30 | Private Shared _connectionString = ConfigurationManager.ConnectionStrings("<#= IdentifierHelper.GetTargetLanguageIdentifier(database.Name) #>").ConnectionString 31 | 32 | <#+ 33 | var arguments = table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey, IncludeKeyIdentificationComment.No); 34 | if (arguments.Count == 0) 35 | { 36 | #> 37 | Public Shared Function Select<#= table.TargetLanguageIdentifier #>() As List(Of <#= table.TargetLanguageIdentifier #>) 38 | <#+ 39 | } 40 | else 41 | { 42 | #> 43 | Public Shared Function Select<#= table.TargetLanguageIdentifier #> _ 44 | ( 45 | <#= String.Join("," + Environment.NewLine + " ", arguments) #> 46 | ) As List(Of <#= table.TargetLanguageIdentifier #>) 47 | <#+ 48 | } 49 | #> 50 | Dim result As New List(Of <#= table.TargetLanguageIdentifier #>)() 51 | 52 | Using connection As New SqlConnection(_connectionString) 53 | connection.Open() 54 | 55 | Using command As New SqlCommand() With { .Connection = connection, .CommandType = CommandType.StoredProcedure, .CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Select") #>" } 56 | command.Parameters.Clear() 57 | <#+ 58 | var parameters = table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey, IncludeKeyIdentificationComment.No); 59 | if (parameters.Count > 0) 60 | { 61 | #> 62 | command.Parameters.Add(<#= String.Join(")" + Environment.NewLine + " command.Parameters.Add(", parameters) #>) 63 | <#+ 64 | } 65 | #> 66 | 67 | Using reader = command.ExecuteReader(CommandBehavior.CloseConnection) 68 | While reader.Read() 69 | result.Add( 70 | New <#= table.TargetLanguageIdentifier #>() With 71 | { 72 | <#= String.Join("," + Environment.NewLine + " ", 73 | table.Columns.OrderBy(column => column.Name) 74 | .Select(column => String.Format(".{0} = {1}", column.TargetLanguageIdentifier, column.GetTargetLanguageDataReaderExpression("reader")))) #> 75 | }) 76 | End While 77 | End Using 78 | 79 | Return result 80 | End Using 81 | End Using 82 | End Function 83 | 84 | <#+ 85 | 86 | /* Views don't need insert, update and delete methods. */ 87 | if (!table.IsView) 88 | { 89 | 90 | #> 91 | Public Shared Sub Insert<#= table.TargetLanguageIdentifier #> _ 92 | ( 93 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.CanAppearInInsertStatement, IncludeKeyIdentificationComment.No)) #> 94 | ) 95 | Using connection As New SqlConnection(_connectionString) 96 | connection.Open() 97 | 98 | Using command As New SqlCommand() With { .Connection = connection, .CommandType = CommandType.StoredProcedure, .CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Insert") #>" } 99 | command.Parameters.Clear() 100 | command.Parameters.Add(<#= String.Join(")" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.CanAppearInInsertStatement, IncludeKeyIdentificationComment.No)) #>) 101 | command.ExecuteNonQuery() 102 | End Using 103 | End Using 104 | End Sub 105 | 106 | Public Shared Sub Update<#= table.TargetLanguageIdentifier #> _ 107 | ( 108 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause, IncludeKeyIdentificationComment.No)) #> 109 | ) 110 | Using connection As New SqlConnection(_connectionString) 111 | connection.Open() 112 | 113 | Using command As New SqlCommand() With { .Connection = connection, .CommandType = CommandType.StoredProcedure, .CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Update") #>" } 114 | command.Parameters.Clear() 115 | command.Parameters.Add(<#= String.Join(")" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey | ColumnType.CanAppearInUpdateSetClause, IncludeKeyIdentificationComment.No)) #>) 116 | command.ExecuteNonQuery() 117 | End Using 118 | End Using 119 | End Sub 120 | 121 | Public Shared Sub Merge<#= table.TargetLanguageIdentifier #> _ 122 | ( 123 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList, IncludeKeyIdentificationComment.No)) #> 124 | ) 125 | Using connection As New SqlConnection(_connectionString) 126 | connection.Open() 127 | 128 | Using command As New SqlCommand() With { .Connection = connection, .CommandType = CommandType.StoredProcedure, .CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Merge") #>" } 129 | command.Parameters.Clear() 130 | command.Parameters.Add(<#= String.Join(")" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey | ColumnType.CanAppearInMergeSelectList, IncludeKeyIdentificationComment.No)) #>) 131 | command.ExecuteNonQuery() 132 | End Using 133 | End Using 134 | End Sub 135 | 136 | Public Shared Sub Delete<#= table.TargetLanguageIdentifier #> _ 137 | ( 138 | <#= String.Join("," + Environment.NewLine + " ", table.Columns.GetTargetLanguageMethodIdentifiersAndTypes(ColumnType.PrimaryKey, IncludeKeyIdentificationComment.No)) #> 139 | ) 140 | Using connection As New SqlConnection(_connectionString) 141 | connection.Open() 142 | 143 | Using command As New SqlCommand() With { .Connection = connection, .CommandType = CommandType.StoredProcedure, .CommandText = "<#= GetStoredProcedureName(database.Name, table.Schema.Name, table.Name, "Delete") #>" } 144 | command.Parameters.Clear() 145 | command.Parameters.Add(<#= String.Join(")" + Environment.NewLine + " command.Parameters.Add(", table.Columns.GetTargetLanguageSqlParameterText(ColumnType.PrimaryKey, IncludeKeyIdentificationComment.No)) #>) 146 | command.ExecuteNonQuery() 147 | End Using 148 | End Using 149 | End Sub 150 | 151 | <#+ 152 | } // if 153 | #> 154 | End Class 155 | 156 | <#+ 157 | } // foreach table 158 | } // foreach schema 159 | #> 160 | End Namespace 161 | 162 | <#+ 163 | 164 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".vb")); 165 | } // foreach database 166 | } 167 | #> -------------------------------------------------------------------------------- /Visual_Basic/Entity Classes.ttinclude: -------------------------------------------------------------------------------- 1 | <#+ 2 | 3 | private void GenerateEntityClasses(IEnumerable databases, String outputDirectory) 4 | { 5 | foreach (var database in databases) 6 | { 7 | var outputFilename = IdentifierHelper.GetTargetLanguageIdentifier(database.Name) + ".Entities"; 8 | 9 | #> 10 | Namespace <#= outputFilename #> 11 | <#+ 12 | 13 | foreach (var schema in database.Schemas.OrderBy(schema => schema.Name)) 14 | { 15 | foreach (var table in schema.Tables.OrderBy(table => table.Name)) 16 | { 17 | 18 | #> 19 | Public Class <#= table.TargetLanguageIdentifier #> 20 | <#= String.Join(Environment.NewLine + " ", table.Columns.GetClassPropertyDeclarations("Public")) #> 21 | End Class 22 | 23 | <#+ 24 | } // foreach table 25 | } // foreach schema 26 | #> 27 | End Namespace 28 | 29 | <#+ 30 | 31 | this.SaveOutput(Path.Combine(outputDirectory, outputFilename + ".vb")); 32 | } // foreach database 33 | } 34 | #> -------------------------------------------------------------------------------- /Visual_Basic/Main.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="true" language="C#" #> 2 | <#@ output extension=".txt" #> 3 | <#@ assembly name="System.Core" #> 4 | <#@ assembly name="System.Data" #> 5 | <#@ assembly name="System.Xml" #> 6 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll" #> 7 | <#@ assembly name="C:\users\ctimmons\documents\Data\Dev\Visual Studio\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll" #> 8 | <#@ import namespace="System.Collections.Generic" #> 9 | <#@ import namespace="System.Data" #> 10 | <#@ import namespace="System.Data.SqlClient" #> 11 | <#@ import namespace="System.IO" #> 12 | <#@ import namespace="System.Linq" #> 13 | <#@ import namespace="System.Text.RegularExpressions" #> 14 | <#@ import namespace="Utilities.Core" #> 15 | <#@ import namespace="Utilities.Sql.SqlServer" #> 16 | <#@ include file="..\T4_Utilities\SQL Generator Utilities.ttinclude" #> 17 | <#@ include file="Entity Classes.ttinclude" #> 18 | <#@ include file="Data Access Classes.ttinclude" #> 19 | <# 20 | 21 | using (var connection = new SqlConnection("Data Source=laptop2;Initial Catalog=AdventureWorks2012;Integrated Security=true;")) 22 | { 23 | connection.Open(); 24 | 25 | var configuration = 26 | new Configuration() 27 | { 28 | Connection = connection, 29 | XmlSystem = XmlSystem.Linq_XDocument, 30 | TargetLanguage = TargetLanguage.VisualBasic_Latest, 31 | XmlValidationLocation = XmlValidationLocation.PropertySetter 32 | }; 33 | 34 | var outputDirectory = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath(".")), "Output"); 35 | var server = new Server(configuration); 36 | var databaseNames = new List() { "AdventureWorks2012" }; 37 | var databases = 38 | server 39 | .Databases 40 | .Where(db => databaseNames.Contains(db.Name, CaseInsensitiveStringComparer.Instance)) 41 | .OrderBy(db => db.Name); 42 | 43 | this.GenerateEntityClasses(databases, outputDirectory); 44 | this.GenerateDataAccessClasses(databases, outputDirectory); 45 | } 46 | 47 | #> -------------------------------------------------------------------------------- /Visual_Basic/Module1.vb: -------------------------------------------------------------------------------- 1 | Module Module1 2 | 3 | Sub Main() 4 | 5 | End Sub 6 | 7 | End Module 8 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Application.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.34209 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Application.myapp: -------------------------------------------------------------------------------- 1 |  2 | 3 | false 4 | false 5 | 0 6 | true 7 | 0 8 | 2 9 | true 10 | 11 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 21 | 22 | 23 | ' Version information for an assembly consists of the following four values: 24 | ' 25 | ' Major Version 26 | ' Minor Version 27 | ' Build Number 28 | ' Revision 29 | ' 30 | ' You can specify all the values or you can default the Build and Revision Numbers 31 | ' by using the '*' as shown below: 32 | ' 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.34209 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | End Module 63 | End Namespace 64 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Settings.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:4.0.30319.34209 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | 15 | Namespace My 16 | 17 | _ 20 | Partial Friend NotInheritable Class MySettings 21 | Inherits Global.System.Configuration.ApplicationSettingsBase 22 | 23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) 24 | 25 | #Region "My.Settings Auto-Save Functionality" 26 | #If _MyType = "WindowsForms" Then 27 | Private Shared addedHandler As Boolean 28 | 29 | Private Shared addedHandlerLockObject As New Object 30 | 31 | _ 32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) 33 | If My.Application.SaveMySettingsOnExit Then 34 | My.Settings.Save() 35 | End If 36 | End Sub 37 | #End If 38 | #End Region 39 | 40 | Public Shared ReadOnly Property [Default]() As MySettings 41 | Get 42 | 43 | #If _MyType = "WindowsForms" Then 44 | If Not addedHandler Then 45 | SyncLock addedHandlerLockObject 46 | If Not addedHandler Then 47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings 48 | addedHandler = True 49 | End If 50 | End SyncLock 51 | End If 52 | #End If 53 | Return defaultInstance 54 | End Get 55 | End Property 56 | End Class 57 | End Namespace 58 | 59 | Namespace My 60 | 61 | _ 64 | Friend Module MySettingsProperty 65 | 66 | _ 67 | Friend ReadOnly Property Settings() As Global.My.MySettings 68 | Get 69 | Return Global.My.MySettings.Default 70 | End Get 71 | End Property 72 | End Module 73 | End Namespace 74 | -------------------------------------------------------------------------------- /Visual_Basic/My Project/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Visual_Basic/UNLICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the PUBLIC DOMAIN. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Visual_Basic/Visual_Basic.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4B727A97-A002-46CA-B4ED-09C3E4A7EA25} 8 | Exe 9 | Module1 10 | 11 | 12 | Visual_Basic 13 | 512 14 | Console 15 | v4.5.1 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | true 23 | true 24 | bin\Debug\ 25 | Visual_Basic.xml 26 | 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | false 32 | true 33 | true 34 | bin\Release\ 35 | Visual_Basic.xml 36 | 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 37 | 38 | 39 | On 40 | 41 | 42 | Binary 43 | 44 | 45 | Off 46 | 47 | 48 | Off 49 | 50 | 51 | 52 | False 53 | ..\..\..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Types.dll 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ..\..\..\cs_utilities\Utilities.Core\bin\Debug\Utilities.Core.dll 65 | 66 | 67 | ..\..\..\cs_utilities\Utilities.Sql\bin\Debug\Utilities.Sql.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | True 86 | Application.myapp 87 | 88 | 89 | True 90 | True 91 | Resources.resx 92 | 93 | 94 | True 95 | Settings.settings 96 | True 97 | 98 | 99 | 100 | 101 | VbMyResourcesResXFileCodeGenerator 102 | Resources.Designer.vb 103 | My.Resources 104 | Designer 105 | 106 | 107 | 108 | 109 | 110 | 111 | TextTemplatingFileGenerator 112 | Main.txt 113 | 114 | 115 | MyApplicationCodeGenerator 116 | Application.Designer.vb 117 | 118 | 119 | SettingsSingleFileGenerator 120 | My 121 | Settings.Designer.vb 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | True 131 | True 132 | Main.tt 133 | 134 | 135 | 136 | 143 | --------------------------------------------------------------------------------