Skip to content

Commit

Permalink
Improvement: Updated to respect new Stored Procedure stereotypes intr…
Browse files Browse the repository at this point in the history
…oduced in version `1.1.1` of the `Intent.Modelers.Domain.StoredProcedures` module.
  • Loading branch information
JonathanLydall committed Sep 20, 2024
1 parent a172758 commit 44c7309
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using Intent.Metadata.Models;
using Intent.Modelers.Domain.Api;
using Intent.Modules.Common;

namespace Intent.Modules.EntityFrameworkCore.Repositories.Api
{
/// <summary>
/// This file was created manually since these stereotypes use a function to determine applicability.
/// Stereotypes defined in the "Intent.Modelers.Domain.StoredProcedures" module.
/// </summary>
internal static class StoredProcedureStereotypeExtensions
{
public static bool TryGetStoredProcedure(this OperationModel operation, out StoredProcedureStereotype storedProcedureStereotype)
{
var stereotype = operation.GetStereotype(StoredProcedureStereotype.Id);
if (stereotype == null)
{
storedProcedureStereotype = default;
return false;
}

storedProcedureStereotype = new StoredProcedureStereotype(stereotype);
return true;
}

public static bool TryGetStoredProcedureParameter(this ParameterModel parameter,
out StoredProcedureParameterStereotype storedProcedureParameterStereotype)
{
var stereotype = parameter.GetStereotype(StoredProcedureParameterStereotype.Id);
if (stereotype == null)
{
storedProcedureParameterStereotype = default;
return false;
}

storedProcedureParameterStereotype = new StoredProcedureParameterStereotype(stereotype);
return true;
}
}

internal class StoredProcedureStereotype
{
private readonly IStereotype _stereotype;

public StoredProcedureStereotype(IStereotype stereotype)
{
_stereotype = stereotype;
}

public const string Id = "f40ff84c-68ad-405f-bda0-1237dd15fc92";

public string GetName() => _stereotype.GetProperty("4e2a3f58-6b6e-43c5-9398-f9c3fde593f6").Value;
}

internal class StoredProcedureParameterStereotype
{
private readonly IStereotype _stereotype;

public StoredProcedureParameterStereotype(IStereotype stereotype)
{
_stereotype = stereotype;
}

public const string Id = "6ac91fd5-206c-49da-b4a2-b6ea2cad11f7";

public string GetName() => _stereotype.GetProperty("714a95a6-c3ef-4117-a66c-24876c675cd5").Value;
public StoredProcedureParameterDirection GetDirection()
{
var value = _stereotype.GetProperty("39491728-8327-4b94-b9a2-9851dd4b4a01").Value;

return value switch
{
"In" => StoredProcedureParameterDirection.In,
"Out" => StoredProcedureParameterDirection.Out,
"Both" => StoredProcedureParameterDirection.Both,
_ => throw new Exception($"Unknown value: {value}")
};
}

public string GetSqlStringType() => _stereotype.GetProperty<string>("8ba486d3-853c-42b8-acfb-bafb1e2cdb6e");
public int? GetSize() => _stereotype.GetProperty<int?>("a2df34af-2fb9-49e3-ab6e-caff7a27bf99");
public int? GetPrecision() => _stereotype.GetProperty<int?>("ed35ae5c-a708-457d-a22a-145b3b2f1148");
public int? GetScale() => _stereotype.GetProperty<int?>("38d3c607-ac3b-41ea-86b2-b43fa81e101c");
}

internal enum StoredProcedureParameterDirection { In, Out, Both }
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected override void OnAfterTemplateRegistrations(IApplication application)

foreach (var (entity, repository) in classRepositories)
{
var storedProcedures = repository.GetStoredProcedureModels();
var storedProcedures = repository.GetGeneralizedStoredProcedures();
if (!storedProcedures.Any())
{
continue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<package>
<id>Intent.EntityFrameworkCore.Repositories</id>
<version>4.6.4-pre.2</version>
<supportedClientVersions>[4.2.4-a, 5.0.0-a)</supportedClientVersions>
<version>4.7.0-pre.3</version>
<supportedClientVersions>[4.3.0-a, 5.0.0-a)</supportedClientVersions>
<summary>Generates Repositories for Domain Entities</summary>
<description>Generates Repositories for Domain Entities</description>
<authors>Intent Architect</authors>
Expand Down Expand Up @@ -70,7 +70,7 @@
<dependency id="Intent.Metadata.RDBMS" version="3.6.1" />
<dependency id="Intent.Modelers.Domain" version="3.9.0" />
<dependency id="Intent.Modelers.Domain.Repositories" version="3.5.0" />
<dependency id="Intent.Modules.Modelers.Domain.StoredProcedures" version="1.1.0" />
<dependency id="Intent.Modules.Modelers.Domain.StoredProcedures" version="1.1.1-pre.0" />
<dependency id="Intent.OutputManager.RoslynWeaver" version="4.5.1" />
</dependencies>
<files>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Version>4.6.4-pre.2</Version>
<Version>4.7.0-pre.3</Version>
<PackageProjectUrl>https://intentarchitect.com</PackageProjectUrl>
<PackageIconUrl></PackageIconUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand All @@ -19,7 +19,7 @@
<PackageReference Include="Intent.Modules.Metadata.RDBMS" Version="3.6.1" />
<PackageReference Include="Intent.Modules.Modelers.Domain" Version="3.9.0" />
<PackageReference Include="Intent.Modules.Modelers.Domain.Repositories" Version="3.5.0" />
<PackageReference Include="Intent.Modules.Modelers.Domain.StoredProcedures" Version="1.0.0" />
<PackageReference Include="Intent.Modules.Modelers.Domain.StoredProcedures" Version="1.1.1-pre.0" />
<PackageReference Include="Intent.Packager" Version="3.4.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public CustomRepositoryTemplate(IOutputTarget outputTarget, RepositoryModel mode
}
}, 1000);

