14 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-04-16T11:46:11.806575+00:00 | zai-org/GLM-5-FP8 | 1 | 695fcda61b684601 |
DTS.Common.Import.Persist Module Documentation
1. Purpose
This module implements the persistence layer for an import system, responsible for saving various imported data entities (hardware, users, test setups, groups, sensors, etc.) to a database. It follows the Strategy pattern where each SaveVariantBase subclass handles a specific entity type, providing a unified interface (IPersistImport) for the import pipeline while supporting progress tracking, cancellation, and error reporting.
2. Public Interface
SaveVariantBase (Abstract Base Class)
public abstract class SaveVariantBase : IPersistImport
{
protected ImportObject _importObject;
protected readonly IPersistCalculator _persistCalculator;
protected readonly IImportNotification _importNotification;
protected readonly Func<bool> IsCancelled;
protected SaveVariantBase(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, Func<bool> isCancelled = null)
public abstract void Save();
}
Base class for all save variants. Provides shared infrastructure for progress reporting, cancellation checking, and access to the import data object.
IPersistCalculator / PersistCalculator
public interface IPersistCalculator
{
void AddDone();
void AddDone(double value);
double ProgressValue { get; }
void AddToTotal(double value);
}
public class PersistCalculator : IPersistCalculator
{
public double ProgressValue { get; } // Returns _done / _total
public void AddDone();
public void AddDone(double value);
public void AddToTotal(double value); // Throws ArgumentOutOfRangeException if value < 0
}
Tracks progress as a ratio of completed work (_done) to total work (_total).
SaveServer
public class SaveServer : SaveVariantBase
{
public SaveServer(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, Func<bool> isCancelled = null)
public override void Save(); // Throws NotImplementedException
}
Stub implementation — currently unimplemented.
SaveGroupTemplates
public class SaveGroupTemplates : SaveVariantBase
{
public SaveGroupTemplates(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, Func<bool> isCancelled = null)
public override void Save(); // Iterates _importObject.GroupTemplates(), updates progress
}
Iterates group templates without persisting them (appears to be a placeholder that only updates progress).
SaveGlobalSettings
public class SaveGlobalSettings : SaveVariantBase
{
public override void Save(); // Calls SettingsDB.SetGlobalValue(g.Key, g.Value) for each setting
}
Persists global settings via SettingsDB.SetGlobalValue().
SaveSensorModels
public class SaveSensorModels : SaveVariantBase
{
public User CurrentUser { get; set; }
public override void Save(); // Commits sensor models via SensorModelCollection.SensorModelList.Commit()
}
Persists sensor models. Requires CurrentUser to be set for the commit operation.
SaveTestEngineerDetails
public class SaveTestEngineerDetails : SaveVariantBase
{
public override void Save(); // Adds test engineers via TestEngineerDetailsList.TestEngineerList.AddTestEngineer()
}
Persists test engineer details. Sets status to ImportExtraStatus.ReadingEngineerDetails.
SaveLabDetails
public class SaveLabDetails : SaveVariantBase
{
public override void Save(); // Adds labs via LabratoryDetailsList.AddLab()
}
Persists lab details. Skips invalid/blank entries (calls l.IsInvalidBlank()). Sets status to ImportExtraStatus.ReadingLabDetails.
SaveUsers
public class SaveUsers : SaveVariantBase
{
public IUIItems[] UIItems { get; set; }
public User CurrentUser { get; set; }
public override void Save(); // Commits users via UserCollection.UsersList.Commit()
}
Persists users. Asserts that CurrentUser.IsAdmin is true (will fail in debug builds if non-admin attempts import). Sets status to ImportExtraStatus.ReadingUsers.
SaveCustomerDetails
public class SaveCustomerDetails : SaveVariantBase
{
public override void Save(); // Adds customers via CustomerDetailsList.AddCustomer()
}
Persists customer details. Skips invalid/blank entries. Note: Sets status to ImportExtraStatus.ReadingLabDetails (appears to be a copy-paste error).
SaveHardware
public class SaveHardware : SaveVariantBase
{
public Dictionary<int, int> OldDASIdToNewDASId { get; set; } = new Dictionary<int, int>();
public Dictionary<int, List<IISOHardware>> TestIdToHardware { get; set; } = new Dictionary<int, List<IISOHardware>>();
public override void Save(); // Commits hardware via DASHardwareList.GetList().Commit()
}
Persists hardware configurations. Tracks DAS ID remapping (OldDASIdToNewDASId) and hardware-to-test relationships (TestIdToHardware). Sorts hardware before processing. Progress includes both hardware items and their channels.
SaveGroups
public class SaveGroups : SaveVariantBase
{
public bool CanCurrentUserCommitChannelCodes { get; set; } = true;
public IChannelSetting DefaultZeroMethod { get; set; }
public IChannelSetting DefaultZeroStart { get; set; }
public IChannelSetting DefaultZeroEnd { get; set; }
public IChannelSetting DefaultInitialOffset { get; set; }
public Dictionary<int?, int> OldGroupIdToNewGroupId { get; set; } = new Dictionary<int?, int>();
public SaveGroups(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, SaveHardware saveHardware, Func<bool> isCancelled = null)
public override void Save();
}
Persists static groups. Requires SaveHardware dependency for DAS ID remapping. Fixes missing zero method parameters and initial offsets. Maps old group IDs to new IDs. Reports warnings for groups with channels assigned to unknown DAS.
SaveCustomChannels
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 override void Save();
}
Persists custom channels via CustomChannelList.List.Commit(). Handles ID remapping for existing channels. Updates group templates and groups that reference custom channels. Calls CustomChannelList.List.UpdateAll() at the end.
SaveTestSetup
public class SaveTestSetup : SaveVariantBase
{
public User CurrentUser { get; set; }
public string TestSetupName { get; set; }
public SaveTestSetup(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, SaveCustomChannels saveCustomChannels,
SaveHardware saveHardware, SaveGroups saveGroups, Func<bool> isCancelled = null)
public override void Save();
}
Persists test setups via TestTemplateList.TestTemplatesList.Commit(). Requires dependencies on SaveCustomChannels, SaveHardware, and SaveGroups. Handles special case for ImportFileFormat.SingleTestSetup with custom naming. Deletes existing test setups before import. Updates hardware TestId references after commit.
SaveCheckoutTestSetup
public class SaveCheckoutTestSetup : SaveVariantBase
{
public User CurrentUser { get; set; }
public SaveCheckoutTestSetup(ImportObject importObject, IPersistCalculator persistCalculator,
IImportNotification importNotification, SaveCustomChannels saveCustomChannels,
SaveHardware saveHardware, SaveGroups saveGroups,
Func<bool> isCancelled = null, string setupName = null)
public override void Save();
}
Persists checkout test setups with specific configuration (checkout mode enabled, missing sensors allowed, etc.). Creates new groups from ChannelsForGroup configuration.
SaveTestSetupHelper (Static Class)
public static class SaveTestSetupHelper
{
public static void AddHardwareFromEmbeddedGroups(TestTemplate t, SaveGroups saveGroups,
List<int> hardwareRemoved, List<int> hardwareIncluded);
public static void FixDasAff(Dictionary<string, DASHardware> hardwareLookup, TestTemplate t);
public static Dictionary<string, DASHardware> PopulateHarwareLookup();
public static void DeleteExistingTestSetups(IEnumerable<TestTemplate> testSetups, string userName);
public static void UpdateLevelTriggers(ref Dictionary<string, string> oldIdToNewIdLookup,
SaveCustomChannels saveCustomChannels, IEnumerable<TestTemplate> testSetups);
}
Helper methods extracted for reuse between SaveTestSetup and SaveCheckoutTestSetup.
3. Invariants
-
Cancellation Check Pattern: All
Save()implementations checkIsCancelled()at the start of each iteration loop and return immediately if true. -
Progress Reporting Pattern: After each item is processed, implementations call
_persistCalculator.AddDone()followed by_importNotification.SetProgress(_persistCalculator.ProgressValue). -
Constructor Signature: All
SaveVariantBasesubclasses accept the same base parameters:ImportObject,IPersistCalculator,IImportNotification, and optionalFunc<bool> isCancelled. -
Null Cancellation Handler: If
isCancelledis null,SaveVariantBaseassigns a lambda returningfalse. -
ProgressValue Calculation:
ProgressValueis calculated as_done / _total. Division by zero is possible ifAddToTotal()is never called (undefined behavior in source). -
AddToTotal Validation:
PersistCalculator.AddToTotal()throwsArgumentOutOfRangeExceptionifvalue < 0. -
Hardware ID Mapping:
SaveHardwarealways populatesOldDASIdToNewDASIdwhen DAS IDs change during commit. -
Group ID Mapping:
SaveGroupsalways populatesOldGroupIdToNewGroupIdfor non-embedded static groups.
4. Dependencies
This module depends on:
- DTS.Common.Import.Interfaces -
IPersistImportinterface (inferred) - DTS.Common.Settings -
SettingsDBfor global settings persistence - DTS.SensorDB -
SensorModelCollection,SensorsCollectionfor sensor data - DTS.Slice.Users -
User,UserCollection,IUIItemsfor user management - DataPROWin7.DataModel - Core data models (
TestTemplate,DASHardware,CustomerDetails,LabratoryDetails,TestEngineerDetails,CustomChannel, etc.) - DTS.Common.Import.Enums -
ImportStatus,ImportExtraStatus,PossibleStatus,ImportFileFormat,ImportSeverityError - DTS.Common.Interface.Channels - Channel interfaces
- DTS.Common.Interface.Groups.GroupList -
IGroup,IGroupChannel,GroupHelper - DTS.Common.SharedResource.Strings -
StringResourcesfor localized error messages - DTS.Common.Storage -
DbOperationsfor database queries - DTS.Common.ISO -
ISO13499FileDb,IsoCodeStatics,MMEPossibleChannels - DTS.Common.Classes.Groups.ChannelSettings -
ChannelSettingBase,IChannelSetting - DTS.Common.Interface.DASFactory.Diagnostics - Diagnostics interfaces
- DTS.Common.Enums -
SupportedExportFormatBitFlags
What depends on this module:
- Cannot be determined from source alone (no consumers shown).
5. Gotchas
-
SaveServer is unimplemented: Calling
Save()onSaveServerthrowsNotImplementedException. -
SaveCustomerDetails status typo: Sets
ImportExtraStatus.ReadingLabDetailsinstead of a customer-specific status (likely copy-paste error fromSaveLabDetails). -
SaveUsers admin assertion: Uses
Trace.Assertto verify admin status — this only triggers in debug builds; production builds will silently proceed with potentially unauthorized operations. -
SaveGroupTemplates does nothing: Iterates group templates but performs no persistence — only updates progress.
-
Division by zero risk:
PersistCalculator.ProgressValuereturns_done / _totalwithout checking if_totalis zero. -
SaveHardware sorts in-place: Calls
_importObject.Hardware().ToList().Sort()but then iterates the original_importObject.Hardware()— unclear if this has any effect sinceToList()creates a copy. -
SaveCustomChannels memory concern: Contains commented-out
GC.Collect()with a code smell note referencing issue #11287 (out of memory exceptions on large CSV imports). -
Interdependent save order:
SaveGroupsrequiresSaveHardwareto be executed first (needsOldDASIdToNewDASId).SaveTestSetuprequiresSaveCustomChannels,SaveHardware, andSaveGroups. Order of execution matters. -
SaveCheckoutTestSetup clears groups: Explicitly clears
t.Groupsandt.ChannelsForGroupbefore repopulating — this modifies the import object state. -
SaveTestSetup and SaveCheckoutTestSetup delete existing setups: Both call
DeleteExistingTestSetups()which removes existing test setups by name before importing.