Skip to content

Commit

Permalink
More triggers to Core
Browse files Browse the repository at this point in the history
Fixes #28673
  • Loading branch information
AndriySvyryd committed Aug 13, 2022
1 parent 2dcd881 commit cf00f88
Show file tree
Hide file tree
Showing 71 changed files with 1,499 additions and 1,768 deletions.
6 changes: 3 additions & 3 deletions src/EFCore.Design/Extensions/ScaffoldingModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,14 @@ public static IEnumerable<AttributeCodeFragment> GetDataAnnotations(this ISkipNa
toTableNestedCalls.Add(new MethodCallCodeFragment(nameof(TableBuilder.HasComment), comment));
}

if (entityType.GetTriggers().Any())
if (entityType.GetDeclaredTriggers().Any())
{
toTableHandledByConventions = false;
toTableHandledByDataAnnotations = false;

foreach (var trigger in entityType.GetTriggers())
foreach (var trigger in entityType.GetDeclaredTriggers())
{
toTableNestedCalls.Add(new MethodCallCodeFragment(nameof(TableBuilder.HasTrigger), trigger.Name));
toTableNestedCalls.Add(new MethodCallCodeFragment(nameof(TableBuilder.HasTrigger), trigger.ModelName));
}
}

Expand Down
50 changes: 29 additions & 21 deletions src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Text;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace Microsoft.EntityFrameworkCore.Migrations.Design;
Expand Down Expand Up @@ -847,28 +849,28 @@ private void GenerateTableMapping(
annotations.TryGetAndRemove(RelationalAnnotationNames.TableName, out IAnnotation tableNameAnnotation);
var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
var tableName = (string?)tableNameAnnotation?.Value ?? table?.Name;
var explicitName = tableNameAnnotation != null
|| entityType.BaseType == null
var explicitName = tableNameAnnotation != null
|| entityType.BaseType == null
|| entityType.BaseType.GetTableName() != tableName;

annotations.TryGetAndRemove(RelationalAnnotationNames.Schema, out IAnnotation schemaAnnotation);
var schema = (string?)schemaAnnotation?.Value ?? table?.Schema;

annotations.TryGetAndRemove(RelationalAnnotationNames.IsTableExcludedFromMigrations, out IAnnotation isExcludedAnnotation);
var isExcludedFromMigrations = (isExcludedAnnotation?.Value as bool?) == true;

annotations.TryGetAndRemove(RelationalAnnotationNames.Comment, out IAnnotation commentAnnotation);
var comment = (string?)commentAnnotation?.Value;
var hasTriggers = entityType.GetTriggers().Any(t => t.TableName == tableName! && t.TableSchema == schema);

var hasTriggers = entityType.GetDeclaredTriggers().Any(t => t.GetTableName() == tableName! && t.GetTableSchema() == schema);
var hasOverrides = table != null
&& entityType.GetProperties().Select(p => p.FindOverrides(table.Value)).Any(o => o != null);
var requiresTableBuilder = isExcludedFromMigrations
|| comment != null
|| hasTriggers
|| hasOverrides
|| entityType.GetCheckConstraints().Any();

if (!explicitName
&& !requiresTableBuilder)
{
Expand All @@ -879,7 +881,7 @@ private void GenerateTableMapping(
.AppendLine()
.Append(entityTypeBuilderName)
.Append(".ToTable(");

if (explicitName)
{
if (tableName == null
Expand Down Expand Up @@ -932,7 +934,7 @@ private void GenerateTableMapping(
.AppendLine()
.AppendLine("t.ExcludeFromMigrations();");
}

if (comment != null)
{
stringBuilder
Expand Down Expand Up @@ -1106,6 +1108,7 @@ protected virtual void GenerateEntityTypeMappingFragmentAnnotations(
var annotations = Dependencies.AnnotationCodeGenerator
.FilterIgnoredAnnotations(fragment.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

if (annotations.Count > 0)
{
GenerateAnnotations(tableBuilderName, fragment, stringBuilder, annotations, inChainedCall: false);
Expand Down Expand Up @@ -1169,6 +1172,7 @@ protected virtual void GenerateCheckConstraintAnnotations(
var annotations = Dependencies.AnnotationCodeGenerator
.FilterIgnoredAnnotations(checkConstraint.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

using (stringBuilder.Indent())
{
if (hasNonDefaultName)
Expand Down Expand Up @@ -1207,9 +1211,9 @@ protected virtual void GenerateTriggers(
string? schema,
IndentedStringBuilder stringBuilder)
{
foreach (var trigger in entityType.GetTriggers())
foreach (var trigger in entityType.GetDeclaredTriggers())
{
if (trigger.TableName != table || trigger.TableSchema != schema)
if (trigger.GetTableName() != table || trigger.GetTableSchema() != schema)
{
continue;
}
Expand Down Expand Up @@ -1237,15 +1241,6 @@ protected virtual void GenerateTrigger(
// Note that GenerateAnnotations below does the corresponding decrement
stringBuilder.IncrementIndent();

if (trigger.Name != trigger.GetDefaultName()!)
{
stringBuilder
.AppendLine()
.Append(".HasName(")
.Append(Code.Literal(trigger.Name))
.Append(")");
}

GenerateTriggerAnnotations(triggerBuilderName, trigger, stringBuilder);
}

Expand All @@ -1264,6 +1259,18 @@ protected virtual void GenerateTriggerAnnotations(
.FilterIgnoredAnnotations(trigger.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

if (annotations.TryGetAndRemove(RelationalAnnotationNames.Name, out IAnnotation nameAnnotation))
{
stringBuilder
.AppendLine()
.Append(".HasName(")
.Append(Code.Literal((string?)nameAnnotation.Value))
.Append(")");
}

annotations.Remove(RelationalAnnotationNames.TableName);
annotations.Remove(RelationalAnnotationNames.Schema);

GenerateAnnotations(triggerBuilderName, trigger, stringBuilder, annotations, inChainedCall: true);
}

Expand Down Expand Up @@ -1337,6 +1344,7 @@ protected virtual void GeneratePropertyOverridesAnnotations(
var annotations = Dependencies.AnnotationCodeGenerator
.FilterIgnoredAnnotations(overrides.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

GenerateAnnotations(propertyBuilderName, overrides, stringBuilder, annotations, inChainedCall: true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,11 @@ private void CreateEntityType(
Create(index, propertyVariables, parameters, nullable);
}

foreach (var trigger in entityType.GetDeclaredTriggers())
{
Create(trigger, parameters);
}

mainBuilder
.Append("return ")
.Append(entityTypeVariable)
Expand Down Expand Up @@ -1322,6 +1327,26 @@ private void CreateSkipNavigation(
.AppendLine("}");
}

private void Create(ITrigger trigger, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var triggerVariable = _code.Identifier(trigger.ModelName, parameters.ScopeVariables, capitalize: false);

var mainBuilder = parameters.MainBuilder;
mainBuilder
.Append("var ").Append(triggerVariable).Append(" = ").Append(parameters.TargetName).AppendLine(".AddTrigger(")
.IncrementIndent()
.Append(_code.Literal(trigger.ModelName))
.AppendLine(");")
.DecrementIndent();

CreateAnnotations(
trigger,
_annotationCodeGenerator.Generate,
parameters with { TargetName = triggerVariable });

mainBuilder.AppendLine();
}

private void CreateAnnotations(
IEntityType entityType,
IndentedStringBuilder mainBuilder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,9 @@ protected virtual ModelBuilder VisitTables(ModelBuilder modelBuilder, ICollectio
VisitUniqueConstraints(builder, table.UniqueConstraints);
VisitIndexes(builder, table.Indexes);

if (table.FindAnnotation(RelationalAnnotationNames.Triggers) is { Value: HashSet<string> triggers })
foreach (var triggerName in table.Triggers)
{
foreach (var triggerName in triggers)
{
builder.ToTable(table.Name, table.Schema, tb => tb.HasTrigger(triggerName));
}

table.RemoveAnnotation(RelationalAnnotationNames.Triggers);
builder.ToTable(table.Name, table.Schema, tb => tb.HasTrigger(triggerName));
}

builder.Metadata.AddAnnotations(table.GetAnnotations());
Expand Down
39 changes: 38 additions & 1 deletion src/EFCore.Relational/Design/AnnotationCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public class AnnotationCodeGenerator : IAnnotationCodeGenerator
private static readonly ISet<string> IgnoredRelationalAnnotations = new HashSet<string>
{
RelationalAnnotationNames.CheckConstraints,
RelationalAnnotationNames.Triggers,
RelationalAnnotationNames.Sequences,
RelationalAnnotationNames.DbFunctions,
RelationalAnnotationNames.DeleteStoredProcedure,
Expand Down Expand Up @@ -123,6 +122,18 @@ public virtual void RemoveAnnotationsHandledByConventions(
IDictionary<string, IAnnotation> annotations)
=> RemoveConventionalAnnotationsHelper(foreignKey, annotations, IsHandledByConvention);

/// <inheritdoc />
public virtual void RemoveAnnotationsHandledByConventions(
INavigation navigation,
IDictionary<string, IAnnotation> annotations)
=> RemoveConventionalAnnotationsHelper(navigation, annotations, IsHandledByConvention);

/// <inheritdoc />
public virtual void RemoveAnnotationsHandledByConventions(
ISkipNavigation navigation,
IDictionary<string, IAnnotation> annotations)
=> RemoveConventionalAnnotationsHelper(navigation, annotations, IsHandledByConvention);

/// <inheritdoc />
public virtual void RemoveAnnotationsHandledByConventions(IIndex index, IDictionary<string, IAnnotation> annotations)
=> RemoveConventionalAnnotationsHelper(index, annotations, IsHandledByConvention);
Expand Down Expand Up @@ -543,6 +554,32 @@ protected virtual bool IsHandledByConvention(IProperty property, IAnnotation ann
protected virtual bool IsHandledByConvention(IForeignKey foreignKey, IAnnotation annotation)
=> false;

/// <summary>
/// Checks if the given <paramref name="annotation" /> is handled by convention when
/// applied to the given <paramref name="navigation" />.
/// </summary>
/// <remarks>
/// The default implementation always returns <see langword="false" />.
/// </remarks>
/// <param name="navigation">The <see cref="INavigation" />.</param>
/// <param name="annotation">The <see cref="IAnnotation" />.</param>
/// <returns><see langword="false" />.</returns>
protected virtual bool IsHandledByConvention(INavigation navigation, IAnnotation annotation)
=> false;

/// <summary>
/// Checks if the given <paramref name="annotation" /> is handled by convention when
/// applied to the given <paramref name="navigation" />.
/// </summary>
/// <remarks>
/// The default implementation always returns <see langword="false" />.
/// </remarks>
/// <param name="navigation">The <see cref="ISkipNavigation" />.</param>
/// <param name="annotation">The <see cref="IAnnotation" />.</param>
/// <returns><see langword="false" />.</returns>
protected virtual bool IsHandledByConvention(ISkipNavigation navigation, IAnnotation annotation)
=> false;

/// <summary>
/// Checks if the given <paramref name="annotation" /> is handled by convention when
/// applied to the given <paramref name="index" />.
Expand Down
24 changes: 22 additions & 2 deletions src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,26 @@ void RemoveAnnotationsHandledByConventions(IForeignKey foreignKey, IDictionary<s
{
}

/// <summary>
/// Removes annotation whose configuration is already applied by convention, and do not need to be
/// specified explicitly.
/// </summary>
/// <param name="navigation">The navigation to which the annotations are applied.</param>
/// <param name="annotations">The set of annotations from which to remove the conventional ones.</param>
void RemoveAnnotationsHandledByConventions(INavigation navigation, IDictionary<string, IAnnotation> annotations)
{
}

/// <summary>
/// Removes annotation whose configuration is already applied by convention, and do not need to be
/// specified explicitly.
/// </summary>
/// <param name="navigation">The navigation to which the annotations are applied.</param>
/// <param name="annotations">The set of annotations from which to remove the conventional ones.</param>
void RemoveAnnotationsHandledByConventions(ISkipNavigation navigation, IDictionary<string, IAnnotation> annotations)
{
}

/// <summary>
/// Removes annotation whose configuration is already applied by convention, and do not need to be
/// specified explicitly.
Expand Down Expand Up @@ -139,8 +159,8 @@ void RemoveAnnotationsHandledByConventions(ISequence sequence, IDictionary<strin
}

/// <summary>
/// For the given annotations which have corresponding fluent API calls, returns those fluent API calls
/// and removes the annotations.
/// Removes annotation whose configuration is already applied by convention, and do not need to be
/// specified explicitly.
/// </summary>
/// <param name="annotatable">The annotatable to which the annotations are applied.</param>
/// <param name="annotations">The set of annotations from which to generate fluent API calls.</param>
Expand Down
Loading

0 comments on commit cf00f88

Please sign in to comment.