Skip to content

Commit

Permalink
Fix stringlen part2 (#2696)
Browse files Browse the repository at this point in the history
* revert

* More stringlength fixes
  • Loading branch information
ErikEJ authored Dec 3, 2024
1 parent 199e8b1 commit ce656a0
Show file tree
Hide file tree
Showing 17 changed files with 571 additions and 381 deletions.
229 changes: 221 additions & 8 deletions src/Core/RevEng.Core.80/Routines/Functions/FunctionScaffolder.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,242 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Scaffolding;
using NetTopologySuite.Geometries;
using RevEng.Common;
using RevEng.Core.Abstractions;
using RevEng.Core.Abstractions.Metadata;
using RevEng.Core.Routines.Extensions;

namespace RevEng.Core.Routines.Functions
{
public abstract class FunctionScaffolder : RoutineScaffolder
public abstract class FunctionScaffolder : IRoutineScaffolder
{
#pragma warning disable SA1401 // Fields should be private
internal readonly ICSharpHelper Code;
internal IndentedStringBuilder Sb;
#pragma warning restore SA1401 // Fields should be private
private readonly IClrTypeMapper typeMapper;

protected FunctionScaffolder([System.Diagnostics.CodeAnalysis.NotNull] ICSharpHelper code, IClrTypeMapper typeMapper)
: base(code, typeMapper)
{
ArgumentNullException.ThrowIfNull(code);

Code = code;
this.typeMapper = typeMapper;
}

public new string FileNameSuffix { get; set; }
public string FileNameSuffix { get; set; }

public new SavedModelFiles Save(ScaffoldedModel scaffoldedModel, string outputDir, string nameSpaceValue, bool useAsyncCalls)
public SavedModelFiles Save(ScaffoldedModel scaffoldedModel, string outputDir, string nameSpaceValue, bool useAsyncCalls)
{
return base.Save(scaffoldedModel, outputDir, nameSpaceValue, useAsyncCalls);
ArgumentNullException.ThrowIfNull(scaffoldedModel);

Directory.CreateDirectory(outputDir);

var contextPath = Path.GetFullPath(Path.Combine(outputDir, scaffoldedModel.ContextFile.Path));
var path = Path.GetDirectoryName(contextPath);
if (path != null)
{
Directory.CreateDirectory(path);
File.WriteAllText(contextPath, scaffoldedModel.ContextFile.Code, Encoding.UTF8);
}

var additionalFiles = new List<string>();

foreach (var entityTypeFile in scaffoldedModel.AdditionalFiles)
{
var additionalFilePath = Path.Combine(outputDir, entityTypeFile.Path);
var addpath = Path.GetDirectoryName(additionalFilePath);
if (addpath != null)
{
Directory.CreateDirectory(addpath);
File.WriteAllText(additionalFilePath, entityTypeFile.Code, Encoding.UTF8);
additionalFiles.Add(additionalFilePath);
}
}

return new SavedModelFiles(contextPath, additionalFiles);
}

public new ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List<string> schemas, ref List<string> errors)
public ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List<string> schemas, ref List<string> errors)
{
ArgumentNullException.ThrowIfNull(model);

ArgumentNullException.ThrowIfNull(errors);

ArgumentNullException.ThrowIfNull(scaffolderOptions);

var result = new ScaffoldedModel();
var path = string.Empty;

errors.AddRange(model.Errors);

schemas = schemas ?? new List<string>();

foreach (var routine in model.Routines.Where(r => string.IsNullOrEmpty(r.MappedType) && (!(r is Function f) || !f.IsScalar)))
{
var i = 1;

foreach (var resultSet in routine.Results)
{
if (routine.NoResultSet)
{
continue;
}

var suffix = string.Empty;
if (routine.Results.Count > 1)
{
suffix = $"{i++}";
}

var typeName = ScaffoldHelper.GenerateIdentifierName(routine, model, Code, scaffolderOptions.UsePascalIdentifiers) + "Result" + suffix;

var classContent = WriteResultClass(resultSet, scaffolderOptions, typeName, routine.Schema);

if (!string.IsNullOrEmpty(routine.Schema))
{
schemas.Add($"{routine.Schema}Schema");
}

path = scaffolderOptions.UseSchemaFolders
? Path.Combine(routine.Schema, $"{typeName}.cs")
: $"{typeName}.cs";
#if CORE90
result.AdditionalFiles.Add(new ScaffoldedFile(path, classContent));
#else
result.AdditionalFiles.Add(new ScaffoldedFile
{
Code = classContent,
Path = path,
});
#endif
}
}

var dbContext = WriteDbContext(scaffolderOptions, model, schemas.Distinct().ToList());

path = Path.GetFullPath(Path.Combine(scaffolderOptions.ContextDir, scaffolderOptions.ContextName + $"{FileNameSuffix}.cs"));
#if CORE90
result.ContextFile = new ScaffoldedFile(path, dbContext);
#else
result.ContextFile = new ScaffoldedFile
{
Code = dbContext,
Path = path,
};
#endif
return result;
}

protected abstract string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List<string> schemas);

