Skip to content

Commit

Permalink
Adding support for add/drop views and functions, and sprocs
Browse files Browse the repository at this point in the history
  • Loading branch information
dgmjr committed Feb 23, 2024
1 parent 011e24d commit 176df01
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 34 deletions.
6 changes: 5 additions & 1 deletion src/Abstractions/ISoftDeletable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ namespace Dgmjr.EntityFrameworkCore.Abstractions;
public interface ISoftDeletable
{
DateTimeOffset? Deleted { get; set; }
bool IsDeleted { get; }
#if NET6_0_OR_GREATER
bool IsDeleted => Deleted is not null && Deleted.Value < DateTimeOffset.Now;
#else
bool IsDeleted { get; set; }
#endif
}
2 changes: 1 addition & 1 deletion src/Constants/Constants/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class Prefixes
/// <value>ufn_</value>
public const string ufn_ = nameof(ufn_);

/// <value>sp_</value>
/// <value>udp_</value>
public const string udp_ = nameof(udp_);

/// <value>sp_</value>
Expand Down
41 changes: 40 additions & 1 deletion src/Constants/DbTypesNamesAndSchemas/DbTypeNameEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public enum DbTypeNames
/// <summary>Database type of datetime.</summary>
[Display(Name = "datetime", Description = "Database type of datetime.", ShortName = "datetime")]
SqlDateTime,
/// <summary>Database type of datetime2.</summary>
[Display(Name = "datetime2", Description = "Database type of datetime2.", ShortName = "datetime")]
SqlDateTime2,

/// <summary>Database type of date.</summary>
[Display(Name = "date", Description = "Database type of date.", ShortName = "date")]
Expand Down Expand Up @@ -122,5 +125,41 @@ public enum DbTypeNames
Description = "Database type of uniqueidentifier.",
ShortName = "uniqueidentifier"
)]
UniqueIdentifier
UniqueIdentifier,

/// <summary>Database type of float.</summary>
[Display(
Name = "float",
Description = "Database type of float.",
ShortName = "float"
)]
Float,
/// <summary>Database type of GEOMETRY.</summary>
[Display(
Name = "GEOMETRY",
Description = "Database type of GEOMETRY.",
ShortName = "GEOMETRY"
)]
Geometry,
/// <summary>Database type of GEOGRAPHY.</summary>
[Display(
Name = "GEOGRAPHY",
Description = "Database type of GEOGRAPHY.",
ShortName = "GEOGRAPHY"
)]
Geography,
/// <summary>Database type of VARCHAR({0}).</summary>
[Display(
Name = "VARCHAR({0})",
Description = "Database type of VARCHAR({0}).",
ShortName = "VARCHAR({0})"
)]
VarCharX,
/// <summary>Database type of NVARCHAR({0}).</summary>
[Display(
Name = "NVARCHAR({0})",
Description = "Database type of NVARCHAR({0}).",
ShortName = "NVARCHAR({0})"
)]
NVarCharX,
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Description>Provides a set of constants and enums for EF Core</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dgmjr.Enumerations.CodeGenerator" IncludeAssets="Analyzers;Build;Runtime;Compile" ExcludeAssets="Native;BuildTransitive;BuildMultitargeting;ContentFiles" PrivateAssets="Analyzers" />
Expand All @@ -10,5 +11,6 @@
<PackageReference Include="Dgmjr.Enumerations.Abstractions" />
<PackageReference Include="Dgmjr.Abstractions" />
<PackageReference Include="Dgmjr.Primitives" />
<PackageReference Include="NetTopologySuite" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/Constants/DbTypesNamesAndSchemas/SchemasEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace Dgmjr.EntityFrameworkCore.Enums;

