Files
2026-04-17 14:55:32 -04:00

9.2 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/CustomerDetails.cs
DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/LabratoryDetails.cs
DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/TestEngineerDetails.cs
2026-04-16T04:59:22.874172+00:00 Qwen/Qwen3-Coder-Next-FP8 1 283afdf9f6a03436

Documentation: Test Metadata Wrappers (Version 57)

1. Purpose

This module provides managed wrapper classes for low-level ISO.*Details types (CustomerDetails, LabratoryDetails, TestEngineerDetails) used in database export operations for Version 57 of the database schema. Its primary role is to encapsulate and standardize access to these domain entities—offering lazy-loaded, sorted, and deduplicated collections via singleton list managers (CustomerDetailsList, LabratoryDetailsList, TestEngineerDetailsList). It ensures consistent handling of a special "(none)" placeholder entry and provides thread-safe access to metadata used in test reporting and export workflows.

2. Public Interface

CustomerDetails

  • CustomerDetails()
    Default constructor. Initializes internal _customerDetails with a new ISO.CustomerDetails, setting its Name to "(none)".
  • CustomerDetails(ISO.CustomerDetails customerDetails)
    Copy constructor. Creates a new ISO.CustomerDetails instance from the provided customerDetails.
  • string Name { get; set; }
    Gets or sets the Name property of the underlying ISO.CustomerDetails.
  • ISO.CustomerDetails GetISOCustomer()
    Returns the internal ISO.CustomerDetails instance.
  • override string ToString()
    Returns the Name property.

CustomerDetailsList

  • static CustomerDetailsList CustomerList { get; }
    Singleton accessor.
  • CustomerDetails[] Customers { get; }
    Returns a sorted (by Name, ordinal) array of all CustomerDetails, including the "(none)" entry. Thread-safe via lock and lazy initialization.
  • CustomerDetails[] GetAllCustomers()
    Returns a fresh array containing a new "(none)" CustomerDetails followed by all CustomerDetails created from ISO.CustomerDetails.GetAllCustomerDetails().
  • CustomerDetails GetCustomerDetail(string name)
    Returns the first CustomerDetails in Customers (parallel query) matching name, or null if none found.

LabratoryDetails

  • LabratoryDetails()
    Default constructor. Initializes _lab with a new ISO.LabratoryDetails, setting Name to "(none)".
  • LabratoryDetails(ISO.LabratoryDetails lab)
    Copy constructor. Creates a new ISO.LabratoryDetails instance from lab.
  • string Name { get; set; }
    Gets or sets the Name property of _lab.
  • ISO.LabratoryDetails GetIsoLab()
    Returns the internal _lab instance.
  • override string ToString()
    Returns the Name property.

LabratoryDetailsList

  • protected LabratoryDetailsList()
    Protected constructor (enforces singleton via private instantiation).
  • static LabratoryDetailsList LabratoryList { get; }
    Singleton accessor.
  • LabratoryDetails[] Labs { get; }
    Returns a sorted (by Name, ordinal) array of all LabratoryDetails, including "(none)". Thread-safe via lock and lazy initialization.
  • LabratoryDetails GetLab(string name)
    Returns the LabratoryDetails for name from the internal _labs dictionary (if populated), or null. Includes exception handling (logs via APILogger on failure).
  • private LabratoryDetails[] GetAllLabs()
    Returns a fresh array containing a new "(none)" LabratoryDetails followed by all LabratoryDetails created from ISO.LabratoryDetails.GetAllLabratoryDetails(). Includes exception handling.

TestEngineerDetails

  • TestEngineerDetails()
    Default constructor. Initializes _testEngineerDetails with a new ISO.TestEngineerDetails, setting Name to "(none)".
  • TestEngineerDetails(ISO.TestEngineerDetails testEngineerDetails)
    Copy constructor. Creates a new ISO.TestEngineerDetails instance from testEngineerDetails.
  • string Name { get; set; }
    Gets or sets the Name property of _testEngineerDetails.
  • ISO.TestEngineerDetails GetISOTestEngineer()
    Returns the internal _testEngineerDetails instance.
  • override string ToString()
    Returns the Name property.

