Share EF secret shadow property names

This commit is contained in:
Sipke Schoorstra 2026-06-01 21:45:53 +02:00
parent d3c80a8167
commit 7becbd3146
No known key found for this signature in database
GPG key ID: 5C10502B28A4268F
6 changed files with 28 additions and 22 deletions

View file

@ -1,4 +1,5 @@
using Elsa.Secrets.Models;
using Elsa.Secrets.Persistence.EFCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
@ -8,7 +9,7 @@ public class SecretsConfiguration : IEntityTypeConfiguration<Secret>
{
public void Configure(EntityTypeBuilder<Secret> builder)
{
builder.Property<string>("SerializedTags").HasColumnName("Tags").HasColumnType("NCLOB").IsRequired();
builder.Property<string>("SerializedVersions").HasColumnName("Versions").HasColumnType("NCLOB").IsRequired();
builder.Property<string>(SecretShadowPropertyNames.SerializedTags).HasColumnName("Tags").HasColumnType("NCLOB").IsRequired();
builder.Property<string>(SecretShadowPropertyNames.SerializedVersions).HasColumnName("Versions").HasColumnType("NCLOB").IsRequired();
}
}

View file

@ -1,4 +1,6 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using Elsa.Persistence.EFCore;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
@ -7,11 +9,11 @@ namespace Elsa.Secrets.Persistence.EFCore.Sqlite.Migrations.Secrets
/// <inheritdoc />
public partial class Initial : Migration
{
private readonly Elsa.Persistence.EFCore.IElsaDbContextSchema _schema;
private readonly IElsaDbContextSchema _schema;
public Initial(Elsa.Persistence.EFCore.IElsaDbContextSchema schema)
public Initial(IElsaDbContextSchema schema)
{
_schema = schema;
_schema = schema ?? throw new ArgumentNullException(nameof(schema));
}
/// <inheritdoc />

View file

@ -108,12 +108,12 @@ public class EFCoreSecretRepository(Store<SecretsElsaDbContext, Secret> store) :
private static Task<Secret?> FindByNameAsync(SecretsElsaDbContext dbContext, string name, CancellationToken cancellationToken)
{
var normalizedName = NormalizeName(name);
return dbContext.Secrets.FirstOrDefaultAsync(x => EF.Property<string>(x, SecretConfiguration.NormalizedNamePropertyName) == normalizedName, cancellationToken);
return dbContext.Secrets.FirstOrDefaultAsync(x => EF.Property<string>(x, SecretShadowPropertyNames.NormalizedName) == normalizedName, cancellationToken);
}
private static Task<bool> ExistsByNormalizedNameAsync(SecretsElsaDbContext dbContext, string normalizedName, CancellationToken cancellationToken)
{
return dbContext.Secrets.AnyAsync(x => EF.Property<string>(x, SecretConfiguration.NormalizedNamePropertyName) == normalizedName, cancellationToken);
return dbContext.Secrets.AnyAsync(x => EF.Property<string>(x, SecretShadowPropertyNames.NormalizedName) == normalizedName, cancellationToken);
}
private async Task SaveChangesAsync(SecretsElsaDbContext dbContext, string name, CancellationToken cancellationToken)
@ -155,7 +155,7 @@ public class EFCoreSecretRepository(Store<SecretsElsaDbContext, Secret> store) :
private static void SetNormalizedName(SecretsElsaDbContext dbContext, Secret secret)
{
dbContext.Entry(secret).Property(SecretConfiguration.NormalizedNamePropertyName).CurrentValue = NormalizeName(secret.Name);
dbContext.Entry(secret).Property(SecretShadowPropertyNames.NormalizedName).CurrentValue = NormalizeName(secret.Name);
}
private static string NormalizeName(string name) => name.Trim().ToLowerInvariant();

View file

@ -6,24 +6,22 @@ namespace Elsa.Secrets.Persistence.EFCore;
internal class SecretConfiguration : IEntityTypeConfiguration<Secret>
{
public const string NormalizedNamePropertyName = "NormalizedName";
public void Configure(EntityTypeBuilder<Secret> builder)
{
builder.HasKey(x => x.Id);
builder.Ignore(x => x.Tags);
builder.Ignore(x => x.Versions);
builder.Ignore(x => x.LatestActiveVersion);
builder.Property<string>(SecretSerialization.SerializedTagsPropertyName).HasColumnName("Tags").IsRequired();
builder.Property<string>(SecretSerialization.SerializedVersionsPropertyName).HasColumnName("Versions").IsRequired();
builder.Property<string>(SecretShadowPropertyNames.SerializedTags).HasColumnName("Tags").IsRequired();
builder.Property<string>(SecretShadowPropertyNames.SerializedVersions).HasColumnName("Versions").IsRequired();
builder.Property(x => x.Name).HasMaxLength(200).IsRequired();
builder.Property<string>(NormalizedNamePropertyName).HasMaxLength(200).IsRequired();
builder.Property<string>(SecretShadowPropertyNames.NormalizedName).HasMaxLength(200).IsRequired();
builder.Property(x => x.DisplayName).HasMaxLength(200).IsRequired();
builder.Property(x => x.TypeName).HasMaxLength(100).IsRequired();
builder.Property(x => x.StoreName).HasMaxLength(100).IsRequired();
builder.Property(x => x.Scope).HasMaxLength(200);
builder.Property(x => x.Status).HasConversion<string>().HasMaxLength(32).IsRequired();
builder.HasIndex(NormalizedNamePropertyName).HasDatabaseName($"IX_{nameof(Secret)}_{NormalizedNamePropertyName}").IsUnique();
builder.HasIndex(SecretShadowPropertyNames.NormalizedName).HasDatabaseName($"IX_{nameof(Secret)}_{SecretShadowPropertyNames.NormalizedName}").IsUnique();
builder.HasIndex(x => x.TypeName).HasDatabaseName($"IX_{nameof(Secret)}_{nameof(Secret.TypeName)}");
builder.HasIndex(x => x.StoreName).HasDatabaseName($"IX_{nameof(Secret)}_{nameof(Secret.StoreName)}");
builder.HasIndex(x => x.Scope).HasDatabaseName($"IX_{nameof(Secret)}_{nameof(Secret.Scope)}");

View file

@ -7,9 +7,6 @@ namespace Elsa.Secrets.Persistence.EFCore;
internal static class SecretSerialization
{
public const string SerializedTagsPropertyName = "SerializedTags";
public const string SerializedVersionsPropertyName = "SerializedVersions";
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
{
Converters = { new JsonStringEnumConverter() }
@ -17,8 +14,8 @@ internal static class SecretSerialization
public static void StoreSerializedProperties(DbContext dbContext, Secret secret)
{
dbContext.Entry(secret).Property(SerializedTagsPropertyName).CurrentValue = JsonSerializer.Serialize(secret.Tags.Order(StringComparer.OrdinalIgnoreCase), JsonOptions);
dbContext.Entry(secret).Property(SerializedVersionsPropertyName).CurrentValue = JsonSerializer.Serialize(secret.Versions, JsonOptions);
dbContext.Entry(secret).Property(SecretShadowPropertyNames.SerializedTags).CurrentValue = JsonSerializer.Serialize(secret.Tags.Order(StringComparer.OrdinalIgnoreCase), JsonOptions);
dbContext.Entry(secret).Property(SecretShadowPropertyNames.SerializedVersions).CurrentValue = JsonSerializer.Serialize(secret.Versions, JsonOptions);
}
public static void LoadSerializedProperties(DbContext dbContext, Secret? secret)
@ -26,8 +23,8 @@ internal static class SecretSerialization
if (secret == null)
return;
var tagsJson = dbContext.Entry(secret).Property<string>(SerializedTagsPropertyName).CurrentValue;
var versionsJson = dbContext.Entry(secret).Property<string>(SerializedVersionsPropertyName).CurrentValue;
var tagsJson = dbContext.Entry(secret).Property<string>(SecretShadowPropertyNames.SerializedTags).CurrentValue;
var versionsJson = dbContext.Entry(secret).Property<string>(SecretShadowPropertyNames.SerializedVersions).CurrentValue;
var tags = Deserialize(tagsJson, static () => new List<string>());
var versions = Deserialize(versionsJson, static () => new List<SecretVersion>());
secret.Tags = tags.ToHashSet(StringComparer.OrdinalIgnoreCase);

View file

@ -0,0 +1,8 @@
namespace Elsa.Secrets.Persistence.EFCore;
public static class SecretShadowPropertyNames
{
public const string NormalizedName = "NormalizedName";
public const string SerializedTags = "SerializedTags";
public const string SerializedVersions = "SerializedVersions";
}