Skip to content

Commit

Permalink
Generate class and validation code inside single namespaces. (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
EndsOfTheEarth authored Jul 1, 2023
1 parent 96f32b9 commit 162fbc5
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 64 deletions.
4 changes: 2 additions & 2 deletions CodeGeneratorUI/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,13 @@ private void UpdateCode(bool updatePrefix) {

txtCode.Text += Environment.NewLine;

CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(_database, table, prefix, settings);
CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(_database, table, prefix, settings, includeUsings: true);

txtCode.Text += Environment.NewLine + classCode.ToString();

if(!table.IsView) {

CodeBuilder validationCode = FluentValidationGenerator.GenerateFluentValidationCode(_database, table, prefix, useIdentifiers: chkUseIdentifiers.Checked, namespaces);
CodeBuilder validationCode = FluentValidationGenerator.GenerateFluentValidationCode(table, prefix, settings, includeUsings: true);

txtCode.Text += Environment.NewLine + Environment.NewLine + validationCode.ToString();
}
Expand Down
59 changes: 53 additions & 6 deletions DbSchema/CodeGeneration/ClassCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,73 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**/
using QueryLite.DbSchema.Tables;
using System;
using System.Collections.Generic;
using System.Linq;

namespace QueryLite.DbSchema.CodeGeneration {

public static class ClassCodeGenerator {

public static CodeBuilder GenerateClassCode(IDatabase database, DatabaseTable table, TablePrefix prefix, CodeGeneratorSettings settings) {
public static CodeBuilder Generate(IDatabase database, List<DatabaseTable> tables, CodeGeneratorSettings settings) {

CodeBuilder code = new CodeBuilder();

code.Append("using System;").EndLine();
code.Append("using QueryLite;").EndLine();

List<StringKey<ISchemaName>> schemaNames = new List<StringKey<ISchemaName>>();

foreach(DatabaseTable table in tables) {

if(!schemaNames.Contains(table.Schema)) {
schemaNames.Add(table.Schema);
}
}

schemaNames.Sort((a, b) => a.Value.CompareTo(b.Value));

int count = 0;

foreach(StringKey<ISchemaName> schema in schemaNames) {

if(count > 0) {
code.EndLine();
}
count++;
code.EndLine().Append($"namespace {settings.Namespaces.GetTableNamespace(schema)} {{").EndLine();

foreach(DatabaseTable table in tables) {

if(string.Equals(table.Schema.Value, schema.Value, StringComparison.OrdinalIgnoreCase)) {
TablePrefix prefix = new TablePrefix(table);
code.Append(GenerateClassCode(database, table, prefix, settings, includeUsings: false).ToString());
}
}
code.Append("}");
}
return code;
}

public static CodeBuilder GenerateClassCode(IDatabase database, DatabaseTable table, TablePrefix prefix, CodeGeneratorSettings settings, bool includeUsings) {

CodeBuilder classCode = new CodeBuilder();

classCode.Append($"namespace {settings.Namespaces.GetClassesNamespace(table.Schema)} {{").EndLine().EndLine();
classCode.Indent(1).Append("using System;").EndLine();
classCode.Indent(1).Append("using QueryLite;").EndLine();
if(includeUsings) {
classCode.Append($"namespace {settings.Namespaces.GetClassesNamespace(table.Schema)} {{").EndLine().EndLine();
classCode.Indent(1).Append("using System;").EndLine();
classCode.Indent(1).Append("using QueryLite;").EndLine();

classCode.Indent(1).Append($"using {settings.Namespaces.TableNamespace};").EndLine();
classCode.Indent(1).Append($"using {settings.Namespaces.TableNamespace};").EndLine();


string tableNamespace = settings.Namespaces.GetTableNamespace(table.Schema);

if(settings.Namespaces.TableNamespace != tableNamespace) { //If this table exist in a non default schema it will have a different namespace
classCode.Indent(1).Append($"using {tableNamespace};").EndLine();
}
}

if(settings.IncludeMessagePackAttributes) {
classCode.Indent(1).Append("using MessagePack;").EndLine();
Expand Down Expand Up @@ -165,7 +210,9 @@ public static CodeBuilder GenerateClassCode(IDatabase database, DatabaseTable ta
classCode.EndLine();
classCode.Indent(1).Append("}").EndLine();

classCode.Append("}");
if(includeUsings) {
classCode.Append("}");
}
return classCode;
}
}
Expand Down
2 changes: 1 addition & 1 deletion DbSchema/CodeGeneration/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public static void GenerateToFiles(string dirPath, IDatabase database, List<Data
string tableFilePath = Path.Combine(tablesDir, CodeHelper.GetTableName(table, includePostFix: true) + ".cs");
File.WriteAllText(tableFilePath, code.ToString());

CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(database, table, prefix, settings);
CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(database, table, prefix, settings, includeUsings: true);

string logicFilePath = Path.Combine(logicDir, CodeHelper.GetTableName(table, includePostFix: true) + ".cs");
File.WriteAllText(logicFilePath, classCode.ToString());
Expand Down
74 changes: 57 additions & 17 deletions DbSchema/CodeGeneration/FluentValidationGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,71 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**/
using QueryLite.DbSchema.Tables;
using System;
using System.Collections.Generic;

namespace QueryLite.DbSchema.CodeGeneration {

public static class FluentValidationGenerator {

public static CodeBuilder GenerateFluentValidationCode(IDatabase database, DatabaseTable table, TablePrefix prefix, bool useIdentifiers, Namespaces namespaces) {
public static CodeBuilder Generate(List<DatabaseTable> tables, CodeGeneratorSettings settings) {

CodeBuilder code = new CodeBuilder();

//code.Append("using System;").EndLine();
code.Append("using FluentValidation;").EndLine();

List<StringKey<ISchemaName>> schemaNames = new List<StringKey<ISchemaName>>();

foreach(DatabaseTable table in tables) {

if(!schemaNames.Contains(table.Schema)) {
schemaNames.Add(table.Schema);
}
}

schemaNames.Sort((a, b) => a.Value.CompareTo(b.Value));

int count = 0;

foreach(StringKey<ISchemaName> schema in schemaNames) {

if(count > 0) {
code.EndLine();
}
count++;
code.EndLine().Append($"namespace {settings.Namespaces.GetTableNamespace(schema)} {{").EndLine();

foreach(DatabaseTable table in tables) {

if(string.Equals(table.Schema.Value, schema.Value, StringComparison.OrdinalIgnoreCase)) {
TablePrefix prefix = new TablePrefix(table);
code.Append(GenerateFluentValidationCode(table, prefix, settings, includeUsings: false).ToString());
}
}
code.Append("}");
}
return code;
}

public static CodeBuilder GenerateFluentValidationCode(DatabaseTable table, TablePrefix prefix, CodeGeneratorSettings settings, bool includeUsings) {

CodeBuilder classCode = new CodeBuilder();

classCode.Append($"namespace {namespaces.GetClassesNamespace(table.Schema)} {{").EndLine().EndLine();
classCode.Indent(1).Append("using System;").EndLine();
classCode.Indent(1).Append("using FluentValidation;").EndLine();
if(includeUsings) {

classCode.Indent(1).Append($"using {namespaces.TableNamespace};").EndLine();
classCode.Append($"namespace {settings.Namespaces.GetClassesNamespace(table.Schema)} {{").EndLine().EndLine();

string tableNamespace = namespaces.GetTableNamespace(table.Schema);
classCode.Indent(1).Append("using FluentValidation;").EndLine();

if(namespaces.TableNamespace != tableNamespace) { //If this table exist in a non default schema it will have a different namespace
classCode.Indent(1).Append($"using {tableNamespace};").EndLine();
classCode.Indent(1).Append($"using {settings.Namespaces.TableNamespace};").EndLine();

string tableNamespace = settings.Namespaces.GetTableNamespace(table.Schema);

if(settings.Namespaces.TableNamespace != tableNamespace) { //If this table exist in a non default schema it will have a different namespace
classCode.Indent(1).Append($"using {tableNamespace};").EndLine();
}
}

string className = CodeHelper.GetTableName(table, includePostFix: false);
Expand Down Expand Up @@ -73,7 +118,7 @@ public static CodeBuilder GenerateFluentValidationCode(IDatabase database, Datab
continue;
}

CodeHelper.GetColumnName(table, column, useIdentifiers: useIdentifiers, dotNetType: out Type dotNetType, columnTypeName: out string _, out bool isKeyColumn);
CodeHelper.GetColumnName(table, column, useIdentifiers: settings.UseIdentifiers, dotNetType: out Type dotNetType, columnTypeName: out string _, out bool isKeyColumn);

string columnName = prefix.GetColumnName(column.ColumnName.Value, className: null);

Expand Down Expand Up @@ -105,13 +150,6 @@ public static CodeBuilder GenerateFluentValidationCode(IDatabase database, Datab

bool hasRule = false;

//column.DataType.DotNetType.

//if(!column.IsAutoGenerated && !column.IsNullable && !column.DataType.DotNetType.IsValueType) {
// rule.Append(".NotNull()");
// hasRule = true;
//}

bool addBeginAndEndLine = false;

if(column.Length != null) {
Expand Down Expand Up @@ -170,7 +208,9 @@ public static CodeBuilder GenerateFluentValidationCode(IDatabase database, Datab

classCode.Append(validateCode.ToString());

classCode.Append("}");
if(includeUsings) {
classCode.Append("}");
}
return classCode;
}
}
Expand Down
15 changes: 9 additions & 6 deletions DbSchema/CodeGeneration/Namespaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,19 @@
**/
using QueryLite.DbSchema.Tables;
using System;
using System.Xml.Linq;

namespace QueryLite.DbSchema.CodeGeneration {

public sealed class Namespaces {

public Namespaces(string baseNamespace, string tableNamespace, string classNamespace) {
BaseNamespace = baseNamespace;
TableNamespace = tableNamespace;
ClassNamespace = classNamespace;
BaseNamespace = FirstLetterUpperCase(baseNamespace);
TableNamespace = FirstLetterUpperCase(tableNamespace);
ClassNamespace = FirstLetterUpperCase(classNamespace);
}

private string FirstLetterUpperCase(string value) {
return !string.IsNullOrEmpty(value) ? $"{char.ToUpper(value[0])}{value.Substring(startIndex: 1)}" : string.Empty;
}
public string BaseNamespace { get; set; }
public string TableNamespace { get; set; }
Expand All @@ -42,7 +45,7 @@ public string GetTableNamespace(StringKey<ISchemaName> schema) {

string schemaName = schema.Value;

schemaName = !string.IsNullOrEmpty(schemaName) ? $"{char.ToUpper(schemaName[0])}{schemaName.Substring(startIndex: 1)}" : string.Empty;
schemaName = FirstLetterUpperCase(schemaName);

if(!IsDefaultSchema(schema)) {
return $"{TableNamespace}.{schemaName}";
Expand All @@ -56,7 +59,7 @@ public string GetClassesNamespace(StringKey<ISchemaName> schema) {

string schemaName = schema.Value;

schemaName = !string.IsNullOrEmpty(schemaName) ? $"{char.ToUpper(schemaName[0])}{schemaName.Substring(startIndex: 1)}" : string.Empty;
schemaName = FirstLetterUpperCase(schemaName);

if(!IsDefaultSchema(schema)) {
return $"{ClassNamespace}.{schemaName}";
Expand Down
45 changes: 13 additions & 32 deletions DbSchema/CodeGeneration/OutputToFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace QueryLite.DbSchema.CodeGeneration {

Expand All @@ -36,64 +35,46 @@ public static void Output(List<DatabaseTable> tables, Namespaces namespaces, Cod
throw new ArgumentException($"{nameof(folder)} = '{folder}' does not exist");
}

StringBuilder classesText = new StringBuilder();
StringBuilder fluentValidationText = new StringBuilder();

string tablesFolder = Path.Combine(folder, "Tables");
string classesFolder = Path.Combine(folder, "Classes");
string validationFolder = Path.Combine(folder, "Validation");

if(singleFiles) {

Directory.CreateDirectory(tablesFolder);
Directory.CreateDirectory(classesFolder);
Directory.CreateDirectory(validationFolder);
}

foreach(DatabaseTable table in tables) {

if(classesText.Length > 0) {
classesText.Append(Environment.NewLine).Append(Environment.NewLine);
}
TablePrefix prefix = new TablePrefix(table);

CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(database, table, prefix, settings);
foreach(DatabaseTable table in tables) {

classesText.Append(classCode.ToString());

if(!table.IsView) {
CodeBuilder validationCode = FluentValidationGenerator.GenerateFluentValidationCode(database, table, prefix, settings.UseIdentifiers, namespaces);
fluentValidationText.Append(validationCode.ToString());
}

if(singleFiles) {
TablePrefix prefix = new TablePrefix(table);

CodeBuilder tableCode = TableCodeGenerator.Generate(new List<DatabaseTable>() { table }, settings);

string tableFileName = Path.Combine(tablesFolder, CodeHelper.GetTableName(table, includePostFix: true) + ".cs");
File.WriteAllText(tableFileName, tableCode.ToString());

CodeBuilder classCode = ClassCodeGenerator.GenerateClassCode(database, table, prefix, settings, includeUsings: true);

string classesFileName = Path.Combine(classesFolder, CodeHelper.GetTableName(table, includePostFix: false) + (table.IsView ? "View" : string.Empty) + ".cs");
File.WriteAllText(classesFileName, classesText.ToString());
classesText.Clear();
File.WriteAllText(classesFileName, classCode.ToString());

if(!table.IsView) {
CodeBuilder validationCode = FluentValidationGenerator.GenerateFluentValidationCode(table, prefix, settings, includeUsings: true);
string validationFileName = Path.Combine(validationFolder, CodeHelper.GetTableName(table, includePostFix: false) + "Validation.cs");
File.WriteAllText(validationFileName, fluentValidationText.ToString());
fluentValidationText.Clear();
File.WriteAllText(validationFileName, validationCode.ToString());
}
}
else {
fluentValidationText.Append(Environment.NewLine).Append(Environment.NewLine);
}
}

if(!singleFiles) {
else {

CodeBuilder tableCode = TableCodeGenerator.Generate(tables, settings);
CodeBuilder classCode = ClassCodeGenerator.Generate(database, tables, settings);
CodeBuilder validationCode = FluentValidationGenerator.Generate(tables, settings);

File.WriteAllText(Path.Combine(folder, "Tables.cs"), tableCode.ToString());
File.WriteAllText(Path.Combine(folder, "Classes.cs"), classesText.ToString());
File.WriteAllText(Path.Combine(folder, "Validation.cs"), fluentValidationText.ToString().TrimEnd());
File.WriteAllText(Path.Combine(folder, "Classes.cs"), classCode.ToString());
File.WriteAllText(Path.Combine(folder, "Validation.cs"), validationCode.ToString());
}
}
}
Expand Down

0 comments on commit 162fbc5

Please sign in to comment.