Files
DP44/enriched-qwen3-coder-next/DataPRO/DbAPI/Database.md
2026-04-17 14:55:32 -04:00

8.2 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/DbAPI/Database/IDatabase.cs
DataPRO/DbAPI/Database/Database.cs
2026-04-16T04:24:57.920635+00:00 Qwen/Qwen3-Coder-Next-FP8 1 460fbd3d82516ff4

Database

Documentation: DbAPI.Database Module


1. Purpose

This module provides core database versioning and metadata operations for the DataPRO system. It defines and implements the IDatabase interface, enabling retrieval of the highest database version (GetDatabaseVersion), insertion of new version records (InsertDatabaseVersion), and extraction of the SQL Server major version (GetSQLVersion). It also includes utility methods for resolving versioned stored procedure names (GetStoredProcedureVersion, GetStoredProcedureVersionCached, PrepareForDbAccess), supporting backward/forward compatibility across database schema versions. The module acts as a low-level abstraction layer between application logic and SQL Server, enforcing user authentication and delegating to stored procedures for persistence.


2. Public Interface

The interface IDatabase is the public contract. The concrete implementation Database is internal, so only IDatabase members are externally visible.

IDatabase.GetSQLVersion(IConnectionDetails connection) → int

  • Behavior: Retrieves the major version number (e.g., 15 for SQL Server 2019) from the servers ServerVersion string.
  • Notes: Does not require user authentication. Returns 0 on failure (e.g., parsing error or connection issue).

IDatabase.GetDatabaseVersion(IUserDbRecord user, IConnectionDetails connection, out int version) → ulong

  • Behavior: Executes the stored procedure sp_DBVersionGet to fetch all version records, then returns the maximum version number via the out int version parameter.
  • Authentication: Does not enforce user login (despite XML comment stating “User must be logged in” — implementation explicitly allows querying without login).
  • Return: ErrorCodes.ERROR_SUCCESS (0) on success; ErrorCodes.ERROR_UNKNOWN on exception.
  • Output: version is set to 0 on failure.

IDatabase.InsertDatabaseVersion(IUserDbRecord user, IConnectionDetails connection, int version, int step, DateTime date, string remarks, string userField) → ulong

  • Behavior: Inserts a new version record into the database by calling the stored procedure sp_DbVersionInsert.
  • Authentication: Explicitly checks IsUserLoggedIn(user, connection); returns ErrorCodes.ERROR_ACCESS_DENIED if not logged in.
  • Parameters:
    • version, step, date, remarks, userField → values inserted into the record.
  • Return: ErrorCodes.ERROR_SUCCESS on success; ErrorCodes.ERROR_UNKNOWN on SQL error (non-zero @errorNumber output) or exception.
  • Notes: Does not validate uniqueness or ordering of version numbers — duplicates or regressions are allowed.

Database.GetStoredProcedureVersion(IConnectionDetails connection, string storedProcedure, int clientDbVersion) → string

  • Behavior: Resolves the correct stored procedure name (e.g., sp_MyProc vs sp_MyProc_3) based on client and DB versions. Calls DbAPI.GetStoredProcedureToUse.
  • Fallback: Returns original storedProcedure name if resolution fails.

Database.GetStoredProcedureVersionCached(IConnectionDetails connection, string storedProcedure) → string

  • Behavior: Same as GetStoredProcedureVersion, but uses a cached result (via DbAPI.GetStoredProcedureToUseCached) to avoid repeated DB lookups.
  • Uses: connection.ClientDbVersion as the client version.

Database.PrepareForDbAccess(IUserDbRecord user, IConnectionDetails connection, int clientDbVersion, string storedProcedure, out int storedProcedureVersionToUse, out SqlCommand cmd) → ulong

  • Behavior: A helper to prepare a SqlCommand for a versioned stored procedure.
  • Steps:
    1. Checks user login (IsUserLoggedIn) → returns ERROR_ACCESS_DENIED if false.
    2. Resolves stored procedure name version via DbAPI.GetStoredProcedureToUse.
    3. Creates SqlCommand via ConnectionManager.GetSqlCommand.
  • Output:
    • storedProcedureVersionToUse: resolved version suffix (e.g., 3), or 0 if none.
    • cmd: fully configured SqlCommand object.
  • Return: ERROR_SUCCESS on success; otherwise error code (e.g., ERROR_ACCESS_DENIED, ERROR_UNKNOWN).

