diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Interfaces/Repositories/ITemplateEngineRepository.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Interfaces/Repositories/ITemplateEngineRepository.cs
index d565617b..b666318f 100644
--- a/src/ZB.MOM.WW.ScadaBridge.Commons/Interfaces/Repositories/ITemplateEngineRepository.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Interfaces/Repositories/ITemplateEngineRepository.cs
@@ -96,6 +96,18 @@ public interface ITemplateEngineRepository
/// Cancellation token.
Task DeleteTemplateAlarmAsync(int id, CancellationToken cancellationToken = default);
+ // TemplateNativeAlarmSource
+ /// Retrieves a template native alarm source by ID.
+ Task GetTemplateNativeAlarmSourceByIdAsync(int id, CancellationToken cancellationToken = default);
+ /// Retrieves native alarm sources for a template.
+ Task> GetNativeAlarmSourcesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
+ /// Adds a new template native alarm source.
+ Task AddTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default);
+ /// Updates an existing template native alarm source.
+ Task UpdateTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default);
+ /// Deletes a template native alarm source by ID.
+ Task DeleteTemplateNativeAlarmSourceAsync(int id, CancellationToken cancellationToken = default);
+
// TemplateScript
/// Retrieves a template script by ID.
/// The script ID.
@@ -214,6 +226,18 @@ public interface ITemplateEngineRepository
/// Cancellation token.
Task DeleteInstanceAlarmOverrideAsync(int id, CancellationToken cancellationToken = default);
+ // InstanceNativeAlarmSourceOverride
+ /// Retrieves native alarm source overrides for an instance.
+ Task> GetNativeAlarmSourceOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
+ /// Retrieves a single native alarm source override by instance + source canonical name.
+ Task GetNativeAlarmSourceOverrideAsync(int instanceId, string sourceCanonicalName, CancellationToken cancellationToken = default);
+ /// Adds a new instance native alarm source override.
+ Task AddInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default);
+ /// Updates an existing instance native alarm source override.
+ Task UpdateInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default);
+ /// Deletes an instance native alarm source override by ID.
+ Task DeleteInstanceNativeAlarmSourceOverrideAsync(int id, CancellationToken cancellationToken = default);
+
// InstanceConnectionBinding
/// Retrieves connection bindings for an instance.
/// The instance ID.
diff --git a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
index f79cfd81..ac5e8647 100644
--- a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
@@ -29,6 +29,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(t => t.Alarms)
.Include(t => t.Scripts)
.Include(t => t.Compositions)
+ .Include(t => t.NativeAlarmSources)
.AsSplitQuery()
.FirstOrDefaultAsync(t => t.Id == id, cancellationToken);
}
@@ -59,6 +60,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(t => t.Alarms)
.Include(t => t.Scripts)
.Include(t => t.Compositions)
+ .Include(t => t.NativeAlarmSources)
.AsSplitQuery()
.ToListAsync(cancellationToken);
}
@@ -71,6 +73,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(t => t.Alarms)
.Include(t => t.Scripts)
.Include(t => t.Compositions)
+ .Include(t => t.NativeAlarmSources)
.AsSplitQuery()
.ToListAsync(cancellationToken);
}
@@ -188,6 +191,45 @@ public class TemplateEngineRepository : ITemplateEngineRepository
}
}
+ // TemplateNativeAlarmSource
+
+ ///
+ public async Task GetTemplateNativeAlarmSourceByIdAsync(int id, CancellationToken cancellationToken = default)
+ {
+ return await _context.TemplateNativeAlarmSources.FindAsync(new object[] { id }, cancellationToken);
+ }
+
+ ///
+ public async Task> GetNativeAlarmSourcesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default)
+ {
+ return await _context.TemplateNativeAlarmSources
+ .Where(s => s.TemplateId == templateId)
+ .ToListAsync(cancellationToken);
+ }
+
+ ///
+ public async Task AddTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default)
+ {
+ await _context.TemplateNativeAlarmSources.AddAsync(source, cancellationToken);
+ }
+
+ ///
+ public Task UpdateTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default)
+ {
+ _context.TemplateNativeAlarmSources.Update(source);
+ return Task.CompletedTask;
+ }
+
+ ///
+ public async Task DeleteTemplateNativeAlarmSourceAsync(int id, CancellationToken cancellationToken = default)
+ {
+ var source = await _context.TemplateNativeAlarmSources.FindAsync(new object[] { id }, cancellationToken);
+ if (source != null)
+ {
+ _context.TemplateNativeAlarmSources.Remove(source);
+ }
+ }
+
// TemplateScript
///
@@ -275,6 +317,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(i => i.AttributeOverrides)
.Include(i => i.AlarmOverrides)
.Include(i => i.ConnectionBindings)
+ .Include(i => i.NativeAlarmSourceOverrides)
.AsSplitQuery()
.FirstOrDefaultAsync(i => i.Id == id, cancellationToken);
}
@@ -286,6 +329,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(i => i.AttributeOverrides)
.Include(i => i.AlarmOverrides)
.Include(i => i.ConnectionBindings)
+ .Include(i => i.NativeAlarmSourceOverrides)
.AsSplitQuery()
.ToListAsync(cancellationToken);
}
@@ -306,6 +350,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(i => i.AttributeOverrides)
.Include(i => i.AlarmOverrides)
.Include(i => i.ConnectionBindings)
+ .Include(i => i.NativeAlarmSourceOverrides)
.AsSplitQuery()
.ToListAsync(cancellationToken);
}
@@ -317,6 +362,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
.Include(i => i.AttributeOverrides)
.Include(i => i.AlarmOverrides)
.Include(i => i.ConnectionBindings)
+ .Include(i => i.NativeAlarmSourceOverrides)
.AsSplitQuery()
.FirstOrDefaultAsync(i => i.UniqueName == uniqueName, cancellationToken);
}
@@ -419,6 +465,46 @@ public class TemplateEngineRepository : ITemplateEngineRepository
}
}
+ // InstanceNativeAlarmSourceOverride
+
+ ///
+ public async Task> GetNativeAlarmSourceOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default)
+ {
+ return await _context.InstanceNativeAlarmSourceOverrides
+ .Where(o => o.InstanceId == instanceId)
+ .ToListAsync(cancellationToken);
+ }
+
+ ///
+ public async Task GetNativeAlarmSourceOverrideAsync(int instanceId, string sourceCanonicalName, CancellationToken cancellationToken = default)
+ {
+ return await _context.InstanceNativeAlarmSourceOverrides
+ .FirstOrDefaultAsync(o => o.InstanceId == instanceId && o.SourceCanonicalName == sourceCanonicalName, cancellationToken);
+ }
+
+ ///
+ public async Task AddInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default)
+ {
+ await _context.InstanceNativeAlarmSourceOverrides.AddAsync(ovr, cancellationToken);
+ }
+
+ ///
+ public Task UpdateInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default)
+ {
+ _context.InstanceNativeAlarmSourceOverrides.Update(ovr);
+ return Task.CompletedTask;
+ }
+
+ ///
+ public async Task DeleteInstanceNativeAlarmSourceOverrideAsync(int id, CancellationToken cancellationToken = default)
+ {
+ var ovr = await _context.InstanceNativeAlarmSourceOverrides.FindAsync(new object[] { id }, cancellationToken);
+ if (ovr != null)
+ {
+ _context.InstanceNativeAlarmSourceOverrides.Remove(ovr);
+ }
+ }
+
// InstanceConnectionBinding
///
diff --git a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/TemplateEngineRepositoryTests.cs b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/TemplateEngineRepositoryTests.cs
index 7c8b634e..d5dc2112 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/TemplateEngineRepositoryTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/TemplateEngineRepositoryTests.cs
@@ -147,4 +147,32 @@ public class TemplateEngineRepositoryTests : IDisposable
Assert.NotNull(loaded);
Assert.Equal(baseTemplate.Id, loaded!.ParentTemplateId);
}
+
+ [Fact]
+ public async Task AddAndGetNativeAlarmSourcesByTemplateId_RoundTrips()
+ {
+ var t = new Template("T");
+ _context.Templates.Add(t);
+ await _context.SaveChangesAsync();
+
+ await _repository.AddTemplateNativeAlarmSourceAsync(
+ new TemplateNativeAlarmSource("S") { TemplateId = t.Id, ConnectionName = "C", SourceReference = "r" });
+ await _context.SaveChangesAsync();
+
+ var list = await _repository.GetNativeAlarmSourcesByTemplateIdAsync(t.Id);
+ Assert.Single(list);
+ Assert.Equal("S", list[0].Name);
+ }
+
+ [Fact]
+ public async Task GetTemplateWithChildren_IncludesNativeAlarmSources()
+ {
+ var t = new Template("T");
+ t.NativeAlarmSources.Add(new TemplateNativeAlarmSource("S") { ConnectionName = "C", SourceReference = "r" });
+ _context.Templates.Add(t);
+ await _context.SaveChangesAsync();
+
+ var loaded = await _repository.GetTemplateWithChildrenAsync(t.Id);
+ Assert.Single(loaded!.NativeAlarmSources);
+ }
}