var storedProcedures = Model.GetStoredProcedureModels();
var storedProcedures = Model.GetGeneralizedStoredProcedures();
if (!storedProcedures.Any())
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public CustomRepositoryInterfaceTemplate(IOutputTarget outputTarget, RepositoryM
RepositoryOperationHelper.ApplyMethods(this, @interface, model);
});

var storedProcedures = Model.GetStoredProcedureModels();
var storedProcedures = Model.GetGeneralizedStoredProcedures();
if (!storedProcedures.Any())
{
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System.Collections.Generic;
using Intent.EntityFrameworkCore.Repositories.Api;
using Intent.Metadata.Models;
using Intent.Modelers.Domain.Api;
using Intent.Modelers.Domain.Repositories.Api;
using Intent.Modules.Common;
using Intent.Modules.EntityFrameworkCore.Repositories.Api;
using Intent.Modules.Modelers.Domain.StoredProcedures.Api;

namespace Intent.Modules.EntityFrameworkCore.Repositories.Templates;

internal static class RepositoryModelExtensions
{
public static IReadOnlyCollection<GeneralizedStoredProcedure> GetGeneralizedStoredProcedures(this RepositoryModel repositoryModel)
{
var results = new List<GeneralizedStoredProcedure>();

foreach (var childElement in repositoryModel.InternalElement.ChildElements)
{
var operationModel = childElement.AsOperationModel();
if (operationModel != null && operationModel.TryGetStoredProcedure(out var storedProcedure))
{
results.Add(new GeneralizedStoredProcedure(operationModel, storedProcedure));
}

if (childElement.IsStoredProcedureModel())
{
results.Add(new GeneralizedStoredProcedure(childElement.AsStoredProcedureModel()));
}
}

return results;
}
}

internal class GeneralizedStoredProcedure : IElementWrapper, IHasTypeReference, IMetadataModel
{
public GeneralizedStoredProcedure(OperationModel model, StoredProcedureStereotype storedProcedureStereotype)
{
Name = storedProcedureStereotype.GetName();
Model = model;
InternalElement = model.InternalElement;

foreach (var parameterModel in model.Parameters)
{
var parameter = new Parameter
{
Model = parameterModel,
InternalElement = parameterModel.InternalElement
};

if (parameterModel.TryGetStoredProcedureParameter(out var storedProcedureParameter))
{
parameter.StoredProcedureDetails = new ParameterStoredProcedureDetails
{
Name = storedProcedureParameter.GetName(),
Direction = storedProcedureParameter.GetDirection(),
Size = storedProcedureParameter.GetSize(),
Precision = storedProcedureParameter.GetPrecision(),
Scale = storedProcedureParameter.GetScale(),
SqlStringType = storedProcedureParameter.GetSqlStringType()
};
}

Parameters.Add(parameter);
}
}

public GeneralizedStoredProcedure(StoredProcedureModel model)
{
var storedProcedure = model.GetStoredProcedureSettings();

Name = storedProcedure.NameInSchema();
Model = model;
InternalElement = model.InternalElement;

foreach (var parameterModel in model.Parameters)
{
var storedProcedureParameter = parameterModel.GetStoredProcedureParameterSettings();

Parameters.Add(new Parameter
{
Model = parameterModel,
InternalElement = parameterModel.InternalElement,
StoredProcedureDetails = new ParameterStoredProcedureDetails
{
Name = parameterModel.Name,
Direction = !storedProcedureParameter.IsOutputParameter()
? StoredProcedureParameterDirection.In
: StoredProcedureParameterDirection.Out,
Size = storedProcedureParameter.Size(),
Precision = storedProcedureParameter.Precision(),
Scale = storedProcedureParameter.Scale(),
SqlStringType = storedProcedureParameter.SQLStringType().Value
}
});
}
}

/// <summary>
/// The name in the schema.
/// </summary>
public string Name { get; set; }

public List<Parameter> Parameters { get; set; } = new();
public IMetadataModel Model { get; set; }
public IElement InternalElement { get; }
public ITypeReference TypeReference => InternalElement.TypeReference;
public string Id => InternalElement.Id;
}

internal class Parameter : IElementWrapper, IHasTypeReference, IMetadataModel
{
public Parameter() { }

public IMetadataModel Model { get; set; }
public IElement InternalElement { get; set; }
public ITypeReference TypeReference => InternalElement.TypeReference;
public string Id => InternalElement.Id;
public ParameterStoredProcedureDetails StoredProcedureDetails { get; set; }
}

internal class ParameterStoredProcedureDetails
{
/// <summary>
/// The name in the schema.
/// </summary>
public string Name { get; set; }
public StoredProcedureParameterDirection Direction { get; set; }
public int? Size { get; set; }
public int? Precision { get; set; }
public int? Scale { get; set; }
public string SqlStringType { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Intent.Modules.Common.CSharp.Templates;
using Intent.Modules.Common.Templates;
using Intent.Modules.Constants;
using Intent.Modules.EntityFrameworkCore.Repositories.Api;

namespace Intent.Modules.EntityFrameworkCore.Repositories.Templates;

Expand All @@ -14,9 +15,14 @@ public static class RepositoryOperationHelper
public static void ApplyMethods(ICSharpFileBuilderTemplate template, CSharpClass @class, RepositoryModel repositoryModel)
{
template.AddDomainTypeSources();

foreach (var operationModel in repositoryModel.Operations)
{
if (operationModel.TryGetStoredProcedure(out _))
{
continue;
}

var isAsync = operationModel.Name.EndsWith("Async") || operationModel.HasStereotype("Asynchronous");
@class.AddMethod(GetReturnType(template, operationModel.ReturnType), operationModel.Name, method =>
{
Expand Down Expand Up @@ -48,6 +54,11 @@ public static void ApplyMethods(ICSharpFileBuilderTemplate template, CSharpInter

foreach (var operationModel in repositoryModel.Operations)
{
if (operationModel.TryGetStoredProcedure(out _))
{
continue;
}

var isAsync = operationModel.Name.EndsWith("Async") || operationModel.HasStereotype("Asynchronous");
@interface.AddMethod(GetReturnType(template, operationModel.ReturnType), operationModel.Name, method =>
{
Expand Down
Loading

0 comments on commit 44c7309

Please sign in to comment.