--- source_files: - DataPRO/DbAPI/TestSetups/IGraphs.cs - DataPRO/DbAPI/TestSetups/ICalculatedChannels.cs - DataPRO/DbAPI/TestSetups/IRegionsOfInterest.cs - DataPRO/DbAPI/TestSetups/ITestSetups.cs - DataPRO/DbAPI/TestSetups/CalculatedChannels.cs - DataPRO/DbAPI/TestSetups/Graphs.cs generated_at: "2026-04-17T15:51:12.206877+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "37c4e37f0df42b66" --- # TestSetups Module Documentation ## 1. Purpose This module provides the database access layer for test setup configuration data within the DataPRO system. It defines and implements CRUD operations for four primary entities: graphs (`IGraphs`/`Graphs`), calculated channels (`ICalculatedChannels`/`CalculatedChannels`), regions of interest (`IRegionsOfInterest`), and test setup metadata (`ITestSetups`). The module abstracts SQL Server stored procedure calls behind strongly-typed interfaces, handling user authentication, parameter marshalling, and error propagation. It serves as the persistence boundary between the application's domain model and the relational database. --- ## 2. Public Interface ### IGraphs Interface | Method | Signature | |--------|-----------| | `GraphsGet` | `ulong GraphsGet(IUserDbRecord user, IConnectionDetails connection, int? graphId, int? testSetupId, out IGraphRecord[] records)` | | `GraphsUpdate` | `ulong GraphsUpdate(IUserDbRecord user, IConnectionDetails connection, IGraphRecord record)` | | `GraphsInsert` | `ulong GraphsInsert(IUserDbRecord user, IConnectionDetails connection, ref IGraphRecord record)` | | `GraphsDelete` | `ulong GraphsDelete(IUserDbRecord user, IConnectionDetails connection, int graphId)` | **Behaviors:** - `GraphsGet`: Retrieves graph records filtered by optional `graphId` and/or `testSetupId`. Returns empty array if no matches. - `GraphsUpdate`: Updates an existing graph record identified by `record.GraphId`. - `GraphsInsert`: Inserts a new graph record. The `ref` parameter is mutated with the new `GraphId` from the database. - `GraphsDelete`: Removes a graph record by its database ID. ### ICalculatedChannels Interface | Method | Signature | |--------|-----------| | `CalculatedChannelsDelete` | `ulong CalculatedChannelsDelete(IUserDbRecord user, IConnectionDetails connection, int calculatedChannelId)` | | `CalculatedChannelsGet` | `ulong CalculatedChannelsGet(IUserDbRecord user, IConnectionDetails connection, int? calculatedChannelId, string testSetupName, out ICalculatedChannelRecord[] records)` | | `CalculatedChannelsInsert` | `ulong CalculatedChannelsInsert(IUserDbRecord user, IConnectionDetails connection, ref ICalculatedChannelRecord record)` | | `CalculatedChannelsUpdate` | `ulong CalculatedChannelsUpdate(IUserDbRecord user, IConnectionDetails connection, ICalculatedChannelRecord record)` | **Behaviors:** - `CalculatedChannelsGet`: Retrieves calculated channel records filtered by optional `calculatedChannelId` and/or `testSetupName`. - `CalculatedChannelsInsert`: Inserts a new calculated channel. The `ref` parameter is mutated with the new `Id` from the database. - `CalculatedChannelsUpdate`: Updates an existing calculated channel identified by `record.Id`. - `CalculatedChannelsDelete`: Removes a calculated channel by its database ID. ### IRegionsOfInterest Interface | Method | Signature | |--------|-----------| | `RegionsOfInterestDelete` | `ulong RegionsOfInterestDelete(IUserDbRecord user, IConnectionDetails connection, int testSetupId)` | | `RegionsOfInterestInsert` | `ulong RegionsOfInterestInsert(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupId, IRegionOfInterest regionOfInterest)` | | `RegionsOfInterestGet` | `ulong RegionsOfInterestGet(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupId, out IRegionOfInterest[] records)` | | `TestSetupROIsDelete` | `ulong TestSetupROIsDelete(IUserDbRecord user, IConnectionDetails connection, int testSetupId)` | | `TestSetupROIsInsert` | `ulong TestSetupROIsInsert(IUserDbRecord user, IConnectionDetails connection, int testSetupId, IRegionOfInterest regionOfInterest, out int testSetupROIId)` | | `TestSetupROIsGet` | `ulong TestSetupROIsGet(IUserDbRecord user, IConnectionDetails connection, int testSetupId, out ITestSetupROIRecord[] records)` | | `ROIPeriodChannelsInsert` | `ulong ROIPeriodChannelsInsert(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupROIId, string channelName, long channelId)` | | `ROIPeriodChannelsGet` | `ulong ROIPeriodChannelsGet(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupROIId, out IROIPeriodChannelRecord[] roiPeriodChannelRecords)` | **Behaviors:** - `RegionsOfInterestDelete`: Removes records from both `TestSetupROIs` and `ROIPeriodChannels` tables for a given `testSetupId`. - `RegionsOfInterestInsert`: Inserts records into both `TestSetupROIs` and `ROIPeriodChannels` tables. - `RegionsOfInterestGet`: Retrieves and combines records from `TestSetupROIs` and `ROIPeriodChannels` tables. - `TestSetupROIsInsert`: Inserts into `TestSetupROIs` table; outputs the new `testSetupROIId`. ### ITestSetups Interface | Method | Signature | |--------|-----------| | `TestSetupHardwareDelete` | `ulong TestSetupHardwareDelete(IUserDbRecord user, IConnectionDetails connection, int? Id, int? dasId, int? testSetupId)` | | `TestSetupHardwareUpdate` | `ulong TestSetupHardwareUpdate(IUserDbRecord user, IConnectionDetails connection, ITestSetupHardwareRecord record)` | | `TestSetupHardwareInsert` | `ulong TestSetupHardwareInsert(IUserDbRecord user, IConnectionDetails connection, ITestSetupHardwareRecord record)` | | `TestSetupHardwareGet` | `ulong TestSetupHardwareGet(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int? testSetupId, out ITestSetupHardwareRecord[] records)` | | `TestSetupGroupsInsert` | `ulong TestSetupGroupsInsert(IUserDbRecord user, IConnectionDetails connection, ITestSetupGroupRecord record)` | | `TestSetupGroupsUpdate` | `ulong TestSetupGroupsUpdate(IUserDbRecord user, IConnectionDetails connection, ITestSetupGroupRecord record)` | | `TestSetupGroupsGet` | `ulong TestSetupGroupsGet(IUserDbRecord user, IConnectionDetails connection, int? groupId, int? testSetupId, string testSetupName, out ITestSetupGroupRecord[] groups)` | | `TestSetupsMarkIsDirtyIsComplete` | `ulong TestSetupsMarkIsDirtyIsComplete(IUserDbRecord user, IConnectionDetails connection, string name, bool dirty, bool complete, string error)` | | `TestSetupsDeleteByDate` | `ulong TestSetupsDeleteByDate(IUserDbRecord user, IConnectionDetails connection, DateTime date)` | | `TestSetupsAndGroupsDeleteAll` | `ulong TestSetupsAndGroupsDeleteAll(IUserDbRecord user, IConnectionDetails connection)` | | `TestSetupsDeleteById` | `ulong TestSetupsDeleteById(IUserDbRecord user, IConnectionDetails connection, int[] ids)` | | `TestSetupsDeleteByName` | `ulong TestSetupsDeleteByName(IUserDbRecord user, IConnectionDetails connection, string[] names)` | | `TestSetupsUpdateInsert` | `ulong TestSetupsUpdateInsert(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, ref ITestSetupRecord record)` | | `TestSetupsGet` | `ulong TestSetupsGet(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int? testSetupId, string testSetupName, double defaultROIStart, double defaultROIEnd, bool defaultIgnoreShortedStart, bool defaultIgnoreShortedTrigger, out ITestSetupRecord[] records, out string[] errors)` | **Behaviors:** - `TestSetupHardwareDelete`: Requires at least one of `Id`, `dasId`, or `testSetupId` to be specified. - `TestSetupsMarkIsDirtyIsComplete`: Updates the `IsDirty` and `IsComplete` flags for a test setup by name. - `TestSetupsGet`: Accepts default ROI values for backward compatibility with older database versions that may lack ROI data. --- ## 3. Invariants 1. **Return Value Convention**: All methods return `ulong` where `0` equals `ERROR_SUCCESS`. Any non-zero value indicates an error. 2. **Authentication Requirement**: All public methods in `Graphs` and `CalculatedChannels` implementations call `DbAPI.Connections.IsUserLoggedIn(user, connection)` before executing database operations. Failure returns `ErrorCodes.ERROR_ACCESS_DENIED`. 3. **Null Record Handling**: Insert and Update methods in `CalculatedChannels` check for null `record` parameter and return `ErrorCodes.ERROR_MISSING_PARAMETER` if null. 4. **Resource Cleanup**: All implementations use `try/finally` blocks to dispose of `SqlCommand` and its `Connection`. The `SqlConnection` is disposed via `cmd.Connection.Dispose()`. 5. **Stored Procedure Usage**: All database operations use stored procedures (e.g., `sp_CalculatedChannelsInsert`, `sp_TestGraphsGet`). No inline SQL is used. 6. **Output Parameter Mutation**: Insert methods (`GraphsInsert`, `CalculatedChannelsInsert`) use `ref` parameters to return the newly assigned database ID to the caller. 7. **Error Propagation**: Stored procedures return errors via `@errorNumber` and `@errorMessage` output parameters. Non-zero error numbers are logged via `LogManager.Log` and result in `ErrorCodes.ERROR_UNKNOWN` being returned. --- ## 4. Dependencies ### This module depends on: | Namespace | Purpose | |-----------|---------| | `DbAPI.Connections` | `IConnectionDetails`, `ConnectionManager.GetSqlCommand()`, `IsUserLoggedIn()` | | `DbAPI.Errors` | `ErrorCodes` constants (`ERROR_SUCCESS`, `ERROR_ACCESS_DENIED`, `ERROR_MISSING_PARAMETER`, `ERROR_UNKNOWN`) | | `DbAPI.Logging` | `LogManager.Log()`, `LogEvents` enum | | `DTS.Common.Interface.Database` | `IUserDbRecord` | | `DTS.Common.Interface.Graphs` | `IGraphRecord` | | `DTS.Common.Interface.TestSetups` | `ICalculatedChannelRecord`, `ITestSetupRecord`, `ITestSetupHardwareRecord`, `ITestSetupGroupRecord`, `ITestSetupROIRecord`, `IROIPeriodChannelRecord` | | `DTS.Common.Interface.RegionOfInterest` | `IRegionOfInterest` | | `DTS.Common.Classes.TestSetups` | Concrete implementations: `GraphRecord`, `CalculatedChannelRecord` | | `DTS.Common.Classes` | `Utility.GetBytesFromStringArray()` | | `System.Data.SqlClient` | `SqlConnection`, `SqlCommand`, `SqlParameter`, `SqlDataReader` | ### What depends on this module: Not determinable from the provided source files alone. The interfaces are public and the implementations are `internal`, suggesting they are consumed by other components within the `DbAPI` assembly. --- ## 5. Gotchas 1. **Incorrect Log Event in `CalculatedChannelsGet`**: The implementation logs errors using `LogEvents.Graphs` instead of `LogEvents.CalculatedChannels`: ```csharp LogManager.Log(TraceEventType.Error, LogManager.LogEvents.Graphs, $"sp_CalculatedChannelsGet failed: {ex.Message}"); ``` This appears to be a copy-paste error. 2. **Incorrect Log Message in `GraphsDelete`**: The exception log message incorrectly references "GraphsInsert": ```csharp LogManager.Log(TraceEventType.Error, LogManager.LogEvents.Graphs, $"GraphsInsert exception {ex.Message}"); ``` 3. **Inconsistent Command Disposal**: The `Graphs` class only disposes `cmd.Connection` in its `finally` block, while `CalculatedChannels` disposes both `cmd.Connection` and `cmd`. This may indicate inconsistent cleanup patterns. 4. **Missing XML Documentation**: The `IRegionsOfInterest` interface lacks XML documentation for `TestSetupROIsDelete`, `TestSetupROIsInsert`, `TestSetupROIsGet`, `ROIPeriodChannelsInsert`, and `ROIPeriodChannelsGet` methods. 5. **Undocumented `clientDbVersion` Parameter**: The purpose and valid values of the `clientDbVersion` parameter (present in `IRegionsOfInterest` and `ITestSetups` methods) is not documented in the interface. Comments in `TestSetupsGet` hint at Version 91 database compatibility concerns, but specifics are unclear from source alone. 6. **InputChannelIds Serialization**: `CalculatedChannelsInsert` and `CalculatedChannelsUpdate` serialize `InputChannelIds` using `Utility.GetBytesFromStringArray()` with `CultureInfo.InvariantCulture.TextInfo.ListSeparator`. The deserialization logic is not present in these files.