[GenerateEnumerationRecordStruct("DbSchemas", "Dgmjr.EntityFrameworkCore")]
public enum SchemasEnum
public enum Schemas
{
[Display(Name = "DBO Schema", ShortName = "dbo", Description = "The dbo schema")]
DboSchema,
Expand Down
78 changes: 74 additions & 4 deletions src/Migrations/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
using System.Domain;
using System.Net.Mail;
using System.Runtime.InteropServices.ComTypes;

using Dgmjr.EntityFrameworkCore.Constants;

using Byte = Dgmjr.EntityFrameworkCore.DbTypeNames.Byte;

namespace Dgmjr.EntityFrameworkCore.Migrations;

public static class Constants
{
public const string CreateOrAlterFunctionPattern =
"CREATE OR ALTER FUNCTION {0}.{1}({2}) RETURNS BIT AS BEGIN {3} END";
public const string CreateOrAlterFunctionPattern = """
CREATE OR ALTER FUNCTION {0}.{1}({2})
RETURNS {3}
AS
BEGIN
{4}
END
""";
public const string CreateOrAlterViewPattern = """
CREATE OR ALTER VIEW {0}.{1}
AS
{2}
""";
public const string CreateOrAlterProcedurePattern = """
CREATE OR ALTER PROCEDURE {0}.{1} {2}
AS
BEGIN
{3}
END
""";

public const string Function = "FUNCTION";
public const string Procedure = "PROCEDURE";
public const string View = "VIEW";

public const string DropFunctionIfExistsPattern = "DROP FUNCTION IF EXISTS {0}.{1}";
public const string DropProcedureIfExistsPattern = "DROP PROCEDURE IF EXISTS {0}.{1}";
public const string DropViewIfExistsPattern = "DROP VIEW IF EXISTS {0}.{1}";
public const string DropSomethingIfExistsPattern = "DROP {0} IF EXISTS {1}.{2}";

public static readonly IReadOnlyDictionary<Type, string> ClrTypeToSqlTypeMap = new Dictionary<
Type,
Expand All @@ -15,7 +48,44 @@ public static class Constants
{ typeof(string), NVarCharMax.ShortName },
{ typeof(int), Int.ShortName },
{ typeof(long), BigInt.ShortName },
{ typeof(datetime), SqlDateTime.ShortName },
{ typeof(DateTimeOffset), SqlDateTimeOffset.ShortName }
{ typeof(DateTimeOffset), SqlDateTimeOffset.ShortName },
{ typeof(guid), UniqueIdentifier.ShortName },
{ typeof(bool), Bit.ShortName },
{ typeof(decimal), Float.ShortName },
{ typeof(double), Float.ShortName },
{ typeof(float), Float.ShortName },
{ typeof(byte), Byte.ShortName },
{ typeof(short), TinyInt.ShortName },
{ typeof(byte[]), VarBinaryMax.ShortName },
{ typeof(DateTime), Date.ShortName },
{ typeof(DateTime?), Date.ShortName },
{ typeof(DateTimeOffset?), SqlDateTime2.ShortName },
{ typeof(TimeSpan), Time.ShortName },
{ typeof(TimeSpan?), Time.ShortName },
{ typeof(decimal?), Float.ShortName },
{ typeof(double?), Float.ShortName },
{ typeof(float?), Float.ShortName },
{ typeof(byte?), Byte.ShortName },
{ typeof(short?), TinyInt.ShortName },
{ typeof(int?), Int.ShortName },
{ typeof(long?), BigInt.ShortName },
{ typeof(bool?), Bit.ShortName },
{ typeof(NetTopologySuite.Geometries.Point), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.LineString), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.Polygon), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.MultiPoint), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.MultiLineString), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.MultiPolygon), Geography.ShortName },
{ typeof(NetTopologySuite.Geometries.GeometryCollection), Geography.ShortName },
{ typeof(Slug), Format(CharX.DisplayName, 6) },
{ typeof(Uri), NVarCharMax.DisplayName },
{ typeof(uri), NVarCharMax.DisplayName },
{ typeof(urn), NVarCharMax.DisplayName },
{ typeof(url), NVarCharMax.DisplayName },
{ typeof(xri), NVarCharMax.DisplayName },
{ typeof(EmailAddress), Format(NVarCharX.DisplayName, UriMaxLengthConstant.UriMaxLength) },
{ typeof(PhoneNumber), Format(VarCharX.DisplayName, 24) },
{ typeof(EmailAddress?), Format(NVarCharX.DisplayName, UriMaxLengthConstant.UriMaxLength) },
{ typeof(PhoneNumber?), Format(VarCharX.DisplayName, 24) },
};
}
15 changes: 9 additions & 6 deletions src/Migrations/CreateFunctionOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,34 @@ namespace Dgmjr.EntityFrameworkCore.Migrations;

