From 4e69a030776dbbddea6f550d8ca0f7fccae2a73f Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Sat, 14 Dec 2024 15:21:11 +0100 Subject: [PATCH] Compensate for bad names from stored proc results fixes #2727 fixes #2729 --- src/Core/RevEng.Core.80/RevEng.Core.80.csproj | 1 + .../RevEng.Core.80/Routines/ScaffoldHelper.cs | 71 ++++++++++--------- .../RevEng.Core.80/Routines/Scaffolder.cs | 21 ++++-- src/Core/RevEng.Core.90/RevEng.Core.90.csproj | 1 + 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/Core/RevEng.Core.80/RevEng.Core.80.csproj b/src/Core/RevEng.Core.80/RevEng.Core.80.csproj index 59c360a2f..1992c3e70 100644 --- a/src/Core/RevEng.Core.80/RevEng.Core.80.csproj +++ b/src/Core/RevEng.Core.80/RevEng.Core.80.csproj @@ -31,6 +31,7 @@ + diff --git a/src/Core/RevEng.Core.80/Routines/ScaffoldHelper.cs b/src/Core/RevEng.Core.80/Routines/ScaffoldHelper.cs index 8ce04bcfb..7c1fe8c2a 100644 --- a/src/Core/RevEng.Core.80/Routines/ScaffoldHelper.cs +++ b/src/Core/RevEng.Core.80/Routines/ScaffoldHelper.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Unicode; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Scaffolding; using RevEng.Core.Abstractions.Metadata; @@ -151,7 +152,7 @@ public static string GenerateIdentifierName(Routine routine, RoutineModel model, { var name = GenerateUniqueName(routine, model); - return CreateIdentifier(name, name, false).Item1; + return CreateIdentifier(name, name, code).Item1; } else { @@ -167,62 +168,68 @@ public static Tuple GeneratePropertyName(string propertyName, IC if (!usePascalCase) { - return CreateIdentifier(propertyName, propertyName, false); + return CreateIdentifier(propertyName, propertyName, code); } else { - var identifier = code.Identifier(propertyName, capitalize: true); + var name = GenerateIdentifier(code.Identifier(propertyName, capitalize: true)); - return CreateIdentifier(GenerateIdentifier(identifier), propertyName, true); + string columAttribute = null; + if (!name.Equals(propertyName, StringComparison.Ordinal)) + { + columAttribute = $"[Column(\"{propertyName}\")]"; + } + + return new Tuple(name, columAttribute); } } - public static Tuple CreateIdentifier(string name, string propertyName, bool usePascalCase) + public static Tuple CreateIdentifier(string name, string propertyName, ICSharpHelper code) { - if (!usePascalCase) - { - var original = name; + var original = name; - var isValid = System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(name); + var isValid = System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(name); - string columAttribute = null; + string columAttribute = null; + + if (!isValid) + { + columAttribute = $"[Column(\"{name}\")]"; - if (!isValid) + // File name contains invalid chars, remove them + var regex = new Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]", RegexOptions.None, TimeSpan.FromSeconds(5)); + name = regex.Replace(name, string.Empty); + + if (string.IsNullOrWhiteSpace(name)) { - columAttribute = $"[Column(\"{name}\")]"; + var fixedName = string.Empty; + foreach (var chr in original) + { +#pragma warning disable S1643 // Strings should not be concatenated using '+' in a loop + fixedName += UnicodeInfo.GetName(chr) + " "; +#pragma warning restore S1643 // Strings should not be concatenated using '+' in a loop + } - // File name contains invalid chars, remove them - var regex = new Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]", RegexOptions.None, TimeSpan.FromSeconds(5)); - name = regex.Replace(name, string.Empty); + name = GenerateIdentifier(fixedName); if (string.IsNullOrWhiteSpace(name)) { // we cannot fix it name = original; } - else if (!char.IsLetter(name, 0)) - { - name = name.Insert(0, "_"); - } } - - if (KeyWords.Contains(name)) + else if (!char.IsLetter(name, 0)) { - name = "@" + name; + name = name.Insert(0, "_"); } - - return new Tuple(name.Replace(" ", string.Empty, StringComparison.OrdinalIgnoreCase), columAttribute); } - else - { - string columAttribute = null; - if (!name.Equals(propertyName, StringComparison.Ordinal)) - { - columAttribute = $"[Column(\"{propertyName}\")]"; - } - return new Tuple(name, columAttribute); + if (KeyWords.Contains(name)) + { + name = "@" + name; } + + return new Tuple(name.Replace(" ", string.Empty, StringComparison.OrdinalIgnoreCase), columAttribute); } private static string GenerateUniqueName(Routine routine, RoutineModel model) diff --git a/src/Core/RevEng.Core.80/Routines/Scaffolder.cs b/src/Core/RevEng.Core.80/Routines/Scaffolder.cs index c119ac8d1..5d17fb3a6 100644 --- a/src/Core/RevEng.Core.80/Routines/Scaffolder.cs +++ b/src/Core/RevEng.Core.80/Routines/Scaffolder.cs @@ -88,9 +88,13 @@ private void GenerateClass(List resultElements, string name private void GenerateProperties(List resultElements, bool nullableReferences, bool useDecimalDataAnnotation, bool usePascalCase) { + var propertyNames = new List(); + + int i = 0; + foreach (var property in resultElements.OrderBy(e => e.Ordinal)) { - var propertyNames = ScaffoldHelper.GeneratePropertyName(property.Name, Code, usePascalCase); + var propertyNameAndAttribute = ScaffoldHelper.GeneratePropertyName(property.Name, Code, usePascalCase); if (property.StoreType == "decimal" && useDecimalDataAnnotation) { @@ -98,9 +102,9 @@ private void GenerateProperties(List resultElements, bool n } else { - if (!string.IsNullOrEmpty(propertyNames.Item2)) + if (!string.IsNullOrEmpty(propertyNameAndAttribute.Item2)) { - Sb.AppendLine(propertyNames.Item2); + Sb.AppendLine(propertyNameAndAttribute.Item2); } } @@ -128,7 +132,16 @@ private void GenerateProperties(List resultElements, bool n } } - Sb.AppendLine($"public {Code.Reference(propertyType)}{nullableAnnotation} {propertyNames.Item1} {{ get; set; }}{defaultAnnotation}"); + var propertyName = propertyNameAndAttribute.Item1; + + if (propertyNames.Contains(propertyName, StringComparer.Ordinal)) + { + propertyName = $"{propertyName}_Duplicate{i++}"; + } + + propertyNames.Add(propertyNameAndAttribute.Item1); + + Sb.AppendLine($"public {Code.Reference(propertyType)}{nullableAnnotation} {propertyName} {{ get; set; }}{defaultAnnotation}"); } } } diff --git a/src/Core/RevEng.Core.90/RevEng.Core.90.csproj b/src/Core/RevEng.Core.90/RevEng.Core.90.csproj index d4a946640..8be417319 100644 --- a/src/Core/RevEng.Core.90/RevEng.Core.90.csproj +++ b/src/Core/RevEng.Core.90/RevEng.Core.90.csproj @@ -44,6 +44,7 @@ +