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

126 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- DataPRO/DbAPI/Database/IDatabase.cs
- DataPRO/DbAPI/Database/Database.cs
generated_at: "2026-04-16T04:24:57.920635+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "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.Logging``LogManager` 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**:
`GetDatabaseVersion`s 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.*