using Microsoft.EntityFrameworkCore.Migrations.Operations;

public class CreateFunctionOperation(string schema, string name, string arguments, string body)
public class CreateFunctionOperation(string schema, string name, SqlArgument[] arguments, string returnType, string body)
: SqlOperation
{
public string Schema { get; set; } = schema;
public string Name { get; set; } = name;
public string Arguments { get; set; } = arguments;
public SqlArgument[] Arguments { get; set; } = arguments;
public string Body { get; set; } = body;
public string ReturnType { get; set; } = returnType;

public override string Sql =>
Format(CreateOrAlterFunctionPattern, Schema, Name, Arguments, Body);
Format(CreateOrAlterFunctionPattern, Schema, Name, Arguments.Join(", "), ReturnType, Body);

public CreateFunctionOperation(
MethodInfo mi,
string body,
string schema = DboSchema.ShortName,
string? name = default,
string? arguments = default
SqlArgument[]? arguments = default
)
: this(
schema,
name ?? mi.Name,
arguments
?? mi.GetParameters()
.Select(p => $"@{p.Name} {ClrTypeToSqlTypeMap[p.ParameterType]}")
.Join(", "),
// .Select(p => $"@{p.Name} {ClrTypeToSqlTypeMap[p.ParameterType]}").ToArray(),
.Select(arg => (SqlArgument)arg)
.ToArray(),
ClrTypeToSqlTypeMap[mi.ReturnType],
body
) { }
}
32 changes: 32 additions & 0 deletions src/Migrations/CreateProcedureOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Dgmjr.EntityFrameworkCore.Migrations;

using Microsoft.EntityFrameworkCore.Migrations.Operations;

public class CreateProcedureOperation(string schema, string name, SqlArgument[] arguments, string body)
: SqlOperation
{
public string Schema { get; set; } = schema;
public string Name { get; set; } = name;
public SqlArgument[] Arguments { get; set; } = arguments;
public string Body { get; set; } = body;

public override string Sql =>
Format(CreateOrAlterProcedurePattern, Schema, Name, Arguments.Join(", "), Body);

public CreateProcedureOperation(
MethodInfo mi,
string body,
string schema = DboSchema.ShortName,
string? name = default,
SqlArgument[]? arguments = default
)
: this(
schema,
name ?? mi.Name,
arguments
?? mi.GetParameters()
.Select(arg => (SqlArgument)arg)
.ToArray(),
body
) { }
}
17 changes: 8 additions & 9 deletions src/Migrations/CreateViewOperation.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// namespace Dgmjr.EntityFrameworkCore.Migrations;
namespace Dgmjr.EntityFrameworkCore.Migrations;

// public class CreateViewOperation(string schema, string name, params Column[] columns) : SqlOperation
// {
// public string Schema { get; set; } = schema;
// public string Name { get; set; } = name;
// public Column[] Columns { get; set; } = columns;
// public Expression
// }
public class CreateViewOperation(string schema, string name, string selectStatement) : SqlOperation
{
public string Schema { get; set; } = schema;
public string Name { get; set; } = name;
public string SelectStatement { get; set; } = selectStatement;

// public record struct Column(string DataType, string SourceTable, string ColumnName);
public override string Sql => Format(CreateOrAlterViewPattern, Schema, Name, SelectStatement);
}
18 changes: 17 additions & 1 deletion src/Migrations/CustomSqlMigrationsGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ICommandBatchPreparer commandBatchPreparer

