Files
DP44/enriched-qwen3-coder-next/DataPRO/Modules/DatabaseImporter/DatabaseImport/SettingsDB.md
2026-04-17 14:55:32 -04:00

7.5 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/DatabaseImporter/DatabaseImport/SettingsDB/GlobalSetting.cs
DataPRO/Modules/DatabaseImporter/DatabaseImport/SettingsDB/SettingsDB.cs
DataPRO/Modules/DatabaseImporter/DatabaseImport/SettingsDB/Setting.cs
2026-04-16T04:30:58.292022+00:00 Qwen/Qwen3-Coder-Next-FP8 1 f40d6df6287d52df

SettingsDB

Documentation: Global Settings Module (DatabaseImport)


1. Purpose

This module provides a centralized, thread-safe mechanism for managing application-wide (global) settings stored in a SQL Server database. It abstracts the persistence logic for global configuration properties, ensuring that each setting is lazily loaded from the database on first access, falls back to a provided default value if missing, and caches the setting instance in memory for subsequent lookups. It is part of the DatabaseImporter module and serves as the canonical source for global configuration values used during database import operations.


2. Public Interface

SettingsDB (Static Class)

  • public static string GetGlobalValue(string id, string defaultValue)
    Retrieves the global setting value for id. If the setting does not exist in the cache or database, it is created with defaultValue, stored in the DB, and returned. Thread-safe via singleton + lock.

  • public static bool GetGlobalValueBool(string id, bool defaultValue)
    Retrieves the global setting as a bool. Converts the stored string value using bool.TryParse; if parsing fails, returns defaultValue. Thread-safe.

  • public static void SetGlobalValue(string id, string value)
    Sets the global setting id to value. Updates the in-memory cache and persists to the database via StoreInDB(). Thread-safe.

  • public static void SetGlobalValueBoolean(string id, bool value)
    Sets the global setting id to the string representation of value (using InvariantCulture). Updates cache and persists. Thread-safe.

GlobalSetting (Concrete Class, inherits Setting)

  • public GlobalSetting(string id, string defaultPropertyValue)
    Constructor. Initializes a GlobalSetting with PropertyType = Global, UserId = "SYSTEM", and triggers GetPropertyValue(defaultPropertyValue).

Setting (Abstract Base Class)

  • public string PropertyId { get; }
    Read-only identifier of the setting (e.g., "ImportBatchSize").

  • public string PropertyValue { get; }
    Current value of the setting (as string). Note: No length validation is enforced at this layer.

  • public string UserId { get; }
    User context for the setting. For GlobalSetting, this is always "SYSTEM".

  • public void SetValue(string value)
    Updates _propertyValue and persists the change via StoreInDB().

  • protected abstract void GetPropertyValue(string defaultValue)
    Implemented by subclasses to fetch the value from the database (or other source). GlobalSetting implements this to query the DB.


3. Invariants

  • Singleton & Thread Safety: SettingsDB is a singleton with lazy initialization. All public static methods (GetGlobalValue, SetGlobalValue, etc.) are guarded by a lock (LOCK_OBJECT) on the singleton instance, ensuring thread-safe access to _settingsLookup and DB operations.

  • Global Scope: GlobalSetting instances are always associated with UserId = "SYSTEM" and PropertyType = PropertyTypes.Global (value 2).

  • Default Fallback: If a setting does not exist in the database, GetPropertyValue falls back to the provided defaultValue, stores it in the DB via StoreInDB(), and returns it.

  • Caching: Once instantiated, a Setting object is cached in SettingsDB._settingsLookup. Subsequent lookups for the same id reuse the cached instance.

  • DB Schema Assumption: The module assumes:

    • A stored procedure sp_SettingsGet exists, accepting @UserId (NVARCHAR) and @PropertyId (NVARCHAR), returning a result set with a column named PropertyValue (via DbOperations.Settings.UserFields.PropertyValue).
    • A stored procedure sp_SettingsUpdateInsert exists, accepting parameters: @PropertyId, @PropertyType, @PropertyValue, @UserId, @new_id (OUTPUT), @errorNumber (OUTPUT), @errorMessage (OUTPUT). All string parameters are NVARCHAR(255).

4. Dependencies

Dependencies of this module:

  • System.Data and System.Data.SqlClient (for SqlDataAdapter, SqlCommand, SqlParameter, SqlDbType, etc.)
  • DbOperations (static class, not shown) — provides:
    • GetSQLCommand(bool) → returns SqlCommand
    • Connection.QueryDataSet(SqlCommand) → returns DataSet
    • Settings.UserFields.PropertyValue → string constant for column name (e.g., "PropertyValue")
    • DbOperationsEnum.StoredProcedure.sp_SettingsGet, sp_SettingsUpdateInsert → enum values for stored procedure names.

Dependencies on this module:

  • Any code requiring global configuration (e.g., import batch size, timeout, feature flags) calls SettingsDB.GetGlobalValue(...) or GetGlobalValueBool(...).

Inferred callers:

  • DatabaseImporter module (e.g., import pipeline components that read global settings like "MaxRetryCount", "DefaultSchema").

5. Gotchas

  • Exception Handling is Minimal:
    GetPropertyValue and StoreInDB both catch Exception and silently fall back to defaultValue or do nothing, respectively. No logging is active (commented-out APILogger.LogException suggests future intent). This makes debugging DB issues difficult.

  • No Validation on Value Length:
    PropertyValue is stored as NVARCHAR(255) in DB calls, but no validation occurs in Setting or GlobalSetting. Passing a >255-character value may cause a DB error (silently ignored in StoreInDB).

  • Race Condition in Initialization (Low Risk):
    While GetGlobalValue locks before checking _settingsLookup, the first call for a new id creates a new GlobalSetting inside the lock. However, GlobalSetting constructor calls GetPropertyValue, which performs a DB round-trip while holding the lock. This can cause contention if many settings are requested concurrently for the first time.

  • Hardcoded "SYSTEM" User:
    GlobalSetting hardcodes UserId = "SYSTEM". This is not configurable and assumes all global settings are owned by a system user.

  • _allGlobalSetting Cache is Unused:
    The GetPropertyValue method contains commented-out code for a _allGlobalSetting cache. This suggests a previous optimization attempt that was reverted or incomplete — the current implementation hits the DB on every first access for a new id.

  • Culture-Specific Boolean Parsing:
    GetGlobalValueBool uses defaultValue.ToString(CultureInfo.InvariantCulture) for the fallback string, but bool.TryParse is culture-insensitive for "True"/"False". This is safe, but the use of InvariantCulture here is redundant and could mislead.

  • No Explicit Disposal of Setting Instances:
    Setting instances are stored in _settingsLookup and never removed. If settings are frequently added/removed at runtime, this could lead to memory leaks.

  • No Distinction Between null and Empty String:
    If the DB stores NULL for PropertyValue, Convert.ToString(...) returns "" (empty string), not null. This may or may not be intended.


Documentation generated from provided source files. No external assumptions or behaviors inferred beyond what is explicitly present.