--- 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-16T04:27:03.727990+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "7a6cc3dcbca85c45" --- # Documentation: TestSetups Module (DbAPI) ## 1. Purpose This module provides data access layer (DAL) interfaces and implementations for managing test setup–related entities in the database: graphs, calculated channels, regions of interest (ROIs), and test setups themselves (including hardware metadata and group associations). It acts as a bridge between higher-level application logic and SQL Server stored procedures, enforcing user authentication, validating input parameters, and translating database errors into standardized error codes. The module is part of the `DbAPI.TestSetups` namespace and is used to persist and retrieve configuration data for physical test setups (e.g., in data acquisition systems), supporting CRUD operations and domain-specific logic such as ROI generation defaults and test setup completeness flags. ## 2. Public Interface All interfaces define *public* contracts; implementations are internal (`CalculatedChannels`, `Graphs`, `RegionsOfInterest`, `TestSetups` classes). Only interface methods are documented here. ### `IGraphs` - **`ulong GraphsGet(IUserDbRecord user, IConnectionDetails connection, int? graphId, int? testSetupId, out IGraphRecord[] records)`** Retrieves graph records matching optional `graphId` and `testSetupId`. Returns array of `IGraphRecord`. - `graphId`: specific graph ID (nullable); `null` means all graphs for given `testSetupId`. - `testSetupId`: required to filter graphs by test setup. - **`ulong GraphsUpdate(IUserDbRecord user, IConnectionDetails connection, IGraphRecord record)`** Updates an existing graph record in the database. - Requires `record.GraphId` to be non-null and valid. - **`ulong GraphsInsert(IUserDbRecord user, IConnectionDetails connection, ref IGraphRecord record)`** Inserts a new graph record. After successful insert, `record.GraphId` is updated with the database-generated ID. - **`ulong GraphsDelete(IUserDbRecord user, IConnectionDetails connection, int graphId)`** Deletes the graph with the specified `graphId`. ### `ICalculatedChannels` - **`ulong CalculatedChannelsDelete(IUserDbRecord user, IConnectionDetails connection, int calculatedChannelId)`** Deletes the calculated channel with the specified `calculatedChannelId`. - **`ulong CalculatedChannelsGet(IUserDbRecord user, IConnectionDetails connection, int? calculatedChannelId, string testSetupName, out ICalculatedChannelRecord[] records)`** Retrieves calculated channel records matching optional `calculatedChannelId` and `testSetupName`. - `testSetupName` may be empty string (`""`) to match no test setup. - **`ulong CalculatedChannelsInsert(IUserDbRecord user, IConnectionDetails connection, ref ICalculatedChannelRecord record)`** Inserts a new calculated channel. After successful insert, `record.Id` is updated with the database-generated ID. - **`ulong CalculatedChannelsUpdate(IUserDbRecord user, IConnectionDetails connection, ICalculatedChannelRecord record)`** Updates an existing calculated channel. Requires `record.Id` to be set. ### `IRegionsOfInterest` - **`ulong RegionsOfInterestDelete(IUserDbRecord user, IConnectionDetails connection, int testSetupId)`** Deletes *all* ROI records associated with the given `testSetupId` from both `TestSetupROIs` and `ROIPeriodChannels` tables. - **`ulong RegionsOfInterestInsert(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupId, IRegionOfInterest regionOfInterest)`** Inserts ROI data into `TestSetupROIs` and `ROIPeriodChannels` tables. - `clientDbVersion`: passed to stored procedure (likely for version-specific logic). - **`ulong RegionsOfInterestGet(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, int testSetupId, out IRegionOfInterest[] records)`** Retrieves all ROI records for the given `testSetupId`, combining data from `TestSetupROIs` and `ROIPeriodChannels`. - **`ulong TestSetupROIsDelete(...)`** Deletes only from `TestSetupROIs` table (not `ROIPeriodChannels`). Signature matches `RegionsOfInterestDelete`. - **`ulong TestSetupROIsInsert(..., out int testSetupROIId)`** Inserts into `TestSetupROIs` only; outputs the new `testSetupROIId`. - **`ulong TestSetupROIsGet(..., out ITestSetupROIRecord[] records)`** Retrieves only `TestSetupROIs` records (not joined with `ROIPeriodChannels`). - **`ulong ROIPeriodChannelsInsert(...)`** Inserts a single `ROIPeriodChannels` record (channel mapping for an ROI period). - **`ulong ROIPeriodChannelsGet(..., out IROIPeriodChannelRecord[] roiPeriodChannelRecords)`** Retrieves `ROIPeriodChannels` records for a given `testSetupROIId`. ### `ITestSetups` - **`ulong TestSetupHardwareDelete(..., int? Id, int? dasId, int? testSetupId)`** Deletes hardware metadata records. At least one of `Id`, `dasId`, or `testSetupId` must be non-null. - **`ulong TestSetupHardwareUpdate(..., ITestSetupHardwareRecord record)`** Updates a hardware metadata record. - **`ulong TestSetupHardwareInsert(..., ITestSetupHardwareRecord record)`** Inserts a hardware metadata record. - **`ulong TestSetupHardwareGet(..., int clientDbVersion, int? testSetupId, out ITestSetupHardwareRecord[] records)`** Retrieves hardware metadata (e.g., sample rate, anti-aliasing filter settings) for given `testSetupId` or all. - **`ulong TestSetupGroupsInsert(..., ITestSetupGroupRecord record)`** Inserts a group–test setup association. - **`ulong TestSetupGroupsUpdate(..., ITestSetupGroupRecord record)`** Updates a group–test setup association. - **`ulong TestSetupGroupsGet(..., int? groupId, int? testSetupId, string testSetupName, out ITestSetupGroupRecord[] groups)`** Retrieves group–test setup associations matching criteria. - **`ulong TestSetupsMarkIsDirtyIsComplete(..., string name, bool dirty, bool complete, string error)`** Updates `IsDirty` and `IsComplete` flags for a test setup named `name`. `error` may contain validation messages. - **`ulong TestSetupsDeleteByDate(..., DateTime date)`** Deletes all test setups *older than* `date`. - **`ulong TestSetupsAndGroupsDeleteAll(...)`** Deletes *all* test setups and associated group associations. - **`ulong TestSetupsDeleteById(..., int[] ids)`** Deletes test setups by their IDs. - **`ulong TestSetupsDeleteByName(..., string[] names)`** Deletes test setups by their names. - **`ulong TestSetupsUpdateInsert(..., int clientDbVersion, ref ITestSetupRecord record)`** Inserts or updates a test setup record. `record` is passed by reference and may be modified (e.g., ID populated on insert). - **`ulong TestSetupsGet(..., int clientDbVersion, int? testSetupId, string testSetupName, double defaultROIStart, double defaultROIEnd, bool defaultIgnoreShortedStart, bool defaultIgnoreShortedTrigger, out ITestSetupRecord[] records, out string[] errors)`** Retrieves test setup records. Includes logic to generate default ROIs if missing (using `defaultROIStart`/`defaultROIEnd`). - `defaultIgnoreShortedStart`/`defaultIgnoreShortedTrigger`: flags for backward compatibility with older DB versions (e.g., v91) that lack these fields. ## 3. Invariants - **Authentication**: All methods first check `IsUserLoggedIn(user, connection)`; if false, return `ERROR_ACCESS_DENIED`. - **Error Handling**: All methods return `ERROR_SUCCESS` (0) on success; non-zero values are error codes. Errors are logged via `LogManager`. - **Null/Empty Handling**: - Nullable parameters (`int?`, `string`) accept `null` or `""` (where applicable) to mean "no filter". - `CalculatedChannelsGet` allows empty `testSetupName`. - `GraphsGet` requires `testSetupId` to be non-null if filtering by test setup (but `graphId` may be null). - **Input Validation**: - `GraphsInsert`, `CalculatedChannelsInsert`, `CalculatedChannelsUpdate`, `CalculatedChannelsDelete` validate `record != null`. - `TestSetupHardwareDelete` requires at least one ID parameter (`Id`, `dasId`, `testSetupId`) to be non-null. - **Output Parameters**: - `ref` parameters (`record` in `Insert` methods) are updated with database-generated IDs after successful insert. - `out` parameters (`records`, `errors`) are always initialized (e.g., `records = new T[0]` on failure). - **Resource Cleanup**: All methods dispose `SqlCommand` and connection in `finally` blocks. ## 4. Dependencies ### Module Dependencies - **`DbAPI.Connections`**: Provides `IsUserLoggedIn`, `ConnectionManager.GetSqlCommand`. - **`DbAPI.Errors`**: Defines `ErrorCodes.ERROR_*` constants. - **`DbAPI.Logging`**: Provides `LogManager`. - **`DTS.Common.Interface.*`**: - `Database`: `IUserDbRecord`, `IConnectionDetails`. - `Graphs`: `IGraphRecord`, `GraphRecord`. - `TestSetups`: `ICalculatedChannelRecord`, `ITestSetupRecord`, `ITestSetupHardwareRecord`, `ITestSetupGroupRecord`, `IRegionOfInterest`, `ITestSetupROIRecord`, `IROIPeriodChannelRecord`. - `RegionOfInterest`: `IRegionOfInterest`. - **`System.Data.SqlClient`**: Used for `SqlCommand`, `SqlDbType`, `SqlParameter`. - **`System.Globalization`**: Used for `CultureInfo.InvariantCulture.TextInfo.ListSeparator` (in `CalculatedChannels`). ### Inferred Usage - Higher-level services (e.g., test setup management UI/backend) depend on these interfaces. - The `TestSetups` class (not shown) likely orchestrates calls to `IGraphs`, `ICalculatedChannels`, `IRegionsOfInterest`, and `ITestSetups`. ## 5. Gotchas - **`GraphsDelete` bug**: In `Graphs.cs`, `GraphsDelete` passes `@TestSetupId = null` to `sp_TestGraphsDelete` *regardless* of input. This likely ignores the `testSetupId` parameter from the interface and may delete graphs incorrectly (only filters by `@GraphId`). → *Observed in source: `cmd.Parameters.Add(new SqlParameter("@TestSetupId", SqlDbType.Int) { Value = null });`* - **Logging inconsistency**: In `CalculatedChannelsGet`, errors are logged under `LogManager.LogEvents.Graphs` instead of `LogManager.LogEvents.CalculatedChannels`. → *Likely copy-paste error.* - **`TestSetupROIsInsert` vs `RegionsOfInterestInsert`**: `RegionsOfInterestInsert` inserts into *both* `TestSetupROIs` and `ROIPeriodChannels`, while `TestSetupROIsInsert` inserts only into `TestSetupROIs`. Confusing naming—`RegionsOfInterest*` implies full ROI handling, but `TestSetupROIs*` is a partial subset. - **`TestSetupsGet` side effects**: The `defaultROIStart`/`defaultROIEnd` parameters suggest the method may *generate* default ROIs on retrieval (not just read them). This could cause unexpected behavior if callers expect pure read-only behavior. - **`CalculatedChannelsInsert`/`Update` input encoding**: `InputChannelIds` is converted to `byte[]` using `Utility.GetBytesFromStringArray(..., ListSeparator)`. The separator is hardcoded to `CultureInfo.InvariantCulture.TextInfo.ListSeparator` (typically `","`), but if `record.InputChannelIds` contains commas, parsing may fail. No validation or escaping is visible. - **Missing `clientDbVersion` in `Graphs*` methods**: Unlike `RegionsOfInterest` and `TestSetups`, the `Graphs` methods do not accept a `clientDbVersion` parameter, suggesting version-specific logic is not supported for graphs. - **No transaction support**: All operations are executed individually. If a logical operation requires multiple DB calls (e.g., insert ROI + period channels), callers must manage transactions externally. - **No explicit validation of `testSetupId` existence**: Methods like `RegionsOfInterestInsert` accept `testSetupId` but do not verify it exists in the database before inserting. This may cause FK violations if the test setup is missing.