315 lines
14 KiB
Markdown
315 lines
14 KiB
Markdown
---
|
|
source_files:
|
|
- Common/DTS.Common.Import/Persist/SaveServer.cs
|
|
- Common/DTS.Common.Import/Persist/SaveGroupTemplates.cs
|
|
- Common/DTS.Common.Import/Persist/SaveVariantBase.cs
|
|
- Common/DTS.Common.Import/Persist/SaveGlobalSettings.cs
|
|
- Common/DTS.Common.Import/Persist/PersistCalculator.cs
|
|
- Common/DTS.Common.Import/Persist/SaveSensorModels.cs
|
|
- Common/DTS.Common.Import/Persist/SaveTestEngineerDetails.cs
|
|
- Common/DTS.Common.Import/Persist/SaveLabDetails.cs
|
|
- Common/DTS.Common.Import/Persist/SaveUsers.cs
|
|
- Common/DTS.Common.Import/Persist/SaveCustomerDetails.cs
|
|
- Common/DTS.Common.Import/Persist/SaveHardware.cs
|
|
- Common/DTS.Common.Import/Persist/SaveTestSetupHelper.cs
|
|
- Common/DTS.Common.Import/Persist/SaveGroups.cs
|
|
- Common/DTS.Common.Import/Persist/SaveCustomChannels.cs
|
|
- Common/DTS.Common.Import/Persist/SaveTestSetup.cs
|
|
- Common/DTS.Common.Import/Persist/SaveCheckoutTestSetup.cs
|
|
generated_at: "2026-04-16T11:46:11.806575+00:00"
|
|
model: "zai-org/GLM-5-FP8"
|
|
schema_version: 1
|
|
sha256: "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)
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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
|
|
```csharp
|
|
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)
|
|
```csharp
|
|
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
|
|
|
|
1. **Cancellation Check Pattern**: All `Save()` implementations check `IsCancelled()` at the start of each iteration loop and return immediately if true.
|
|
|
|
2. **Progress Reporting Pattern**: After each item is processed, implementations call `_persistCalculator.AddDone()` followed by `_importNotification.SetProgress(_persistCalculator.ProgressValue)`.
|
|
|
|
3. **Constructor Signature**: All `SaveVariantBase` subclasses accept the same base parameters: `ImportObject`, `IPersistCalculator`, `IImportNotification`, and optional `Func<bool> isCancelled`.
|
|
|
|
4. **Null Cancellation Handler**: If `isCancelled` is null, `SaveVariantBase` assigns a lambda returning `false`.
|
|
|
|
5. **ProgressValue Calculation**: `ProgressValue` is calculated as `_done / _total`. Division by zero is possible if `AddToTotal()` is never called (undefined behavior in source).
|
|
|
|
6. **AddToTotal Validation**: `PersistCalculator.AddToTotal()` throws `ArgumentOutOfRangeException` if `value < 0`.
|
|
|
|
7. **Hardware ID Mapping**: `SaveHardware` always populates `OldDASIdToNewDASId` when DAS IDs change during commit.
|
|
|
|
8. **Group ID Mapping**: `SaveGroups` always populates `OldGroupIdToNewGroupId` for non-embedded static groups.
|
|
|
|
---
|
|
|
|
## 4. Dependencies
|
|
|
|
### This module depends on:
|
|
- **DTS.Common.Import.Interfaces** - `IPersistImport` interface (inferred)
|
|
- **DTS.Common.Settings** - `SettingsDB` for global settings persistence
|
|
- **DTS.SensorDB** - `SensorModelCollection`, `SensorsCollection` for sensor data
|
|
- **DTS.Slice.Users** - `User`, `UserCollection`, `IUIItems` for 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** - `StringResources` for localized error messages
|
|
- **DTS.Common.Storage** - `DbOperations` for 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
|
|
|
|
1. **SaveServer is unimplemented**: Calling `Save()` on `SaveServer` throws `NotImplementedException`.
|
|
|
|
2. **SaveCustomerDetails status typo**: Sets `ImportExtraStatus.ReadingLabDetails` instead of a customer-specific status (likely copy-paste error from `SaveLabDetails`).
|
|
|
|
3. **SaveUsers admin assertion**: Uses `Trace.Assert` to verify admin status — this only triggers in debug builds; production builds will silently proceed with potentially unauthorized operations.
|
|
|
|
4. **SaveGroupTemplates does nothing**: Iterates group templates but performs no persistence — only updates progress.
|
|
|
|
5. **Division by zero risk**: `PersistCalculator.ProgressValue` returns `_done / _total` without checking if `_total` is zero.
|
|
|
|
6. **SaveHardware sorts in-place**: Calls `_importObject.Hardware().ToList().Sort()` but then iterates the original `_importObject.Hardware()` — unclear if this has any effect since `ToList()` creates a copy.
|
|
|
|
7. **SaveCustomChannels memory concern**: Contains commented-out `GC.Collect()` with a code smell note referencing issue #11287 (out of memory exceptions on large CSV imports).
|
|
|
|
8. **Interdependent save order**: `SaveGroups` requires `SaveHardware` to be executed first (needs `OldDASIdToNewDASId`). `SaveTestSetup` requires `SaveCustomChannels`, `SaveHardware`, and `SaveGroups`. Order of execution matters.
|
|
|
|
9. **SaveCheckoutTestSetup clears groups**: Explicitly clears `t.Groups` and `t.ChannelsForGroup` before repopulating — this modifies the import object state.
|
|
|
|
10. **SaveTestSetup and SaveCheckoutTestSetup delete existing setups**: Both call `DeleteExistingTestSetups()` which removes existing test setups by name before importing. |