private string WriteResultClass(List<ModuleResultElement> resultElements, ModuleScaffolderOptions options, string name, string schemaName)
{
return base.ScaffoldModel(model, scaffolderOptions, schemas, ref errors);
var @namespace = options.ModelNamespace;

Sb = new IndentedStringBuilder();

Sb.AppendLine(PathHelper.Header);

if (resultElements.Exists(p => typeMapper.GetClrType(p) == typeof(Geometry)))
{
Sb.AppendLine("using NetTopologySuite.Geometries;");
}

Sb.AppendLine("using System;");
Sb.AppendLine("using System.Collections.Generic;");
if (options.UseDecimalDataAnnotation)
{
Sb.AppendLine("using System.ComponentModel.DataAnnotations;");
}

Sb.AppendLine("using System.ComponentModel.DataAnnotations.Schema;");
Sb.AppendLine();

if (options.NullableReferences)
{
Sb.AppendLine("#nullable enable");
Sb.AppendLine();
}

Sb.AppendLine($"namespace {@namespace}{(options.UseSchemaNamespaces ? $".{schemaName}Schema" : string.Empty)}");
Sb.AppendLine("{");

using (Sb.Indent())
{
GenerateClass(resultElements, name, options.NullableReferences, options.UseDecimalDataAnnotation, options.UsePascalIdentifiers);
}

Sb.AppendLine("}");

return Sb.ToString();
}

private void GenerateClass(List<ModuleResultElement> resultElements, string name, bool nullableReferences, bool useDecimalDataAnnotation, bool usePascalCase)
{
Sb.AppendLine($"public partial class {name}");
Sb.AppendLine("{");

using (Sb.Indent())
{
GenerateProperties(resultElements, nullableReferences, useDecimalDataAnnotation, usePascalCase);
}

Sb.AppendLine("}");
}

private void GenerateProperties(List<ModuleResultElement> resultElements, bool nullableReferences, bool useDecimalDataAnnotation, bool usePascalCase)
{
foreach (var property in resultElements.OrderBy(e => e.Ordinal))
{
var propertyNames = ScaffoldHelper.GeneratePropertyName(property.Name, Code, usePascalCase);

if (property.StoreType == "decimal" && useDecimalDataAnnotation)
{
Sb.AppendLine($"[Column(\"{property.Name}\", TypeName = \"{property.StoreType}({property.Precision},{property.Scale})\")]");
}
else
{
if (!string.IsNullOrEmpty(propertyNames.Item2))
{
Sb.AppendLine(propertyNames.Item2);
}
}

if (useDecimalDataAnnotation
&& ((property.StoreType.StartsWith("varchar", StringComparison.OrdinalIgnoreCase)

Check failure on line 213 in src/Core/RevEng.Core.80/Routines/Functions/FunctionScaffolder.cs

View workflow job for this annotation

GitHub Actions / build

Check failure on line 213 in src/Core/RevEng.Core.80/Routines/Functions/FunctionScaffolder.cs

View workflow job for this annotation

GitHub Actions / build

Check failure on line 213 in src/Core/RevEng.Core.80/Routines/Functions/FunctionScaffolder.cs

View workflow job for this annotation

GitHub Actions / build

|| property.StoreType.StartsWith("nvarchar", StringComparison.OrdinalIgnoreCase))
&& property.MaxLength > 0))
{
var maxLength = property.StoreType.StartsWith("varchar", StringComparison.OrdinalIgnoreCase) ? property.MaxLength : property.MaxLength / 2;

Sb.AppendLine($"[StringLength({maxLength})]");
}

var propertyType = typeMapper.GetClrType(property);
var nullableAnnotation = string.Empty;
var defaultAnnotation = string.Empty;

if (nullableReferences && !propertyType.IsValueType)
{
if (property.Nullable)
{
nullableAnnotation = "?";
}
else
{
defaultAnnotation = $" = default!;";
}
}

Sb.AppendLine($"public {Code.Reference(propertyType)}{nullableAnnotation} {propertyNames.Item1} {{ get; set; }}{defaultAnnotation}");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ public SqlServerFunctionScaffolder([NotNull] ICSharpHelper code, IClrTypeMapper
FileNameSuffix = ".Functions";
}

protected override void GenerateProcedure(Routine procedure, RoutineModel model, bool signatureOnly, bool useAsyncCalls, bool usePascalCase)
{
}

protected override string WriteDbContext(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List<string> schemas)
{
ArgumentNullException.ThrowIfNull(scaffolderOptions);
Expand Down
Loading

0 comments on commit ce656a0

Please sign in to comment.