TestEngineerDetailsList

  • static TestEngineerDetailsList TestEngineerList { get; }
    Singleton accessor.
  • TestEngineerDetails[] TestEngineers { get; }
    Returns a sorted (by Name, using CompareTo) array of all TestEngineerDetails, including "(none)". Thread-safe via lock and lazy initialization.
  • TestEngineerDetails[] GetAllTestEngineers()
    Returns a fresh array containing a new "(none)" TestEngineerDetails followed by all TestEngineerDetails created from ISO.TestEngineerDetails.GetAllTestEngineerDetails().
  • TestEngineerDetails GetTestEngineerDetail(string name)
    Returns the first TestEngineerDetails in TestEngineers (parallel LINQ query) matching name, or null.

3. Invariants

  • "(none)" Placeholder: Each list (CustomerDetails, LabratoryDetails, TestEngineerDetails) always includes a special entry with Name == "(none)" as the first element returned by GetAll*() methods.
  • Deduplication: The internal _customers, _labs, and _testEngineers dictionaries use Name as the key, ensuring only one entry per unique name (last one wins in case of duplicates in GetAll*()).
  • Sorted Output: The Customers, Labs, and TestEngineers properties return arrays sorted by Name using ordinal string comparison (String.Compare(..., StringComparison.Ordinal) or CompareTo).
  • Thread Safety: All list properties (Customers, Labs, TestEngineers) and their underlying population methods (PopulateCustomers, PopulateList, PopulateEngineers) are guarded by dedicated static lock objects. However, GetCustomerDetail and GetTestEngineerDetail use AsParallel() on the already-computed Customers/TestEngineers array, which is safe but not optimized.
  • Null Handling: Compare* methods explicitly handle null inputs (returning -1, 0, or 1 as appropriate). Get*Detail methods return null if no match is found.

4. Dependencies

  • Internal Dependencies:
    • ISO.CustomerDetails, ISO.LabratoryDetails, ISO.TestEngineerDetails (from the ISO namespace) — core data types being wrapped.
    • ISO.CustomerDetails.GetAllCustomerDetails(), ISO.LabratoryDetails.GetAllLabratoryDetails(), ISO.TestEngineerDetails.GetAllTestEngineerDetails() — static methods to fetch raw data.
  • External Dependencies:
    • DTS.Utilities.Logging.APILogger (used in LabratoryDetailsList only) — for logging exceptions during lab retrieval.
    • Standard .NET: System, System.Collections.Generic, System.Linq.
  • Depended Upon: This module is part of DatabaseExport namespace and is likely consumed by higher-level export/reporting logic in the DataPRO system (not visible in source).

5. Gotchas

  • Inconsistent Naming: Class is named LabratoryDetails (misspelled) instead of LaboratoryDetails. This typo is propagated in both class and list names.
  • Exception Swallowing: LabratoryDetailsList silently swallows exceptions in GetLab and GetAllLabs (logs only via APILogger), which may hide failures during lab data loading.
  • Race Condition in Populate*: While Populate* methods are called under lock, they are not idempotent-safe in all cases:
    • CustomerDetailsList.PopulateCustomers() checks if (null != _customers) return; — safe.
    • TestEngineerDetailsList.PopulateEngineers() does not check _testEngineers != null before reassigning — safe only because its called under lock and only once.
    • LabratoryDetailsList.PopulateList() has the same safe guard (if (null != _labs) return;).
      → All are safe in practice due to locking, but the pattern is fragile.
  • Redundant Copying: Both constructors (CustomerDetails(ISO.CustomerDetails), etc.) create a new instance of the underlying ISO.*Details (via copy constructor), not a reference wrapper. This is intentional but may be surprising if mutation of the returned ISO.*Details is expected to affect the wrappers internal state.
  • Inconsistent Get*Detail Implementations:
    • CustomerDetailsList.GetCustomerDetail and TestEngineerDetailsList.GetTestEngineerDetail use AsParallel() on the already-computed array — unnecessary overhead for small lists.
    • LabratoryDetailsList.GetLab uses direct dictionary lookup (_labs.ContainsKey) — more efficient, but only works after Labs property has been accessed (since _labs is populated in Labs getter, not eagerly).
  • No Validation: No validation on Name values (e.g., empty strings, duplicates in raw data) — relies on underlying ISO.* types or data source to prevent invalid names.
  • Hardcoded Placeholder: The "(none)" string is hardcoded in constructors. No constant or resource reference (despite commented-out Strings.StringResources.TestTemplate_EmptyListName in TestEngineerDetails).