72 lines
2.8 KiB
C#
72 lines
2.8 KiB
C#
using Microsoft.Data.SqlClient;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using ZB.MOM.WW.OtOpcUa.Configuration;
|
|
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
|
|
using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Admin.Services;
|
|
|
|
/// <summary>
|
|
/// Owns the draft → diff → publish workflow (decision #89). Publish + rollback call into the
|
|
/// stored procedures; diff queries <c>sp_ComputeGenerationDiff</c>.
|
|
/// </summary>
|
|
public sealed class GenerationService(OtOpcUaConfigDbContext db)
|
|
{
|
|
public async Task<ConfigGeneration> CreateDraftAsync(string clusterId, string createdBy, CancellationToken ct)
|
|
{
|
|
var gen = new ConfigGeneration
|
|
{
|
|
ClusterId = clusterId,
|
|
Status = GenerationStatus.Draft,
|
|
CreatedBy = createdBy,
|
|
CreatedAt = DateTime.UtcNow,
|
|
};
|
|
db.ConfigGenerations.Add(gen);
|
|
await db.SaveChangesAsync(ct);
|
|
return gen;
|
|
}
|
|
|
|
public Task<List<ConfigGeneration>> ListRecentAsync(string clusterId, int limit, CancellationToken ct) =>
|
|
db.ConfigGenerations.AsNoTracking()
|
|
.Where(g => g.ClusterId == clusterId)
|
|
.OrderByDescending(g => g.GenerationId)
|
|
.Take(limit)
|
|
.ToListAsync(ct);
|
|
|
|
public async Task PublishAsync(string clusterId, long draftGenerationId, string? notes, CancellationToken ct)
|
|
{
|
|
await db.Database.ExecuteSqlRawAsync(
|
|
"EXEC dbo.sp_PublishGeneration @ClusterId = {0}, @DraftGenerationId = {1}, @Notes = {2}",
|
|
[clusterId, draftGenerationId, (object?)notes ?? DBNull.Value],
|
|
ct);
|
|
}
|
|
|
|
public async Task RollbackAsync(string clusterId, long targetGenerationId, string? notes, CancellationToken ct)
|
|
{
|
|
await db.Database.ExecuteSqlRawAsync(
|
|
"EXEC dbo.sp_RollbackToGeneration @ClusterId = {0}, @TargetGenerationId = {1}, @Notes = {2}",
|
|
[clusterId, targetGenerationId, (object?)notes ?? DBNull.Value],
|
|
ct);
|
|
}
|
|
|
|
public async Task<List<DiffRow>> ComputeDiffAsync(long from, long to, CancellationToken ct)
|
|
{
|
|
var results = new List<DiffRow>();
|
|
await using var conn = (SqlConnection)db.Database.GetDbConnection();
|
|
if (conn.State != System.Data.ConnectionState.Open) await conn.OpenAsync(ct);
|
|
|
|
await using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "EXEC dbo.sp_ComputeGenerationDiff @FromGenerationId = @f, @ToGenerationId = @t";
|
|
cmd.Parameters.AddWithValue("@f", from);
|
|
cmd.Parameters.AddWithValue("@t", to);
|
|
|
|
await using var reader = await cmd.ExecuteReaderAsync(ct);
|
|
while (await reader.ReadAsync(ct))
|
|
results.Add(new DiffRow(reader.GetString(0), reader.GetString(1), reader.GetString(2)));
|
|
|
|
return results;
|
|
}
|
|
}
|
|
|
|
public sealed record DiffRow(string TableName, string LogicalId, string ChangeKind);
|