Files
DP44/Common/DTS.Common.Import/Persist/SaveCustomChannels.cs
2026-04-17 14:55:32 -04:00

150 lines
8.3 KiB
C#

using DataPROWin7.DataModel;
using DTS.Common.Import.Enums;
using DTS.Common.ISO;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DTS.Common.Import.Persist
{
public class SaveCustomChannels : SaveVariantBase
{
public ISO13499FileDb IsoDb { get; set; }
public Dictionary<string, string> CustomChannelTextIdToOldChannelId { get; set; } = new Dictionary<string, string>();
public Dictionary<string, TestObjectChannel> CustomChannelOldChannelIdToChannel { get; set; } = new Dictionary<string, TestObjectChannel>();
public SaveCustomChannels(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
base(importObject, persistCalculator, importNotification, isCancelled)
{
}
public override void Save()
{
//there's a bit of a dance here
//when we commit embedded non iso groups for a non iso test setup for instance, the custom channels for that test setup are destroyed and
//recreated new, and as they were before they shall be again, but we'd like to link our level triggers we are importing that have the old ids
//to the new ids that will exist
//since we will go through all the custom channels in the code below, it's a good point to make a note of what once was
//then later on after we commit the groups in question, we'll make a note of what now is, and then correct it in all test setups.
//custom channels have an autoincrement id, because of this we have to do a two step dance with them
//#1, look for existing custom channel if possible and just use it's id
//#2, or insert a new custom channel, get it's id, then update all templates and channels with that custom channel
// with th enew id
var customChannels = _importObject.CustomChannels().ToList();
if (customChannels == null || !customChannels.Any())
{
return;
}
for (int currentCCIdx = customChannels.Count - 1; currentCCIdx >= 0; currentCCIdx--)
{
var cc = customChannels[currentCCIdx];
customChannels.RemoveAt(currentCCIdx);
if (IsCancelled()) { return; }
var oldid = cc.Id; //this is the id from the import file
long newid;
var existing = CustomChannelList.List.GetChannelByISOCode(IsoCodeStatics.GetString(cc, false), false);
if (null != existing)
{
//custom channel already exists, just use it's id
newid = existing.Channel.Id;
cc.SetId(newid);
}
else
{
//custom channel doesn't exist, we need to insert it, but we have to clear the id first so we can insert it
//we've already held onto the old id, so we're good.
cc.ClearId();
}
//update or insert the custom channel
var customchannel = new CustomChannel(cc);
CustomChannelList.List.Commit(customchannel, true, false);
newid = customchannel.Channel.Id; //this is now the official id of the custom channel,
//go through all the channels, updating the ids if needed
var groupTemplates = _importObject.GroupTemplates().ToList();
for (var i = groupTemplates.Count - 1; i >= 0; i--)
{
var gt = groupTemplates[i];
var isoGT = gt.ToISOTestObjectTemplate();
var bUpdated = false;
foreach (var ch in isoGT.Channels)
{
if (ch.Channel.Text_L1 != cc.Text_L1 ||
ch.Channel.MMEChannelType != (int)MMEPossibleChannels.MMEChannelTypes.SQL)
continue;
ch.SetID(newid);
bUpdated = true;
}
//if the group template wasn't updated, then we are done with that group template, if however it was updated
//we then have to go through all groups and update the sensor assignments
if (!bUpdated) continue;
var db = IsoDb;
groupTemplates[i] = new DataPROWin7.DataModel.TestObjectTemplate(isoGT, ref db);
var templateName = isoGT.TemplateName;
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingGroups, PossibleStatus = PossibleStatus.Importing });
var groups = new List<DataPROWin7.DataModel.TestObject>(_importObject.Groups());
foreach (var t in _importObject.TestSetups().Where(t => t.AddedGroups.Any()))
{
groups.AddRange(t.AddedGroups.ToArray());
}
foreach (var g in groups)
{
if (g.Template.TemplateName != templateName) continue;
var oldISOTO = g.GetISOTestObject();
//because of the changing custom channel ids, we have to hold onto some of the properties
//of the import group before we repopulate it with the new template
var isoCodeToSensorSerialNumberLookup = new Dictionary<string, string>();
var isoCodeToHardwareChannelIdLookup = new Dictionary<string, string>();
foreach (var ch in oldISOTO.AllChannels)
{
if (ch.Channel.Text_L1 != cc.Text_L1) continue;
if (string.IsNullOrWhiteSpace(ch.SensorSerialNumber)) continue;
isoCodeToSensorSerialNumberLookup[IsoCodeStatics.GetString(ch.Channel, false)] = ch.SensorSerialNumber;
isoCodeToHardwareChannelIdLookup[IsoCodeStatics.GetString(ch.Channel, false)] = ch.HardwareId;
}
//assign the new template, and then update the channels in the template with a sensor/hardware id if necessary
g.SetTemplateDontResetISOObject(groupTemplates[i]);
var newISOTO = g.GetISOTestObject();
foreach (var ch in newISOTO.AllChannels)
{
if (ch.Channel.MMEChannelType == (int)MMEPossibleChannels.MMEChannelTypes.ISO13499_106) { continue; }
var ccIso = IsoCodeStatics.GetString(cc, false);
if (ch.Channel.Text_L1 != cc.Text_L1 || !isoCodeToSensorSerialNumberLookup.ContainsKey(ccIso))
continue;
//keep a track of what once was
var oldChannelId = ch.GetIdWithSpecificChannelId(oldid);
CustomChannelTextIdToOldChannelId[ccIso] = oldChannelId;
CustomChannelOldChannelIdToChannel[oldChannelId] = ch;
ch.Channel.SetId(customchannel.Channel.Id);
ch.SensorSerialNumber = isoCodeToSensorSerialNumberLookup[ccIso];
ch.HardwareId = isoCodeToHardwareChannelIdLookup[ccIso];
}
}
}
_persistCalculator.AddDone();
_importNotification.SetProgress(_persistCalculator.ProgressValue);
//speed up memory collection by forcing GC
//11287 Out of memory exception when importing large CSV Test Setup files
//This is a critical code smell- moved from existing code base find a better way to handle this in future
//https://rules.sonarsource.com/csharp/RSPEC-1215/
// GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
}
CustomChannelList.List.UpdateAll();
}
}
}