init
This commit is contained in:
126
enriched-qwen3-coder-next/DataPRO/DbAPI/Database.md
Normal file
126
enriched-qwen3-coder-next/DataPRO/DbAPI/Database.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
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 server’s `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 it’s 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.*
|
||||
Reference in New Issue
Block a user