protected override void Generate(
MigrationOperation operation,
IModel model,
IModel? model,
MigrationCommandListBuilder builder
)
{
Expand All @@ -41,6 +41,22 @@ MigrationCommandListBuilder builder
{
builder.Append(dfo.Sql).Append(SqlHelper.StatementTerminator).EndCommand();
}
else if (operation is DropViewOperation dvo)
{
builder.Append(dvo.Sql).Append(SqlHelper.StatementTerminator).EndCommand();
}
else if (operation is CreateViewOperation cvo)
{
builder.Append(cvo.Sql).Append(SqlHelper.StatementTerminator).EndCommand();
}
else if (operation is DropOperation dropop)
{
builder.Append(dropop.Sql).Append(SqlHelper.StatementTerminator).EndCommand();
}
else if (operation is CreateProcedureOperation cpop)
{
builder.Append(cpop.Sql).Append(SqlHelper.StatementTerminator).EndCommand();
}
else
{
base.Generate(operation, model, builder);
Expand Down
7 changes: 5 additions & 2 deletions src/Migrations/Dgmjr.EntityFrameworkCore.Migrations.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
<Description>Entity Framework Core Migrations</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Usings" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
<PackageReference Include="Dgmjr.EntityFrameworkCore.Constants.All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
<ProjectReference Include="../Constants/DbTypesNamesAndSchemas/Dgmjr.EntityFrameworkCore.Constants.DbTypesNamesAndSchemas.csproj" />
<ProjectReference Include="../Models/Dgmjr.EntityFrameworkCore.Models.csproj" />
<SourceGeneratorPackageReference Include="Dgmjr.RegexDtoGenerator" />
<UsingsPackageReference Include="Microsoft.EntityFrameworkCore.Usings" />
</ItemGroup>
<ItemGroup>
<Using Include="Dgmjr.EntityFrameworkCore.Migrations.Constants" Static="true" />
Expand Down
7 changes: 1 addition & 6 deletions src/Migrations/DropFunctionOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ namespace Dgmjr.EntityFrameworkCore.Migrations;

using Microsoft.EntityFrameworkCore.Migrations.Operations;

public class DropFunctionOperation(string schema, string name) : SqlOperation
public class DropFunctionOperation(string schema, string name) : DropOperation(Function, schema, name)
{
public string Schema { get; set; } = schema;
public string Name { get; set; } = name;
public override bool IsDestructiveChange => true;

public override string Sql => Format(DropFunctionIfExistsPattern, Schema, Name);
}
11 changes: 11 additions & 0 deletions src/Migrations/DropOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Dgmjr.EntityFrameworkCore.Migrations;

public class DropOperation(string thingKind, string schema, string name) : SqlOperation
{
public string ThingKind { get; set; } = thingKind;
public string Schema { get; set; } = schema;
public string Name { get; set; } = name;
public override bool IsDestructiveChange => true;

public override string Sql => Format(DropSomethingIfExistsPattern, ThingKind, Schema, Name);
}
8 changes: 8 additions & 0 deletions src/Migrations/DropProcedureOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Dgmjr.EntityFrameworkCore.Migrations;

using Microsoft.EntityFrameworkCore.Migrations.Operations;

public class DropProcedureOperation(string schema, string name) : DropOperation(Procedure, schema, name)
{

}
7 changes: 7 additions & 0 deletions src/Migrations/DropViewOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Dgmjr.EntityFrameworkCore.Migrations;

using Microsoft.EntityFrameworkCore.Migrations.Operations;

public class DropViewOperation(string schema, string name) : DropOperation(View, schema, name)
{
}
Loading

0 comments on commit 176df01

Please sign in to comment.