98 lines
7.4 KiB
Markdown
98 lines
7.4 KiB
Markdown
---
|
|
source_files:
|
|
- Common/DTS.Common.SettingsDB/UserSetting.cs
|
|
- Common/DTS.Common.SettingsDB/Setting.cs
|
|
- Common/DTS.Common.SettingsDB/GlobalSetting.cs
|
|
- Common/DTS.Common.SettingsDB/SettingsDB.cs
|
|
generated_at: "2026-04-16T14:10:18.570863+00:00"
|
|
model: "zai-org/GLM-5-FP8"
|
|
schema_version: 1
|
|
sha256: "0690ee9f2887691d"
|
|
---
|
|
|
|
# Documentation: DTS.Common.Settings
|
|
|
|
## 1. Purpose
|
|
This module provides a persistence layer for application and user-specific configuration settings. It implements a caching singleton pattern (`SettingsDB`) to manage key-value pairs stored in a SQL database, supporting both global (system-wide) and user-specific contexts. The module abstracts database interaction details, offering typed accessors for primitives and arrays, and handles the creation of default values when settings do not exist in the database.
|
|
|
|
## 2. Public Interface
|
|
|
|
### Class: `DTS.Common.Settings.SettingsDB`
|
|
A static facade and singleton manager for accessing all settings. This is the primary entry point for interacting with settings.
|
|
|
|
**Methods:**
|
|
* `static void RefreshSettings()`: Clears the in-memory cache dictionary, forcing subsequent reads to fetch from the database.
|
|
* `static string GetUserValue(string id, string defaultValue, string user)`: Retrieves a setting specific to a user. If the key does not exist in the cache or DB, it creates a new `UserSetting` using the default value and persists it.
|
|
* `static string GetGlobalValue(string id, string defaultValue, bool useCache = true)`: Retrieves a global setting. Accepts a flag to bypass the cache.
|
|
* `static void GetAllGlobalValues()`: Loads all global settings from the database into the local cache.
|
|
* `static double GetGlobalValueDouble(string id, double defaultValue)`: Retrieves a global setting parsed as a `double`.
|
|
* `static int GetGlobalValueInt(string id, int defaultValue)`: Retrieves a global setting parsed as an `int`.
|
|
* `static bool GetGlobalValueBool(string id, bool defaultValue, bool useCache = true)`: Retrieves a global setting parsed as a `bool`.
|
|
* `static double[] GetGlobalValueDoubleArray(string id, double[] defaultValues)`: Retrieves a global setting as an array of doubles.
|
|
* `static int[] GetGlobalValueIntArray(string id, int[] defaultValues)`: Retrieves a global setting as an array of integers.
|
|
* `static void SetUserValue(string id, string value, string user)`: Updates a user-specific setting in the cache and persists it to the database.
|
|
* `static void SetGlobalValue(string id, string value)`: Updates a global setting in the cache and persists it to the database.
|
|
* `static void SetGlobalValueDouble(string id, double value)`: Persists a global setting from a `double` input.
|
|
* `static void SetGlobalValueInt(string id, int value)`: Persists a global setting from an `int` input.
|
|
* `static void SetGlobalValueBoolean(string id, bool value)`: Persists a global setting from a `bool` input.
|
|
* `static void SetGlobalValueDoubleArray(string id, double[] values)`: Persists an array of doubles as a series of global settings.
|
|
* `static void SetGlobalValueIntArray(string id, int[] values)`: Persists an array of integers as a series of global settings.
|
|
|
|
### Class: `DTS.Common.Settings.GlobalSetting`
|
|
Represents a system-wide setting.
|
|
|
|
**Methods:**
|
|
* `GlobalSetting(string id, string defaultPropertyValue)`: Constructor that initializes the setting and loads/instantiates it in the DB.
|
|
* `static GlobalSetting ReadXML(System.Xml.XmlElement root)`: Creates a `GlobalSetting` instance from an XML element.
|
|
* `static GlobalSetting[] GetAllGlobalSettings()`: Fetches all global settings from the database.
|
|
|
|
### Class: `DTS.Common.Settings.UserSetting`
|
|
Represents a user-specific setting.
|
|
|
|
**Methods:**
|
|
* `UserSetting(string id, string defaultValue, string user)`: Constructor that initializes the setting for a specific user.
|
|
|
|
### Class: `DTS.Common.Settings.Setting`
|
|
Abstract base class for settings.
|
|
|
|
**Properties:**
|
|
* `string PropertyId`: The unique identifier for the setting.
|
|
* `PropertyTypes PropertyType`: Enum indicating `User` (1) or `Global` (2).
|
|
* `string PropertyValue`: The string value of the setting.
|
|
* `string UserId`: The user ID associated with the setting (or "SYSTEM" for global).
|
|
|
|
**Methods:**
|
|
* `void SetValue(string value)`: Sets the value of the property and persists the change to the database.
|
|
|
|
## 3. Invariants
|
|
|
|
1. **Cache Key Uniqueness**: User settings are cached with a composite key format `{id}_{user}`, whereas global settings are cached using just the `id`.
|
|
2. **Global User Identity**: All `GlobalSetting` instances use the constant string `"SYSTEM"` as the `UserId` in database transactions.
|
|
3. **Auto-Creation**: Retrieving a non-existent setting via `GetUserValue` or `GetGlobalValue` triggers an insert operation (`StoreInDB`) to persist the provided default value.
|
|
4. **Array Storage Convention**: Arrays are stored as discrete keys in the database.
|
|
* Length is stored in key `{id}_x_Count`.
|
|
* Elements are stored in keys `{id}_x_{index}`.
|
|
5. **Thread Safety**: All public static methods in `SettingsDB` utilize a `lock` on a static `LOCK_OBJECT` to ensure thread-safe access to the singleton `_settingsLookup` dictionary.
|
|
|
|
## 4. Dependencies
|
|
|
|
**Internal Dependencies:**
|
|
* `DTS.Common.Storage`: Used for `DbOperations`, `DbOperationsEnum`, and database connection management.
|
|
* `DTS.Common.Utilities.Logging`: Used for `APILogger` to log exceptions and messages.
|
|
|
|
**External Dependencies:**
|
|
* `System.Data` & `System.Data.SqlClient`: Used for ADO.NET database operations (`SqlConnection`, `SqlCommand`, `SqlParameter`).
|
|
* `System.Xml`: Used in `GlobalSetting.ReadXML`.
|
|
|
|
**Database Dependencies:**
|
|
* Stored Procedure `sp_SettingsGet`: Used to retrieve settings.
|
|
* Stored Procedure `sp_SettingsUpdateInsert`: Used to create or update settings.
|
|
|
|
## 5. Gotchas
|
|
|
|
* **Silent Failures in `UserSetting`**: The `GetPropertyValue` method in `UserSetting` catches all exceptions, sets the value to the default, and continues. Database errors or connection issues will be silently ignored, and the user will receive the default value without any indication that the DB read failed.
|
|
* **Ignored DB Errors in `Setting.StoreInDB`**: The `StoreInDB` method retrieves `@errorNumber` and `@errorMessage` output parameters, but if `@errorNumber` is non-zero, the code block is empty (commented out). Database errors during save are effectively ignored, though the exception is caught and logged.
|
|
* **Null Default Handling**: `GlobalSetting.GetPropertyValue` explicitly throws `NullDefaultValueException` if the setting is missing from the DB and the provided default value is `null`. In contrast, `UserSetting` handles this gracefully by setting the internal value to null/empty.
|
|
* **Legacy Setting Migration**: `SettingsDB` contains specific hardcoded logic for `ImportCreateDynamicGroups`. When setting this boolean value, the code also updates a legacy key `CSVImportCreateDynamicGroups` to maintain backward compatibility with pre-Version 93 clients.
|
|
* **Redundant Ternary Logic**: In `GetGlobalValueBool`, the return statement `!bool.TryParse(sValue, out b) ? b : b` is redundant; it returns `b` in both branches.
|
|
* **Connection Disposal**: The code manually calls `cmd.Connection.Dispose()` inside a `finally` block within `using` statements. While `using` disposes the `SqlCommand`, manually disposing the connection (which might be shared or managed by `DbOperations`) could lead to unexpected behavior depending on the implementation of `DbOperations.GetSQLCommand(true)`. |