3. Invariants

  • Authentication Enforcement: InsertDatabaseVersion and PrepareForDbAccess require the user to be logged in (checked via IsUserLoggedIn). Failure to meet this yields ERROR_ACCESS_DENIED.
  • Stored Procedure Naming: Versioned stored procedures follow the pattern {baseName}_{version} (e.g., sp_MyProc_2). A version suffix of 0 implies no suffix (i.e., base name only).
  • Error Handling: All methods log exceptions to LogManager at TraceEventType.Error level before returning ERROR_UNKNOWN.
  • Resource Management: All SqlCommand objects created via ConnectionManager.GetSqlCommand have their .Connection disposed in finally blocks.
  • No Validation on Version Values: InsertDatabaseVersion does not check for duplicate versions, ordering (e.g., regression), or consistency with existing records.

4. Dependencies

Imports/References:

  • DbAPI.Connections → Provides ConnectionManager, IsUserLoggedIn, and GetStoredProcedureToUse/GetStoredProcedureToUseCached.
  • DbAPI.Errors → Defines ErrorCodes (e.g., ERROR_SUCCESS, ERROR_ACCESS_DENIED, ERROR_UNKNOWN).
  • DbAPI.LoggingLogManager for error logging.
  • DTS.Common.Interface.Database → Interfaces IUserDbRecord, IConnectionDetails.
  • DTS.Common.Classes → Likely contains Utility.GetInt (used in GetDatabaseVersion).
  • System.Data, System.Data.SqlClient → Core ADO.NET types (SqlCommand, SqlParameter, SqlDbType, CommandType, DBNull, IDataReader).

Used By:

  • Any module requiring database versioning operations (e.g., upgrade scripts, version reporting, audit logging).
  • Likely consumed via IDatabase interface (injected or resolved via DI/container — not evident from source).

5. Gotchas

  • Contradictory Authentication Requirement:
    GetDatabaseVersions XML comment states “User must be logged into database”, but the implementation does not call IsUserLoggedIn. This is a discrepancy between documentation and behavior.

  • No Version Uniqueness/Ordering Checks:
    InsertDatabaseVersion blindly inserts records — callers must ensure version numbers are monotonically increasing and unique, or risk data inconsistency.

  • GetSQLVersion Fragility:
    Assumes ServerVersion is dot-separated (e.g., "15.0.2000.5"). Parsing relies on Split(".") and int.Parse on the first segment — will throw if format changes (e.g., "15-0-2000" or "15.0.2000.5-SP2").

  • GetDatabaseVersion Uses Max() on List<int>:
    If no version records exist, dbVersionsList.Max() throws InvalidOperationException. However, the catch block suppresses this and returns ERROR_UNKNOWN with version = 0. This is safe but may mask empty-db scenarios.

  • Stored Procedure Name Resolution:
    GetStoredProcedureVersion and PrepareForDbAccess rely on external DbAPI.GetStoredProcedureToUse/GetStoredProcedureToUseCached. Behavior of these (e.g., how version mapping is determined) is not visible here.

  • userField Parameter Misleading Name:
    The userField parameter in InsertDatabaseVersion is documented as “What user to associate with the insert record (does not have to match any actual users)” — implying its a free-text field, not a foreign key. Do not assume it validates against a user table.

  • No Transaction Support:
    All operations are standalone; no mechanism for atomic multi-step versioning (e.g., insert + update).

  • GetStoredProcedureVersionCached Uses connection.ClientDbVersion:
    Assumes IConnectionDetails exposes a ClientDbVersion property — not visible in this module but required for correct behavior.


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