This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseInitializationScripts/EmbeddedResource.cs
generated_at: "2026-04-16T04:35:11.382491+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ae12472d249773d0"
---
# DatabaseInitializationScripts
## 1. Purpose
This module provides utilities for reading embedded resources (e.g., SQL scripts, configuration files) from a .NET assemblys manifest resources. It exists to abstract away the boilerplate of locating and extracting embedded resources by name, particularly supporting scenarios where database initialization scripts are bundled as embedded resources within the assembly. It enables both stream-based and string-based access to such resources, with overloads that allow specifying a custom assembly or defaulting to the assembly containing the `EmbeddedResource` class itself.
## 2. Public Interface
- **`static StreamReader GetStream(Assembly assembly, string name)`**
Searches the manifest resource names of the given `assembly` for a resource whose name *ends with* the provided `name` (case-sensitive substring match), and returns a `StreamReader` for the first matching resource. Returns `null` if no match is found.
*Note: The caller is responsible for disposing the returned `StreamReader`.*
- **`static string GetString(Assembly assembly, string name)`**
Calls `GetStream(assembly, name)`, reads the entire contents of the stream into a string using `ReadToEnd()`, closes the stream, and returns the resulting string. Returns `null` if `GetStream` returns `null`.
*Note: This method disposes the `StreamReader` internally via `sr.Close()`.*
- **`static string GetString(string name)`**
Overload of `GetString` that uses the assembly containing the `EmbeddedResource` class itself (`typeof(EmbeddedResource).Assembly`) as the target assembly. Behaves identically to `GetString(assembly, name)` for that assembly.
## 3. Invariants
- **Substring matching semantics**: Resource lookup uses `EndsWith(name)`, meaning the full manifest resource name must end with the provided `name` string. For example, `GetString("init.sql")` would match `"MyApp.Migrations.init.sql"` but not `"init.sql.bak"`.
- **First-match behavior**: If multiple resources end with the same `name`, only the first one (as returned by `GetManifestResourceNames()`) is used. The order is not guaranteed by the .NET specification and may vary across builds or environments.
- **No validation of resource existence beyond null**: `GetStream` returns `null` if no matching resource is found; callers must handle this case explicitly.
- **Resource names are case-sensitive**: `EndsWith` performs case-sensitive comparison by default in .NET.
## 4. Dependencies
- **Depends on**:
- `System.IO` (for `StreamReader`)
- `System.Reflection.Assembly` (for `GetManifestResourceNames()` and `GetManifestResourceStream()`)
- **Depended on by**:
- Not inferable from this file alone. However, given the namespace (`DatabaseInitializationScripts`), it is highly likely used by database migration or setup logic elsewhere in the codebase (e.g., to load `.sql` files during schema initialization).
- The default `GetString(string)` overload implies a design assumption that the assembly containing `EmbeddedResource` is the one housing the embedded resources—likely the same assembly where this class resides.
## 5. Gotchas
- **Resource name ambiguity**: Because matching is based on `EndsWith`, two resources named `"script1.sql"` and `"subfolder/script1.sql"` would both match a lookup for `"script1.sql"`, and only the first (arbitrary) one would be returned. This can lead to unpredictable behavior if resource naming is not strictly controlled.
- **Resource stream not disposed by caller**: `GetStream` returns an open `StreamReader`; callers must ensure it is disposed (e.g., via `using`), otherwise resource leaks may occur. The `GetString(Assembly, string)` overload avoids this by closing the stream internally, but the stream-returning overload does not.
- **Encoding assumption**: `StreamReader.ReadToEnd()` uses the default encoding of the `StreamReader`, which is UTF-8 *without BOM* by default in modern .NET. If the embedded resource is encoded differently (e.g., UTF-8 with BOM, UTF-16), the string may be misinterpreted.
- **No support for nested paths**: The API does not distinguish between resource names with directory-like separators (e.g., `"Scripts/init.sql"` vs `"init.sql"`), increasing the risk of collisions.
- **`null` return without exception**: `GetStream` returns `null` on failure, which may lead to `NullReferenceException` if callers do not check for it before use.
- **`sr.Close()` is not `Dispose()`**: While `Close()` and `Dispose()` are functionally equivalent for `StreamReader`, using `Close()` instead of `using` or `Dispose()` is outdated style and may obscure resource management intent.

View File

@@ -0,0 +1,91 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseInitializationScripts/Properties/Settings.Designer.cs
- DataPRO/Modules/Database/DatabaseInitializationScripts/Properties/AssemblyInfo.cs
- DataPRO/Modules/Database/DatabaseInitializationScripts/Properties/Resources.Designer.cs
generated_at: "2026-04-16T04:36:10.385400+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "e3f89237ebe0a62c"
---
# Properties
## Documentation: `DatabaseInitializationScripts.Properties` Module
---
### 1. **Purpose**
This module contains auto-generated .NET assembly metadata and resource management infrastructure for the `DatabaseInitializationScripts` project. It does *not* contain business logic or database initialization scripts themselves; rather, it provides supporting infrastructure—such as strongly-typed settings, resources, and assembly-level attributes—required by the .NET framework for localization, configuration, and COM interop. Its role is purely infrastructural and exists to satisfy standard WPF/WinForms project conventions.
---
### 2. **Public Interface**
All types in this module are `internal` and auto-generated. No user-defined public APIs exist beyond the standard .NET patterns shown below.
#### `Settings` class
```csharp
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
```
- **`Settings.Default`** (static property)
Returns the singleton instance of the `Settings` class, synchronized for thread safety via `ApplicationSettingsBase.Synchronized`.
*Note:* As the class is auto-generated and empty (no user-defined settings), this property currently returns a settings object with no configurable properties.
#### `Resources` class
```csharp
internal class Resources
```
- **`Resources.ResourceManager`** (static property)
Returns a cached `System.Resources.ResourceManager` instance initialized for the `"DatabaseInitializationScripts.Properties.Resources"` base name. Used internally for localized resource lookups.
- **`Resources.Culture`** (static property)
Gets or sets the `CultureInfo` used for resource lookups. Allows overriding the current UI culture for localization.
#### `AssemblyInfo` (via assembly attributes)
No runtime types are defined here; attributes are applied at assembly level:
- `AssemblyTitle("DatabaseInitializationScripts")`
- `AssemblyVersion("1.0.0.0")`
- `AssemblyFileVersion("1.0.0.0")`
- `ComVisible(false)`
- `ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)`
---
### 3. **Invariants**
- The `Settings` class is implemented as a singleton with thread-safe access via `Synchronized`.
- Resource lookups use the fully qualified resource name `"DatabaseInitializationScripts.Properties.Resources"` (hardcoded in `Resources.ResourceManager`).
- The assembly is marked `ComVisible(false)`, meaning it is not intended for COM interop.
- The `ThemeInfo` attribute indicates the assembly does not ship theme-specific resources (`ResourceDictionaryLocation.None`) and expects generic resources in the main assembly (`SourceAssembly`).
- All generated files include explicit warnings that manual edits will be lost on regeneration.
---
### 4. **Dependencies**
#### Dependencies *of* this module:
- `System.Configuration` (for `ApplicationSettingsBase`)
- `System.Resources` / `System.Globalization` (for `ResourceManager`, `CultureInfo`)
- `System.Windows` (for `ThemeInfo` attribute usage, though no WPF UI is present in this module)
#### Dependencies *on* this module:
- The parent project `DatabaseInitializationScripts` (inferred from namespace and assembly name) likely consumes `Settings.Default` and `Resources` for configuration and localization, though no such usage is visible in the provided files.
#### External tooling:
- Generated by Visual Studios `SettingsDesigner` and `StronglyTypedResourceBuilder` (versions 17.12.0.0 and 17.0.0.0 respectively).
- Requires project-level `.settings` and `.resx` files (not provided) to generate content.
---
### 5. **Gotchas**
- **No user-defined settings or resources are present in the source.** The `Settings` class has no properties, and `Resources` has no strongly-typed properties for specific resources (e.g., `Resources.MyString`). This suggests either:
- The project has no localizable strings or configurable settings, *or*
- Such resources/settings exist in `.resx`/`.settings` files but have not been compiled into these designer files yet.
- **Auto-generated warning is critical:** Manual edits to `Settings.Designer.cs` or `Resources.Designer.cs` will be overwritten on build.
- **Thread-safety is superficial:** `Settings.Default` uses `Synchronized`, but since no settings are defined, thread-safety is irrelevant.
- **`ThemeInfo` is misleading:** The presence of `ThemeInfo` (a WPF attribute) in a module with no UI code may indicate legacy scaffolding or project template inheritance. No WPF resources are referenced here.
- **Version is fixed at `1.0.0.0`:** Both `AssemblyVersion` and `AssemblyFileVersion` are hardcoded and unchanging.
None identified beyond the above.

View File

@@ -0,0 +1,58 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseMigrationScripts/EmbeddedResource.cs
generated_at: "2026-04-16T04:34:42.810625+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ab2d5b23dd090ece"
---
# DatabaseMigrationScripts
### **Purpose**
This module provides utilities for reading embedded resources (e.g., SQL migration scripts) from a .NET assemblys manifest resources. It exists to simplify access to versioned, compiled-in migration files without requiring external file system dependencies, enabling reliable deployment of database schema changes across environments.
---
### **Public Interface**
- **`static StreamReader GetStream(Assembly assembly, string name)`**
Searches the manifest resources of the given `assembly` for a resource whose name *ends with* `name` (case-sensitive substring match), and returns a `StreamReader` for the first match. Returns `null` if no matching resource is found.
*Note: Caller is responsible for disposing the `StreamReader`.*
- **`static string GetString(Assembly assembly, string name)`**
Reads the full content of the resource matching `name` (via `GetStream`) from the specified `assembly` and returns it as a `string`. Closes the `StreamReader` internally. Returns `null` if no matching resource is found.
- **`static string GetString(string name)`**
Overload of `GetString` that uses the assembly containing the `EmbeddedResource` type itself (`typeof(EmbeddedResource).Assembly`) as the source. Behaves identically to `GetString(assembly, name)` otherwise.
---
### **Invariants**
- Resource matching is performed via `EndsWith(name)` on the full manifest resource name (e.g., `"MyApp.Migrations.V1_0_0.sql"` matches for `name = "V1_0_0.sql"`).
- Only the *first* matching resource (by enumeration order) is used—no error is raised if multiple resources match.
- `GetString(Assembly, string)` and `GetString(string)` return `null` if no matching resource exists (not an exception).
- The `StreamReader` returned by `GetStream` must be explicitly closed/disposed by the caller to avoid resource leaks.
- `GetString` methods assume the resource content is text-encoded (UTF-8 or system default encoding, per `StreamReader` default behavior).
---
### **Dependencies**
- **Depends on**:
- `System.IO` (`StreamReader`, `Stream`)
- `System.Reflection.Assembly` (for `GetManifestResourceNames`, `GetManifestResourceStream`)
- **Depended on by**:
- Presumably database migration orchestration logic (e.g., a `MigrationRunner` class) that loads `.sql` files from embedded resources.
- *Inferred*: Other types in the `DatabaseMigrationScripts` namespace (not visible here) likely consume `EmbeddedResource` to retrieve migration scripts.
---
### **Gotchas**
- **Substring matching is ambiguous**: A request for `"V1.sql"` could match `"V1.sql"`, `"Old/V1.sql"`, or `"Backup_V1.sql"`—only the first match in `GetManifestResourceNames()` order is used. This may cause unexpected behavior if resource naming is not strictly controlled.
- **No encoding specification**: `StreamReader` uses default encoding (typically UTF-8 without BOM on .NET Core/.NET 5+, but system default on .NET Framework), which may cause issues if migration files contain non-ASCII characters and were authored with a different encoding.
- **Resource enumeration order is undefined**: `GetManifestResourceNames()` does not guarantee consistent ordering across builds or platforms, so multiple matching resources may yield non-deterministic results.
- **No validation of resource existence before `ReadToEnd()`**: If `GetStream` returns `null`, `GetString` will throw a `NullReferenceException` when calling `sr.ReadToEnd()`. *This is a critical bug*: `GetString(Assembly, string)` lacks null-checking on `sr`.
- **`EmbeddedResource()` constructor is private but unused**: The class is never instantiated (all members are static), but the empty constructor serves no functional purpose.
- **No support for binary resources**: Designed exclusively for text-based resources; binary files would require a different approach.
*Note: The `NullReferenceException` risk in `GetString(Assembly, string)` when `GetStream` returns `null` is a likely source of runtime failures and should be addressed.*

View File

@@ -0,0 +1,40 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseMigrationScripts/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T04:35:19.675266+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "9006601d5721f158"
---
# Properties
## 1. Purpose
This module is an assembly containing metadata for the `DatabaseMigrationScripts` component of the DataPRO system. It does not contain executable logic or migration scripts themselves; rather, it defines assembly-level attributes (e.g., title, version, COM visibility) used by the .NET runtime and build/deployment tooling to identify and manage the assembly. Its role is to provide standard .NET assembly metadata, likely to support versioning, deployment, and integration with external tools (e.g., database migration runners or CI/CD pipelines) that rely on assembly identity.
## 2. Public Interface
**No public types, functions, classes, or methods are defined in this file.**
The file contains only assembly-level attributes via `System.Reflection` and `System.Runtime.InteropServices` attributes. It does not declare any classes, interfaces, structs, delegates, or methods.
## 3. Invariants
- The assembly identity is fixed at version `1.0.0.0` (both `AssemblyVersion` and `AssemblyFileVersion`), with no build/revision auto-increment.
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning it cannot be consumed by COM clients unless explicitly overridden.
- The GUID `efab771c-7aa7-4715-8ac3-9a1b6194fcc2` is permanently assigned as the typelib ID for COM interop purposes (though irrelevant given `ComVisible(false)`).
- All assembly attributes are static and immutable at runtime.
## 4. Dependencies
- **Depends on**:
- `System.Runtime.InteropServices` (for `ComVisible`, `Guid`)
- `System.Reflection` (for `AssemblyTitle`, `AssemblyVersion`, etc.)
- **Depends on nothing else** (no custom or third-party imports).
- **Used by**:
- The .NET runtime (for reflection and identity resolution).
- Build/deployment tooling (e.g., MSBuild, NuGet, or custom migration orchestrators) that reads assembly metadata.
- Potentially other modules in the `DataPRO` solution that reference this assembly (e.g., a migration runner expecting metadata from `DatabaseMigrationScripts`), though this is not evident from the file alone.
## 5. Gotchas
- **No executable code**: This file is purely metadata; developers should not expect to find migration logic here. Actual migration scripts are likely in separate `.sql` files or code-based migration classes in other modules (e.g., `DatabaseMigrationScripts` project but outside this file).
- **Version stagnation**: The fixed version `1.0.0.0` may indicate legacy or manual versioning—developers should verify how versioning is managed across the broader migration system (e.g., via database schema version tables or external tooling).
- **COM irrelevance**: Despite the GUID and `ComVisible(false)`, the assembly is unlikely to be used for COM interop; the GUID may be vestigial or reserved for future use.
- **No documentation**: `AssemblyDescription` and `AssemblyProduct` are empty or generic; developers should consult external documentation for the purpose of this assembly.
- **None identified from source alone.**

View File

@@ -0,0 +1,183 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseMigrator/MigrateDatabase.cs
- DataPRO/Modules/Database/DatabaseMigrator/MigrationForm.Designer.cs
- DataPRO/Modules/Database/DatabaseMigrator/MigrationForm.cs
generated_at: "2026-04-16T04:35:00.160493+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ea93d67370ed0c49"
---
# DatabaseMigrator Module Documentation
## 1. Purpose
This module provides a Windows Forms-based utility for upgrading a local DataPRO database to a specified target version. It serves as a standalone migration tool that interacts with SQL Server Express LocalDB instances, validates the current database version, creates backups before migration, executes version-specific upgrade scripts via the `DbOperations.Connection.UpgradeVersionsIfNeeded` method, and handles error reporting and user interaction. It is intended for use during application upgrades where the embedded database schema has changed, ensuring safe and traceable schema evolution.
## 2. Public Interface
The module exposes only one public class: `MigrationForm`. All other types (`MigrateDatabase`, `DbOperations`, `MigrationResult`, etc.) are referenced but not defined in the provided source.
### `MigrationForm(string targetDir)`
**Namespace:** `DatabaseMigrator`
**Inherits:** `System.Windows.Forms.Form`
**Behavior:** Constructor that initializes the form UI and stores the `_targetDir` path (used to locate database files and configuration). It does not perform any migration logic itself.
### `MigrationForm.buttonOK_Click(object sender, EventArgs e)`
**Access:** `private` (event handler)
**Behavior:** Handles the OK button click. Performs the following sequence:
1. Queries the current database version via `GetDatabaseVersion(true)`.
2. Compares current version to `_desiredDatabaseVersion`.
3. If versions match or current > desired, shows a warning message.
4. If migration is needed:
- Calls `CopyLocalDB()` to create a backup.
- Invokes `DbOperations.Connection.UpgradeVersionsIfNeeded(...)` with hardcoded arguments (`"DataPRO"`, `"previousdir"`, `"targetdir"`, `"DataPRO.exe"`, `"applicationSettings"`).
- Displays success or failure via `MessageBox`.
5. Closes the form.
### `MigrationForm.buttonCancel_Click(object sender, EventArgs e)`
**Access:** `private` (event handler)
**Behavior:** Closes the form without performing any migration.
### `MigrationForm.GetDatabaseVersion(bool usingLocalDatabase)`
**Access:** `private`
**Behavior:** Determines the current database version by:
- Attempting to run the stored procedure `sp_DbVersionGet` (via `DbOperations.GetSQLCommand(true)`).
- Parsing the returned version numbers and returning the maximum.
- Falls back to returning `0` on failure (commented-out SQLite fallback logic is present but inactive).
- If `localSQLLocalDbDataExists` is true, calls `InstallDatabase()` first to set up the LocalDB instance.
### `MigrationForm.CopyLocalDB()`
**Access:** `private`
**Behavior:** Creates a timestamped backup of the `DataPRO.mdf` and `DataPRO_log.ldf` files in the `_targetDir`. It:
- Calls `ProcessSqlLocalDbCommand(...StopDataProInstance...)` to stop the LocalDB instance.
- Copies the `.mdf` and `.ldf` files to new filenames with suffix `_YYYY_MM_DD HH_MM`.
- Returns `true` if `.mdf` copy succeeds (`.ldf` copy is not checked for success).
### `MigrationForm.InstallDatabase()`
**Access:** `private`
**Behavior:** Sets up a fresh LocalDB instance named `(localdb)\DataPROInstance` by:
- Setting `DbOperations._usingMSSQL = true`, `_usingCentralizedDB = false`, `_usingNTLMAuthentication = true`.
- Executing a sequence of `sqllocaldb.exe` commands via `ProcessSqlLocalDbCommand(...)`:
- Stop instance
- Delete instance
- Create instance
- Start instance
- Attaching two databases (`DataPRO` and `ISO`) using `AttachDatabase(...)`, which internally calls `sqlcmd.exe` via a batch file.
### `MigrationForm.SetMigrationStatus(string migrationStatus)`
**Access:** `private`
**Behavior:** Updates the `MigrationStatusLabel` UI element with the given status string and forces a UI refresh.
### `MigrationForm.SetStatus(string status, bool output = false)`
**Access:** `private`
**Behavior:** Updates the `statusTextLabel` UI element with the given status string and forces a UI refresh. The `output` parameter is unused.
### `MigrationForm.numericUpDownDesiredVersion_ValueChanged(object sender, EventArgs e)`
**Access:** `private` (event handler)
**Behavior:** Updates `_desiredDatabaseVersion` to the current value of `numericUpDownDesiredVersion`.
### `MigrationForm.LocalDataExists()`
**Access:** `private`
**Behavior:** Checks for existence of database files in `_targetDir\LocalDb\`:
- First checks for `DataPRO.mdf` → sets `localSQLLocalDbDataExists = true`.
- Else checks for `DataPRO.db` (SQLite) → sets `localSQLiteDataExists = true`.
- Returns `true` if either exists.
### `MigrationForm.MigrationForm_Load(object sender, EventArgs e)`
**Access:** `private` (event handler)
**Behavior:** On form load:
- Sets `numericUpDownDesiredVersion` range to `[61, DbOperations.CURRENT_DB_VERSION]`.
- Sets initial value to `DbOperations.CURRENT_DB_VERSION`.
- Calls `LocalDataExists()` to detect existing database type.
- Populates `TbDatabasePath.Text` with the full path to `DataPRO.mdf` if LocalDB data exists.
### `MigrationForm.ConvertMigrationResultToSetting(MigrationResult result)`
**Access:** `private`
**Behavior:** Maps `MigrationResult` enum values to user-facing strings using `Settings.Default.*` resources. Currently only handles `WarningAllowStreamingModesWasNotMigrated`.
### `MigrationForm.ConvertResultAndDisplay(MigrationResult result)`
**Access:** `private`
**Behavior:** Calls `ConvertMigrationResultToSetting(...)` and displays the result in a `MessageBox`.
### `MigrationForm.ProcessSqlLocalDbCommand(string command)` *(static)*
**Access:** `private static`
**Behavior:** Executes a command string via `sqllocaldb.exe`:
- Locates the highest installed LocalDB version via registry (`HKLM\...\LocalDB\InstalledVersions`).
- Constructs full path to `SqlLocalDB.exe`.
- Invokes `SqlCommandProcessor(...)` to run the command and capture output.
### `MigrationForm.AttachDatabase(string targetDir, string dbName, string sqlDbFileName, string sqlLogFileName)` *(static)*
**Access:** `private static`
**Behavior:** Attaches a database using a batch file (`Settings.Default.AttachDBsbat`) via `BatchCommandProcessor(...)`. Uses `sqlcmd.exe` from ODBC tools path.
### `MigrationForm.GetSqlServerLocalDBPath()` *(static)*
**Access:** `private static`
**Behavior:** Reads the Windows registry to find the highest installed SQL Server LocalDB version and returns the path to its tools directory.
### `MigrationForm.OutputHandler(...)` *(static)*
**Access:** `private static`
**Behavior:** Appends asynchronous output from a `Process` to a static `StringBuilder` (`sb`).
### `MigrationForm.SqlCommandProcessor(...)` *(static)*
**Access:** `public static`
**Behavior:** Executes a command-line process (e.g., `sqllocaldb.exe` or batch file), captures output via `OutputHandler`, and returns accumulated output as a string.
### `MigrationForm.BatchCommandProcessor(...)` *(static)*
**Access:** `public static`
**Behavior:** Executes a batch file with arguments (e.g., database attach script), captures output, and returns accumulated output.
> **Note:** The following types are used but *not defined* in the provided source:
> - `DbOperations` (class with static `Connection`, `_usingCentralizedDB`, `_usingMSSQL`, `CURRENT_DB_VERSION`, `GetSQLCommand(...)`, `DbVersions`, `DbVersionFields`)
> - `DbOperationsEnum.StoredProcedure`
> - `MigrationResult` (enum with at least `OK`, `ExceptionThrown`, `WarningAllowStreamingModesWasNotMigrated`)
> - `Settings.Default` (properties: `LocalDbDataPROInstance`, `StopDataProInstance`, `DeleteDataProInstance`, `CreateDataProInstance`, `StartDataProInstance`, `LocalDbFolder`, `Mdf`, `LogLdf`, `DataPRO`, `ISO`, `AttachDBsbat`, `RegistrySoftwareMicrosoftMicrosoftSQLServerLocalDBInstalledVersions`, `InstanceAPIPath`, `SqlUserInstanceDll`, `LocalDB`, `Tools`, `SqlLocalDBExe`, `SqlServerLocalDbNotInstalled`, `SameVersionDatabase`, `CurrentVersionGreater`, `DatabaseMigrationSucceeded`, `DatabaseMigrationFailed`, `ActionRequired`, `Warning`, `WarningAllowStreamingModesWasNotMigrated`, `Db`)
> - `DTS.Common.Storage`, `DTS.Common.Enums`, `DTS.Common.Utils.Database` namespaces
## 3. Invariants
- `_desiredDatabaseVersion` is always set to the current value of `numericUpDownDesiredVersion` via the `ValueChanged` event handler.
- `numericUpDownDesiredVersion` is constrained to `[61, DbOperations.CURRENT_DB_VERSION]` at form load.
- Database backup is *always* attempted before migration (even if `CopyDatabaseFile` does not validate `.ldf` copy success).
- `GetDatabaseVersion` returns `0` if no version can be determined (e.g., stored procedure fails or no versions found).
- LocalDB instance setup (`InstallDatabase`) is only triggered if `localSQLLocalDbDataExists` is true *and* `GetDatabaseVersion` is called.
- `DbOperations.Connection.Server` is hardcoded to `Settings.Default.LocalDbDataPROInstance` in `InstallDatabase`.
- `DbOperations.Connection.DBName` is hardcoded to `"DataPRO"` in `GetDatabaseVersion`.
- `DbOperations.Connection.UpgradeVersionsIfNeeded(...)` is called with fixed string arguments: `"DataPRO"`, `"previousdir"`, `"targetdir"`, `"DataPRO.exe"`, `"applicationSettings"` — no dynamic configuration is used.
## 4. Dependencies
### External Dependencies (Inferred from Imports/Usings):
- `System.Windows.Forms` (UI framework)
- `System.Data.SqlClient` (SQL Server client)
- `System.Diagnostics` (process execution)
- `System.IO` (file operations)
- `Microsoft.Win32` (registry access)
- `DTS.Common.Storage` (likely contains `DbOperations` and related types)
- `DTS.Common.Enums` (likely contains `DbOperationsEnum.StoredProcedure`, `MigrationResult`, `STARTUP_ERRORS`)
- `DTS.Common.Utils.Database` (contains `GetODBCToolsPath(...)`)
### Internal Dependencies (Inferred from Usage):
- `DatabaseMigrator.Properties.Settings.Default` — provides configuration strings (e.g., instance names, file extensions, registry keys, messages).
- `DbOperations.Connection` — central database access object (must expose `Server`, `DBName`, `DbVersion`, `UpgradeVersionsIfNeeded(...)`, `GetSQLCommand(...)`, and static fields like `_usingMSSQL`, `_usingCentralizedDB`, `_usingNTLMAuthentication`).
- `DbOperationsEnum.StoredProcedure` — must include `sp_DbVersionGet`.
- `DbOperations.DbVersions` — must contain `DbVersionFields.Version`.
- `DTS.Common.Utils.Database.GetODBCToolsPath(...)` — returns path to `sqlcmd.exe`.
### What Depends on This Module:
- The main entry point (`MigrateDatabase.Main`) is invoked as a standalone executable (likely triggered by the main DataPRO installer or updater).
- No other modules in this codebase reference `MigrationForm` — it is self-contained.
## 5. Gotchas
- **Hardcoded Migration Arguments**: `DbOperations.Connection.UpgradeVersionsIfNeeded(...)` is called with fixed string parameters (`"previousdir"`, `"targetdir"`, etc.) that do not appear to be derived from user input or configuration. This may cause migration to fail if those strings are not meaningful to the underlying upgrade logic.
- **Silent `.ldf` Copy Failure**: `CopyDatabaseFile` copies the `.mdf` file first and returns `true` if that succeeds, but does *not* check success of the `.ldf` copy — potentially leaving the backup incomplete.
- **`GetDatabaseVersion` Ignores `usingLocalDatabase` Parameter**: The parameter is always `true` in practice (hardcoded in `buttonOK_Click` and `MigrationForm_Load`), and the `else` branch for centralized DB is commented out.
- **SQLite Support Inactive**: `localSQLiteDataExists` is set but never used — the SQLite fallback path in `GetDatabaseVersion` is commented out.
- **Registry Assumptions**: `GetSqlServerLocalDBPath` assumes LocalDB is installed in a specific registry path and uses hardcoded suffixes (`Settings.Default.LocalDB`, `SqlUserInstanceDll`, `InstanceAPIPath`, `Tools`). Failure to match these will cause `ProcessSqlLocalDbCommand` to fail.
- **No Validation of Desired Version**: User can select any version in the `NumericUpDown`, but `DbOperations.Connection.UpgradeVersionsIfNeeded(...)` may not support downgrades or arbitrary version jumps — behavior is unknown without its source.
- **UI Blocking**: All migration logic runs on the UI thread (synchronous `Process.WaitForExit()` calls), which may cause the form to freeze during long operations.
- **Hardcoded Database Names**: `"DataPRO"` and `"ISO"` are hardcoded in multiple places (`InstallDatabase`, `CopyLocalDB`, `LocalDataExists`). No support for custom database names.
- **`SetStatus` Parameter Unused**: The `output` parameter in `SetStatus(string status, bool output = false)` is never used.
- **`_testIDTimestamp` Format Ambiguity**: Backup filename timestamp uses space (`" {0:00}_{1:00}"`) which may cause issues on some filesystems (e.g., network shares with strict naming rules).

View File

@@ -0,0 +1,79 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseMigrator/Properties/AssemblyInfo.cs
- DataPRO/Modules/Database/DatabaseMigrator/Properties/Settings.Designer.cs
generated_at: "2026-04-16T04:35:23.176246+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "044034bedb979c6c"
---
# Properties
## Documentation: DatabaseMigrator Module
### 1. Purpose
This module provides infrastructure and configuration for managing SQL Server LocalDB instance lifecycle and database schema migrations within the DataPRO system. It is responsible for defining application-scoped and user-scoped settings that control LocalDB operations (e.g., create/start/stop/delete instances), file naming conventions, registry paths, and user-facing messages (e.g., migration success/failure notifications). It does *not* contain migration logic itself (e.g., no migration scripts or versioning engine visible here), but supplies the configuration layer required by other components to orchestrate migrations and interact with LocalDB.
### 2. Public Interface
The only public surface exposed by this module is the auto-generated `Settings` class in the `DatabaseMigrator.Properties` namespace. All members are static properties accessed via `DatabaseMigrator.Properties.Settings.Default`.
| Property | Type | Scope | Default Value | Description |
|---------|------|-------|---------------|-------------|
| `LocalDbDataPROInstance` | `string` | Application-scoped | `"(localdb)\DataPROInstance"` | Name of the LocalDB instance used by DataPRO. |
| `StopDataProInstance` | `string` | Application-scoped | `"stop DataPROInstance"` | Command fragment used to stop the LocalDB instance (likely part of a larger command string). |
| `Warning` | `string` | Application-scoped | `"Warning"` | Literal string used in warning messages. |
| `DeleteDataProInstance` | `string` | Application-scoped | `"delete DataPROInstance"` | Command fragment used to delete the LocalDB instance. |
| `CreateDataProInstance` | `string` | Application-scoped | `"create DataPROInstance"` | Command fragment used to create the LocalDB instance. |
| `StartDataProInstance` | `string` | Application-scoped | `"start DataPROInstance"` | Command fragment used to start the LocalDB instance. |
| `LocalDbFolder` | `string` | Application-scoped | `"db"` | Default folder name for LocalDB database files (e.g., relative path). |
| `DataPRO` | `string` | Application-scoped | `"DataPRO"` | Product identifier string. |
| `ISO` | `string` | Application-scoped | `"ISO"` | Likely used for locale or collation settings. |
| `Mdf` | `string` | Application-scoped | `".mdf"` | File extension for primary database files. |
| `LogLdf` | `string` | Application-scoped | `"_log.ldf"` | Suffix for transaction log files. |
| `SqlServerLocalDbNotInstalled` | `string` | Application-scoped | `"SQL Server LocalDb is not installed."` | User-facing error message. |
| `SqlLocalDBExe` | `string` | Application-scoped | `"SqlLocalDB.exe"` | Executable name for the LocalDB CLI tool. |
| `ScriptsFolder` | `string` | Application-scoped | `"SQL Server Scripts"` | Folder name containing SQL scripts (e.g., migration scripts). |
| `AttachDBsbat` | `string` | Application-scoped | `"AttachDBs.bat"` | Batch file name used to attach databases. |
| `RegistrySoftwareMicrosoftMicrosoftSQLServerLocalDBInstalledVersions` | `string` | Application-scoped | `"SOFTWARE\\Microsoft\\Microsoft SQL Server Local DB\\Installed Versions"` | Registry path to check LocalDB installation status. |
| `InstanceAPIPath` | `string` | Application-scoped | `"InstanceAPIPath"` | Key name for registry value storing LocalDB instance path. |
| `SqlUserInstanceDll` | `string` | Application-scoped | `"SqlUserInstance.dll"` | Name of a LocalDB-related DLL (likely for user-instance support). |
| `LocalDB` | `string` | Application-scoped | `"LocalDB"` | Generic identifier for LocalDB. |
| `Tools` | `string` | Application-scoped | `"Tools"` | Folder name for tools (e.g., `SqlLocalDB.exe` location). |
| `Db` | `string` | Application-scoped | `".db"` | Alternative database file extension (possibly legacy). |
| `SameVersionDatabase` | `string` | Application-scoped | `"Database is already version {0} - no migration needed."` | Message template for no-op migration case. |
| `ActionRequired` | `string` | Application-scoped | `"Action required"` | Prefix for user prompts requiring manual intervention. |
| `CurrentVersionGreater` | `string` | Application-scoped | `"The current database version ({0}) is greater than what is requested. Downward migration is not available."` | Error message for downgrade attempt. |
| `DatabaseMigrationFailed` | `string` | Application-scoped | `"Database migration has failed.{0}Previous version of DataPRO must be used. Please contact DTS Support."` | Critical failure message. |
| `DatabaseMigrationSucceeded` | `string` | User-scoped | `"Database has been migrated from version {0} to {1}."` | Success message template (user-scoped, modifiable at runtime). |
| `WarningAllowStreamingModesWasNotMigrated` | `string` | User-scoped | `"Warning: The AllowStreaming config setting was not migrated and has been set to False.{0}{0}An \"Allow streaming modes\" checkbox is now in the \"Test setup settings\" step of the \"System Settings\" tab."` | Warning about legacy config migration gap (user-scoped). |
| `CreatingBackupDb` | `string` | User-scoped | `"Creating a backup database..."` | Status message during backup creation (user-scoped). |
### 3. Invariants
- All application-scoped settings are immutable at runtime (read-only; set only at compile-time via `DefaultSettingValueAttribute`).
- User-scoped settings (`DatabaseMigrationSucceeded`, `WarningAllowStreamingModesWasNotMigrated`, `CreatingBackupDb`) may be modified programmatically and persisted per-user.
- String values are used verbatim in command-line invocations (e.g., `SqlLocalDB.exe` commands), implying strict formatting expectations (e.g., instance names must match exactly).
- File extensions (`Mdf`, `LogLdf`, `Db`) are assumed to be consistent with SQL Server LocalDB conventions (`.mdf`, `_log.ldf`, `.db`).
- Registry path `RegistrySoftwareMicrosoftMicrosoftSQLServerLocalDBInstalledVersions` must exist and contain version keys for LocalDB detection to function.
### 4. Dependencies
**Depends on:**
- `System.Configuration` (for `ApplicationSettingsBase`, `ApplicationScopedSettingAttribute`, `UserScopedSettingAttribute`).
- `System.Runtime.CompilerServices` (for `CompilerGeneratedAttribute`).
- `System.CodeDom.Compiler` (for `GeneratedCodeAttribute`).
- `System.Diagnostics` (for `DebuggerNonUserCodeAttribute`).
- Implicitly depends on `SqlLocalDB.exe` being installed and accessible (via `Tools`/`SqlLocalDBExe` settings).
- Implicitly depends on SQL Server LocalDB runtime components (e.g., `SqlUserInstance.dll`).
**Depended on by:**
- Other modules in `DataPRO/Modules/Database/DatabaseMigrator` (e.g., migration orchestration logic, instance management classes) — not visible in this source but implied by module structure.
- Likely consumed by UI components (e.g., to display messages like `DatabaseMigrationFailed`, `WarningAllowStreamingModesWasNotMigrated`).
### 5. Gotchas
- **Hardcoded instance name**: The LocalDB instance name `DataPROInstance` is hardcoded in multiple settings (`LocalDbDataPROInstance`, `StopDataProInstance`, etc.). Renaming the instance requires coordinated changes across all related settings.
- **User-scoped settings are mutable**: Settings like `DatabaseMigrationSucceeded` can be altered at runtime and persisted, which may cause unexpected behavior if modified by users or other components.
- **Legacy config gap**: `WarningAllowStreamingModesWasNotMigrated` explicitly indicates a known migration gap for a deprecated setting (`AllowStreaming`), suggesting incomplete backward compatibility.
- **No versioning metadata**: This file contains no versioning information for migrations (e.g., no schema version constants or migration script ordering). Version tracking must be handled elsewhere.
- **Batch file assumption**: `AttachDBsbat` implies an external batch script (`AttachDBs.bat`) exists and is correctly structured; its absence or misconfiguration would cause failures.
- **Registry path format**: The registry path uses double backslashes (`\\`) in the source (as required for C# string literals), but this is correct for registry key paths. Ensure no accidental escaping errors in consuming code.
- **No public API beyond `Settings`**: This module exposes *only* configuration; actual migration logic resides in other files (not provided here). Do not assume migration behavior from this file alone.

View File

@@ -0,0 +1,119 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/DatabaseServicesModule.cs
generated_at: "2026-04-16T04:34:59.163908+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "674f1fac51c6e6cb"
---
# DatabaseServices
## Documentation: `DatabaseServicesModule`
---
### **1. Purpose**
The `DatabaseServicesModule` is a Prism module responsible for registering core database-related UI components (views and view models) into the Unity dependency injection container during application startup. It enables modular composition of the database services feature set within the larger application architecture, specifically integrating with Prisms module loading mechanism and Unity for dependency resolution. It also contributes metadata (name, image, group, region) to the main UI for discoverability and placement of database-related components.
---
### **2. Public Interface**
#### **`DatabaseServicesModule` class**
- **`public DatabaseServicesModule(IUnityContainer unityContainer)`**
Constructor. Accepts a Unity container via dependency injection and stores it for later use in type registration.
- **`public void Initialize()`**
Registers the following view/view-model pairs as singleton mappings in the Unity container:
- `IDatabaseCopyView``DatabaseCopyView`
- `IDatabaseCopyViewModel``DatabaseCopyViewModel`
- `IDatabaseStatusBarView``DatabaseStatusBarView`
- `IDatabaseStatusBarViewModel``DatabaseStatusBarViewModel`
- `IDatabaseSwitchView``DatabaseSwitchView`
- `IDatabaseSwitchViewModel``DatabaseSwitchViewModel`
*Note:* This method is called both directly by Prisms `IModule.Initialize()` and indirectly via `RegisterTypes()`.
- **`public void OnInitialized(IContainerProvider containerProvider)`**
Currently empty; no logic implemented.
- **`public void RegisterTypes(IContainerRegistry containerRegistry)`**
Delegates to `Initialize()`. This is required by Prisms `IModule` interface (via `IContainerRegistry`), but the implementation ignores `containerRegistry` and uses the injected `_unityContainer` instead.
#### **`DatabaseServicesModuleNameAttribute` class**
- **`public override string AssemblyName { get; }`**
Returns `"DatabaseServices"` (value of `AssemblyNames.DatabaseServices.ToString()`).
- **`public override string GetAssemblyName()`**
Returns the same value as `AssemblyName`.
- **`public override Type GetAttributeType()`**
Returns `typeof(TextAttribute)`.
#### **`DatabaseServicesModuleImageAttribute` class**
- **`public override BitmapImage AssemblyImage { get; }`**
Loads and returns a `BitmapImage` by calling `AssemblyInfo.GetImage("DatabaseServices")`.
- **`public override string AssemblyName { get; }`**
Returns `"DatabaseServices"`.
- **`public override string AssemblyGroup { get; }`**
Returns `"Prepare"` (value of `eAssemblyGroups.Prepare.ToString()`).
- **`public override eAssemblyRegion AssemblyRegion { get; }`**
Returns `eAssemblyRegion.DatabaseServicesRegion`.
- **`public override string GetAssemblyName()`**
Returns `"DatabaseServices"`.
- **`public override string GetAssemblyGroup()`**
Returns `"Prepare"`.
- **`public override eAssemblyRegion GetAssemblyRegion()`**
Returns `eAssemblyRegion.DatabaseServicesRegion`.
- **`public override BitmapImage GetAssemblyImage()`**
Returns the value of `AssemblyImage`.
- **`public override Type GetAttributeType()`**
Returns `typeof(ImageAttribute)`.
---
### **3. Invariants**
- **Singleton Registration**: All view/view-model pairs registered in `Initialize()` are registered as singletons (default Unity behavior for `RegisterType<T, TImpl>()` without specifying `LifetimeManager`).
- **Assembly Name Consistency**: Both attributes (`DatabaseServicesModuleNameAttribute`, `DatabaseServicesModuleImageAttribute`) consistently use `"DatabaseServices"` as the assembly name (via `AssemblyNames.DatabaseServices`).
- **Group & Region Constraints**:
- `AssemblyGroup` is always `"Prepare"` (from `eAssemblyGroups.Prepare`).
- `AssemblyRegion` is always `eAssemblyRegion.DatabaseServicesRegion`.
- **Image Loading**: `AssemblyImage` is loaded exactly once per instance (cached in `_img`), using `AssemblyInfo.GetImage("DatabaseServices")`. No fallback or error handling is visible in the source.
---
### **4. Dependencies**
#### **Dependencies *of* this module:**
- **Prism.Modularity (`IModule`)**: Required for module discovery and initialization.
- **Unity (`IUnityContainer`, `IContainerProvider`, `IContainerRegistry`)**: Used for DI container registration.
- **DTS.Common (`AssemblyNames`, `eAssemblyGroups`, `eAssemblyRegion`, `AssemblyInfo`)**: Provides metadata constants and image-loading utilities.
- **System.ComponentModel.Composition (`Export`)**: Enables Prism to discover this module via MEF.
- **System.Windows.Media.Imaging (`BitmapImage`)**: Required for the image attribute.
#### **Dependencies *on* this module:**
- **Prism-based shell/application**: The main application must load this module (via Prism module catalog) to register the database services views/view-models.
- **UI regions**: The `DatabaseServicesRegion` (referenced in `AssemblyRegion`) must be defined elsewhere (e.g., in XAML or shell layout) for views to be injected into.
---
### **5. Gotchas**
- **Redundant `Initialize()` call**: `RegisterTypes()` calls `Initialize()`, but `Initialize()` is also called directly by Prism. This is safe (idempotent for registration), but indicates potential design redundancy or legacy code.
- **Ignored `containerRegistry`**: `RegisterTypes()` receives `IContainerRegistry containerRegistry` but ignores it in favor of the injected `_unityContainer`. This couples the module to Unity and may break if another DI container is used.
- **No error handling for image loading**: If `AssemblyInfo.GetImage("DatabaseServices")` fails (e.g., missing image resource), `_img` may be `null` with no visible fallback or logging.
- **Hardcoded string `"DatabaseServices"`**: Used in both attributes and `AssemblyInfo.GetImage()`. A typo or rename in `AssemblyNames.DatabaseServices` would cause runtime issues.
- **No `OnInitialized()` logic**: The `OnInitialized()` method is empty. If initialization order or cross-module coordination is needed, this is currently unsupported.
- **Attribute usage**: Both attributes are applied at the *assembly* level (via `[assembly: ...]`), meaning they are not tied to the `DatabaseServicesModule` class itself but to the entire assembly. This may cause confusion if multiple modules exist in the same assembly.
None identified beyond the above.

View File

@@ -0,0 +1,85 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/Converters/DbTypeToVisibilityConverter.cs
generated_at: "2026-04-16T04:35:48.144608+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "b05fe9322ad19457"
---
# Converters
### **DbTypeToVisibilityConverter.cs Documentation**
---
#### **1. Purpose**
This module provides a WPF `IMultiValueConverter` implementation (`DbTypeToVisibilityConverter`) used to dynamically control the visibility of UI elements (e.g., menu items, buttons, or status bar controls) in the `DatabaseStatusBarView`, based on the current database configuration and connection state. It translates the combination of a `DbType` value and the current view context into a `Visibility` enum (`Visible` or `Collapsed`), enabling UI elements to be conditionally shown only when relevant to the active database mode (e.g., remote-only, local-only, or hybrid with/without remote connection).
---
#### **2. Public Interface**
- **`DbTypeToVisibilityConverter`**
- *Implements*: `System.Windows.Data.IMultiValueConverter`
- *Namespace*: `DatabaseServices.Converters`
- *Inherits*: `object`
- **`object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)`**
- **Signature**: `public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)`
- **Behavior**: Converts a two-element input array (`values`) into a `Visibility` value:
- `values[0]`: An `int` representing a `DbType` enum value (cast to `DbType`).
- `values[1]`: A `DatabaseStatusBarView` instance (used to access its `DataContext`, expected to be a `DatabaseStatusBarViewModel`).
- Returns `Visibility.Visible` if the `dbType` matches the visibility rules for the current `vm.DatabaseType` and `vm.RemoteConnected` state; otherwise returns `Visibility.Collapsed`.
- If `view.DataContext` is `null`, returns `Visibility.Collapsed`.
- Throws no exceptions explicitly, but may throw `InvalidCastException` if inputs are not of expected types.
- **`object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)`**
- **Signature**: `public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)`
- **Behavior**: Always throws `NotImplementedException`. This converter is one-way only.
---
#### **3. Invariants**
- `values` array **must** contain exactly two elements:
- Element 0: An `int` that can be safely cast to `DbType`.
- Element 1: A `DatabaseStatusBarView` instance (non-null).
- `view.DataContext` **must** be non-null and assignable to `DatabaseStatusBarViewModel`; otherwise, the converter returns `Visibility.Collapsed`.
- Visibility logic is strictly governed by the `DatabaseStatusBarViewModel.DatabaseType` and `DatabaseStatusBarViewModel.RemoteConnected` properties:
- For `RemoteOnly`: Only `DbType.RemoteOnly` is visible.
- For `LocalOnly`: Only `DbType.LocalOnly` is visible.
- For `RemoteLocalHybrid`:
- If `RemoteConnected == true`: Only `DbType.RemoteOnly` is visible.
- If `RemoteConnected == false`: Only `DbType.RemoteLocalHybrid` is visible.
- Any other `DatabaseType` value results in `Visibility.Collapsed`.
- The converter is **not** intended for two-way binding (`ConvertBack` is unimplemented).
---
#### **4. Dependencies**
- **Imports/References**:
- `System`, `System.Globalization`, `System.Windows`, `System.Windows.Data` (WPF core)
- `DTS.Common.Enums.Database` (external library/namespace) — provides `DbType` and likely `DatabaseStatusBarView`/`DatabaseStatusBarViewModel`.
- **Assumed Dependencies (from usage context)**:
- `DatabaseStatusBarView`: A WPF `UserControl` or `Window` used in the status bar.
- `DatabaseStatusBarViewModel`: View model with properties:
- `DatabaseType` (`DbType`)
- `RemoteConnected` (`bool`)
- `DbType` enum (from `DTS.Common.Enums.Database`) — expected to include at least: `RemoteOnly`, `LocalOnly`, `RemoteLocalHybrid`.
- **Depended upon by**:
- XAML bindings in `DatabaseStatusBarView` (or related views) where `MultiBinding` is used with this converter to toggle visibility based on database type and connection state.
---
#### **5. Gotchas**
- **Type safety**: Assumes `values[0]` is an `int` that maps to a valid `DbType` enum value. Passing a non-integer or out-of-range value may cause `InvalidCastException` at runtime.
- **Null safety**: Relies on `view.DataContext` being non-null; otherwise, silently returns `Collapsed`. No logging or error handling is present.
- **Hybrid mode logic is conditional**: In `RemoteLocalHybrid` mode, visibility depends on `RemoteConnected`, but the converter does **not** handle cases where `RemoteConnected` is `false` and `dbType == DbType.RemoteOnly` — such cases correctly collapse, but this may be counterintuitive if the UI expects hybrid elements to always show.
- **No support for `parameter`**: The `parameter` argument (often used to customize converter behavior in XAML) is ignored.
- **One-way only**: `ConvertBack` throws `NotImplementedException`, so this converter cannot be used in two-way bindings.
- **No validation of `DbType` values**: Unknown `DbType` values (e.g., future enum additions) fall through to `default: return Visibility.Collapsed`, which may hide UI elements unexpectedly.
None identified beyond these.

View File

@@ -0,0 +1,62 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/Properties/Settings.Designer.cs
- DataPRO/Modules/Database/DatabaseServices/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T04:35:58.384112+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "a47b7825dcdbbbb0"
---
# Properties
## Documentation Page: `DatabaseServices.Properties.Settings`
---
### 1. **Purpose**
This module defines the auto-generated settings class `Settings` for the `DatabaseServices` assembly. It provides a strongly-typed, thread-safe accessor (`Default`) to application-level configuration settings stored in the standard .NET configuration system (e.g., `app.config` or `web.config`). Its role is to abstract access to persisted settings values, enabling type-safe retrieval without manual parsing or casting. It does *not* define any settings itself—only the infrastructure to access them—meaning actual settings keys and values must be defined elsewhere (e.g., via Visual Studios Settings designer or `app.config`).
---
### 2. **Public Interface**
The module exposes a single internal, auto-generated class:
- **`class Settings : ApplicationSettingsBase`**
- **`public static Settings Default { get; }`**
Returns the singleton instance of `Settings`, synchronized for thread safety via `ApplicationSettingsBase.Synchronized`. This is the *only* public member exposed.
> ⚠️ **Note**: The class is `internal`, so `Default` is only accessible within the `DatabaseServices` assembly. External consumers cannot directly reference this class.
---
### 3. **Invariants**
- The `Default` property always returns a non-null reference (initialized lazily and synchronized).
- The class is `sealed` and `partial`, indicating it is not designed for inheritance or manual extension.
- Thread-safety is guaranteed *only for the `Default` accessor* (via `Synchronized`), but not necessarily for individual property accesses on the returned instance (e.g., `Settings.Default.MySetting` is not inherently thread-safe beyond the initial retrieval of `Default`).
- Settings values themselves are not validated or constrained by this class—validation (if any) occurs at the configuration layer or in consuming code.
---
### 4. **Dependencies**
- **Depends on**:
- `System.Configuration` (specifically `ApplicationSettingsBase`, `CompilerGeneratedAttribute`, `GeneratedCodeAttribute`).
- `System.Runtime.CompilerServices` (for `CompilerGeneratedAttribute`).
- **Depended upon by**:
- Other classes in the `DatabaseServices` assembly (e.g., data access layers) that require configuration values (e.g., connection strings, timeouts).
- *Not* exposed to external assemblies due to `internal` visibility.
- **Assembly metadata** (from `AssemblyInfo.cs`):
- Assembly name: `DatabaseServices`
- GUID: `f1a366bc-6128-4c10-be7f-f62628895d8f`
- Version: `1.0.0.0`
- `ComVisible(false)` → not exposed to COM.
---
### 5. **Gotchas**
- **No settings defined here**: This file *only* scaffolds the settings infrastructure. Actual settings (e.g., `ConnectionString`, `CommandTimeout`) must be defined in `Settings.settings` (designer) or `app.config`. If these are missing, accessing `Settings.Default` will succeed, but property access (e.g., `Settings.Default.MyProp`) will throw a `ConfigurationErrorsException` at runtime.
- **Auto-generated**: Manual edits will be overwritten on rebuild (per the `auto-generated` header).
- **Internal visibility**: External consumers cannot use `Settings.Default` directly. They must rely on `DatabaseServices` to expose settings via its public API (e.g., a wrapper method).
- **Thread-safety nuance**: While `Default` is thread-safe, *reading/writing settings values* from multiple threads may require additional synchronization if mutable settings are used (though `ApplicationSettingsBase` typically treats settings as read-only after initialization).
- **No documentation comments**: The class lacks XML documentation, making it harder to infer intended usage without external context.
None identified beyond these.

View File

@@ -0,0 +1,52 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/Resources/TranslateExtension.cs
- DataPRO/Modules/Database/DatabaseServices/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T04:35:33.501804+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "79b93425a9c97e71"
---
# Resources
## Documentation: `TranslateExtension` Markup Extension
### 1. Purpose
The `TranslateExtension` class is a WPF `MarkupExtension` that enables declarative localization of UI text directly in XAML. It resolves string resources by key at runtime using the `StringResources` strongly-typed resource class, returning localized strings or a standardized fallback for missing keys. This module exists to support multi-language UIs in the DatabaseServices module by abstracting resource lookup into a XAML-friendly syntax (e.g., `{local:Translate KeyName}`), decoupling UI text from code and enabling runtime culture switching.
### 2. Public Interface
- **`TranslateExtension(string key)`**
Constructor. Accepts a resource key (e.g., `"ClearingLocalDb"`) to look up. Throws no exceptions on invalid input—invalid keys are handled at lookup time.
- **`override object ProvideValue(IServiceProvider serviceProvider)`**
WPF framework method invoked during XAML parsing. Returns the localized string corresponding to `_key`, or a fallback value if the key is missing/empty.
- If `_key` is `null` or empty: returns `"#stringnotfound#"`.
- If `StringResources.ResourceManager.GetString(_key)` returns `null`: returns `"#stringnotfound# " + _key`.
- Otherwise: returns the localized string.
### 3. Invariants
- `_key` is immutable after construction (stored in a `readonly` field).
- The returned value is always a `string` (per `[MarkupExtensionReturnType(typeof(string))]`).
- No exceptions are thrown during `ProvideValue`—all error cases return a fallback string.
- Resource lookup uses the current UI culture (via `StringResources.Culture`), which may be set externally (e.g., by WPFs `FrameworkElement.Language` or manual assignment).
- The `StringResources` class is auto-generated and must be kept in sync with `.resx` files; changes to `.resx` require regeneration.
### 4. Dependencies
- **Depends on**:
- `System.Windows.Markup` (for `MarkupExtension` and `MarkupExtensionReturnType`).
- `DatabaseServices.Resources.StringResources` (strongly-typed resource class).
- `System.Resources.ResourceManager` (via `StringResources.ResourceManager`).
- **Used by**:
- XAML files in the `DatabaseServices` module (e.g., `Window.xaml`, `UserControl.xaml`) to bind localized text to UI elements.
- No direct programmatic callers in the provided source—usage is exclusively via XAML markup.
### 5. Gotchas
- **Hardcoded fallback prefix**: The `"#stringnotfound#"` string is hardcoded; changing it requires updating both `TranslateExtension` and any tests/scripts expecting this pattern.
- **No caching of lookups**: `ResourceManager.GetString(_key)` is called on every `ProvideValue` invocation. While `ResourceManager` caches internally, repeated lookups for the same key in high-frequency UI scenarios (e.g., data-bound lists) may incur overhead.
- **Silent failure on missing keys**: Missing keys produce visible text like `"#stringnotfound# ClearingLocalDb"` in the UI, which may confuse end users. No logging or telemetry is performed.
- **No null-safety for `serviceProvider`**: The `serviceProvider` parameter is unused, but if future changes require it (e.g., for service resolution), this could break.
- **Auto-generated resource class**: `StringResources.Designer.cs` is auto-generated—manual edits are unsafe and will be overwritten. Resource keys must match exactly (case-sensitive) with entries in the `.resx` file.
- **No support for pluralization/formatting**: The extension only supports simple key→string lookups; composite strings (e.g., `"Connected to: {0}"`) require manual formatting in code-behind or XAML.
None identified beyond these.

View File

@@ -0,0 +1,52 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/View/DatabaseStatusBarView.xaml.cs
- DataPRO/Modules/Database/DatabaseServices/View/DatabaseCopyView.xaml.cs
- DataPRO/Modules/Database/DatabaseServices/View/DatabaseSwitchView.xaml.cs
generated_at: "2026-04-16T04:36:08.419533+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "0a8da82e58412ddf"
---
# View
## Documentation: Database UI Views Module
### 1. Purpose
This module contains WPF view classes that implement the user interface layer for database-related operations—specifically, displaying status information, copying databases, and switching between local and remote database contexts. It serves as the presentation layer for database service functionality, adhering to the MVVM pattern by delegating business logic to corresponding view models (`IDatabaseCopyViewModel`, `IDatabaseSwitchViewModel`, `IDatabaseStatusBarView`). The views are thin wrappers that wire UI events (e.g., button clicks) to view model methods, and they rely on WPFs data binding and command infrastructure.
### 2. Public Interface
| Type | Signature | Behavior |
|------|-----------|----------|
| `DatabaseStatusBarView` | `public partial class DatabaseStatusBarView : IDatabaseStatusBarView` | WPF `UserControl` (inferred from `InitializeComponent()`) implementing `IDatabaseStatusBarView`. Provides UI for displaying database status (e.g., connection state, server info). No additional logic beyond initialization. |
| `DatabaseCopyView` | `public partial class DatabaseCopyView : IDatabaseCopyView` | WPF `UserControl` implementing `IDatabaseCopyView`. Contains a copy operation button. On click, casts `DataContext` to `IDatabaseCopyViewModel` and invokes `CopyDatabase()`. |
| `DatabaseSwitchView` | `public partial class DatabaseSwitchView : IDatabaseSwitchView` | WPF `UserControl` implementing `IDatabaseSwitchView`. Contains two buttons: `SwitchToLocal` and `SwitchToRemote`. On click, casts `DataContext` to `IDatabaseSwitchViewModel` and invokes `SwitchLocal()` or `SwitchRemote()` respectively. |
> **Note**: All classes are `partial`, indicating they are tied to corresponding `.xaml` files (e.g., `DatabaseStatusBarView.xaml`). Constructor calls `InitializeComponent()` to load XAML and wire UI elements.
### 3. Invariants
- **View-ViewModel Contract**: Each view expects its `DataContext` to be an instance of the corresponding view model interface (`IDatabaseStatusBarView` has no explicit contract beyond inheritance; `DatabaseCopyView` and `DatabaseSwitchView` require `IDatabaseCopyViewModel` and `IDatabaseSwitchViewModel` respectively).
- **UI Thread Execution**: Event handlers (`Copy_Click`, `SwitchToLocal_Click`, `SwitchToRemote_Click`) assume execution on the UI thread (standard for WPF event handlers), and view model methods (`CopyDatabase`, `SwitchLocal`, `SwitchRemote`) are invoked synchronously on this thread.
- **Null Safety**: No null checks are present in handlers; assumes `sender` is always a `Control` and `DataContext` is always the expected view model type. Failure to satisfy this will cause runtime exceptions (e.g., `InvalidCastException`, `NullReferenceException`).
### 4. Dependencies
- **External Interfaces**:
- `DTS.Common.Interface.Database.IDatabaseStatusBarView`
- `DTS.Common.Interface.Database.IDatabaseCopyView`
- `DTS.Common.Interface.Database.IDatabaseSwitchView`
- `DTS.Common.Interface.Database.IDatabaseCopyViewModel` (used in `DatabaseCopyView`)
- `DTS.Common.Interface.Database.IDatabaseSwitchViewModel` (used in `DatabaseSwitchView`)
- **WPF Framework**: `System.Windows`, `System.Windows.Controls`, `System.Windows.RoutedEventArgs`.
- **Dependents**: Likely consumed by a module or shell that registers these views with a DI container or view locator (e.g., Caliburn.Micro, Prism), though this is not explicit in the source.
- **No internal dependencies**: No references to other modules beyond the `DTS.Common.Interface.Database` interface layer.
### 5. Gotchas
- **No Error Handling**: Event handlers perform direct casts without validation. If `DataContext` is misconfigured (e.g., wrong view model type or `null`), a runtime exception will occur.
- **Tight Coupling to View Models**: Views assume specific method names (`CopyDatabase`, `SwitchLocal`, `SwitchRemote`) exist on the view model interface. Changes to these interfaces require synchronized updates.
- **No Command Binding**: Uses event handlers instead of `ICommand` bindings (e.g., `Button.Command`), which is less idiomatic in MVVM and reduces testability (e.g., cannot easily unit test button logic without UI interaction).
- **Namespace Quirk**: `// ReSharper disable CheckNamespace` suggests the namespace is intentionally `DatabaseServices` (not nested under `DataPRO.Modules.Database...`), possibly for legacy or build-system reasons.
- **Missing Implementation Details**: Source provides no insight into what `IDatabaseStatusBarView` actually exposes (e.g., properties, events), as the interface is only inherited—not implemented or used directly in logic.
None identified beyond the above.

View File

@@ -0,0 +1,206 @@
---
source_files:
- DataPRO/Modules/Database/DatabaseServices/ViewModel/DatabaseStatusBarViewModel.cs
- DataPRO/Modules/Database/DatabaseServices/ViewModel/DatabaseSwitchViewModel.cs
- DataPRO/Modules/Database/DatabaseServices/ViewModel/DatabaseCopyViewModel.cs
generated_at: "2026-04-16T04:35:56.029845+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "f187d4b018ffae25"
---
# Database Services ViewModels Documentation
## 1. Purpose
This module provides UI-facing view models (`DatabaseStatusBarViewModel`, `DatabaseSwitchViewModel`, and `DatabaseCopyViewModel`) that manage database connection state, user interaction for database switching/copying, and status reporting in the DataPRO application. These view models coordinate database operations (local vs. remote), handle UI state (busy indicators, progress bars, notifications), and integrate with Prisms event aggregation and Unity DI container for decoupled communication with other system components. They serve as the bridge between low-level database operations (e.g., `DbOperations`, `DatabaseServices`) and the WPF UI layer.
---
## 2. Public Interface
### `DatabaseStatusBarViewModel`
- **`string ActiveDbName { get; }`**
Returns a string representing the active database: `"Local"` for `DbType.LocalOnly`, `ServerName` for `DbType.RemoteOnly`, or `ServerName`/`"Local"` conditionally for `DbType.RemoteLocalHybrid`.
- **`Brush BackgroundBrush { get; }`**
Returns `Brushes.Red` when `DatabaseType == DbType.RemoteLocalHybrid` and `RemoteConnected == false`; otherwise `Brushes.Transparent`.
- **`bool RemoteConnected { get; }`**
Returns the value of `DbOperations._usingCentralizedDB`.
- **`string ServerName { get; private set; }`**
Holds the remote server name; updated via `InitializeValues` or `OnDbEvent`.
- **`void InitializeValues(DbType dbType, string serverName, bool remoteConnected)`**
Sets `DatabaseType`, `ServerName`, and triggers property change notifications for `ActiveDbName` and `BackgroundBrush`.
- **`void OnDbEvent(DbStatusArg args)`**
Internal event handler for `DbStatusEvent`; updates `ServerName` and notifies changes to `ActiveDbName`/`BackgroundBrush` when `args.Status == LegacyStatus`.
- **`bool IsBusy { get; set; }`**
Binds to UI busy indicator; updated via `OnBusyIndicatorNotification`.
- **`bool IsMenuIncluded`, `bool IsNavigationIncluded`**
UI state flags for menu/navigation visibility; support INotifyPropertyChanged.
- **`InteractionRequest<Notification> NotificationRequest { get; }`**
Prism interaction request used to show notification popups.
- **`InteractionRequest<Confirmation> ConfirmationRequest { get; }`**
Prism interaction request used to show confirmation dialogs.
- **`IDatabaseStatusBarView View { get; set; }`**
Reference to the associated view; `View.DataContext` is set to `this` in constructor.
- **Constructors**
- `DatabaseStatusBarViewModel(IDatabaseStatusBarView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)`
Registers event subscriptions for `RaiseNotification`, `BusyIndicatorChangeNotification`, and `DbStatusEvent`.
- `DatabaseStatusBarViewModel()`
Parameterless constructor (used for design-time or manual instantiation).
- **Lifecycle methods (no-op)**
`Unset()`, `Cleanup()`, `CleanupAsync()`, `Initialize()`, `Initialize(object)`, `Initialize(object, object)`, `InitializeAsync()`, `InitializeAsync(object)`, `Activated()` — all currently empty.
### `DatabaseSwitchViewModel`
- **`bool RemoteIsActive { get; }`**
Returns `DbOperations._usingCentralizedDB`.
- **`void SwitchRemote()`**
Attempts to switch to remote database:
1. Publishes `AppStatusArg.Busy`.
2. Calls `DatabaseServices.SetupForRemoteDb(...)` with stored credentials.
3. Validates connection via `SimpleDbTest()`.
4. On failure: publishes `DbStatusEvent` with `FailedToConnectToRemote`, calls `SwitchLocal()`, logs exception.
5. On success: publishes `DbStatusEvent.LegacyStatus`, `AppStatusArg.Available`, and `LogoutUserEvent` (reason: `DatabaseSwitch`).
- **`void SwitchLocal()`**
Switches to local database:
1. Checks local DB files exist via `CheckLocalDatabaseFilesExist(...)`.
2. Publishes `AppStatusArg.Busy`.
3. Calls `DatabaseServices.SetupLocal(...)`.
4. Publishes `DbStatusEvent.LegacyStatus`, `AppStatusArg.Available`, and `LogoutUserEvent`.
- **`void InitializeDbSettings(string defaultDbName, string dbHost, bool ntlmAuthentication, string dbUser, string dbPassword)`**
Stores connection settings for later use in `SwitchRemote()`.
- **Properties**: `DefaultDbName`, `DbHost`, `NTLMAuthentication`, `DbUser`, `DbPassword` (all `private set`).
- **`bool IsBusy`, `IsMenuIncluded`, `IsNavigationIncluded`**
Same semantics as `DatabaseStatusBarViewModel`.
- **Constructors & Lifecycle methods**
Same as `DatabaseStatusBarViewModel`; constructor subscribes to `RaiseNotification` and `BusyIndicatorChangeNotification`.
### `DatabaseCopyViewModel`
- **`bool CopyEnabled { get; }`**
Returns `true` only if `DatabaseType == DbType.RemoteLocalHybrid` and `DbOperations._usingCentralizedDB == true`.
- **`void CopyDatabase()`**
Triggers `CopyFunc()` on a background task (`Task.Run`). Publishes `AppStatusArg.Busy` before and `AppStatusArg.Available` after.
- **`void InitializeState(DbType dbType, string dbName)`**
Sets `DatabaseType` and `DbName`, publishes initial `ProgressBarEvent` for both progress bars (collapsed), and notifies `CopyEnabled`.
- **`string DbName { get; private set; }`**
Name of the database being copied.
- **`bool IsCopyVisible { get; set; }`**
Controls visibility of the copy UI section.
- **`IStatusAndProgressBarView OverallProgressBarView`, `IStatusAndProgressBarView CurrentTaskProgressBarView`**
References to progress bar views resolved during `InitializeAsync()`.
- **`Task InitializeAsync()`**
Resolves and configures two `IStatusAndProgressBarView` instances:
- One for `OverallTaskBar` (named `"OverallStatus"`).
- One for `CurrentTaskBar` (named `"CurrentTaskStatus"`).
Each is bound to a shared `IStatusAndProgressBarViewModel` instance.
- **`void OnRaiseNotification(NotificationContentEventArgs)`**
Wraps event args into `Notification` and raises `NotificationRequest`.
- **`void OnBusyIndicatorNotification(bool)`**
Sets `IsBusy`.
- **`bool IsBusy`, `IsMenuIncluded`, `IsNavigationIncluded`, `IsDirty`**
Same semantics as above.
- **Internal helper methods (private)**
- `CopyFunc()`: Main copy logic:
1. Backs up local DB.
2. Disables constraints.
3. Copies all tables in `_allDBTables` via `CopyRemoteTable(...)`.
4. Fixes `Channels.DASId = 0 → NULL`.
5. Re-enables constraints.
6. Restores local DB on failure.
7. Publishes progress via `ProgressBarEvent`.
- `CopyRemoteTable(string tableName, bool bIndentityTable)`: Fetches all rows from remote DB, stores in memory.
- `InsertIntoLocalTable(...)`: Inserts rows in batches (max 20 rows/batch to avoid SQL parameter limit), handles `IDENTITY_INSERT` for tables in `_tablesWithIdentities`.
- `SetStatus(string bar, double percentage, string text)`: Publishes `ProgressBarEvent`.
- **Constants & Data**
- `MAX_BATCH_SIZE = 20`
- `_allDBTables`: List of 72 table names (includes duplicates like `"tblDataPRODbVersion"` and `"DataPRODbVersion"`).
- `_tablesWithIdentities`: HashSet of 58 table names requiring `IDENTITY_INSERT ON/OFF`.
---
## 3. Invariants
- **`RemoteConnected` is derived solely from `DbOperations._usingCentralizedDB`** — no local state overrides it.
- **`ActiveDbName` and `BackgroundBrush` depend on `DatabaseType` and `RemoteConnected`** — their values are recalculated only when `DatabaseType` or `ServerName` changes (via `InitializeValues` or `OnDbEvent`).
- **Progress bars are always reset to collapsed/zero on completion/failure** — `CopyFunc()` publishes `ProgressBarEvent` with `Visibility.Collapsed` in `finally`.
- **`CopyDatabase()` runs asynchronously** — `Task.Run` is used explicitly; no `async/await` is used internally.
- **`DatabaseCopyViewModel` requires `InitializeAsync()` to be called before `CopyDatabase()`** — otherwise `OverallProgressBarView`/`CurrentTaskProgressBarView` remain `null`.
- **`DatabaseSwitchViewModel.SwitchRemote()` and `SwitchLocal()` always trigger `LogoutUserEvent`** — user session is invalidated after any database switch.
- **`DatabaseStatusBarViewModel.OnDbEvent(...)` only handles `LegacyStatus`** — other `DbStatusArg.EventTypes` are ignored.
---
## 4. Dependencies
### Internal Dependencies (from source):
- **`DTS.Common.*`**:
- `DTS.Common.Enums.Database.DbType`
- `DTS.Common.Events.*` (`RaiseNotification`, `BusyIndicatorChangeNotification`, `DbStatusEvent`, `AppStatusEvent`, `PageErrorEvent`, `LogoutUserEvent`)
- `DTS.Common.Storage.DatabaseServices` (`SetupForRemoteDb`, `SimpleDbTest`, `SetupLocal`, `BackupLocalDatabase`, `RestoreLocalDatabase`, `LOCAL_DB_FOLDER`)
- `DTS.Common.Storage.DatabaseServices` (via `DbOperations`, `LocalOnlyOperations`)
- `DTS.Common.Interface.Database.*` (e.g., `IDatabaseStatusBarView`, `IDatabaseCopyViewModel`)
- `DTS.Common.Interface.*` (e.g., `IStatusAndProgressBarView`)
- `DTS.Common.Utilities.Logging.APILogger`
- `DTS.Common.Interactivity.*` (`InteractionRequest`, `Notification`, `Confirmation`)
- **Prism Framework**:
- `Prism.Events.IEventAggregator`, `Prism.Regions.IRegionManager`
- `Prism.Commands`, `Prism.Interactivity.InteractionRequest`
- **Unity DI Container** (`IUnityContainer`)
- **WPF** (`System.Windows.Media.Brush`, `System.Windows.Visibility`)
### External Dependencies:
- **SQL Server** (via `System.Data.SqlClient`, `DbOperations.Connection`, `LocalOnlyOperations`)
- **`Resources.StringResources`** (localized strings: `"Local"`, `"CopyingTable"`, `"ClearingLocalDb"`, `"EnablingConstraints"`, `"SwitchFileNotFound"`)
### Inferred Consumers:
- Views (`IDatabaseStatusBarView`, `IDatabaseSwitchView`, `IDatabaseCopyView`) bind to these view models.
- Event publishers (`RaiseNotification`, `DbStatusEvent`, `AppStatusEvent`, etc.) drive view model state changes.
- `DatabaseServices` layer (`DbOperations`, `LocalOnlyOperations`) is called directly by these view models.
---
## 5. Gotchas
- **`DatabaseStatusBarViewModel` has two constructors** — the parameterless one does not subscribe to events, so `OnDbEvent`, `OnBusyIndicatorNotification`, and `OnRaiseNotification` will not be triggered if used. This is likely a design flaw or legacy artifact.
- **`DatabaseStatusBarViewModel.OnDbEvent` only handles `LegacyStatus`** — other status types (e.g., `FailedToConnectToRemote`) are silently ignored.
- **`DatabaseCopyViewModel.CopyFunc()` loads entire remote tables into memory** — `CopyRemoteTable` fetches all rows via `QueryDataSet` before copying. This may cause OOM for large tables.
- **`DatabaseCopyViewModel` uses hardcoded table list (`_allDBTables`)** — not dynamically fetched from DB schema. Duplicates exist (`"DataPRODbVersion"` and `"tblDataPRODbVersion"`), and missing tables will cause copy failures.
- **Batch size (`MAX_BATCH_SIZE = 20`) is arbitrary** — comment notes it was tuned empirically to avoid SQL parameter limits (2100), but no validation ensures column count × rows ≤ 2100.
- **`DatabaseSwitchViewModel.SwitchRemote()` calls `SwitchLocal()` on failure** — this may cause cascading failures or confusing UI state if local DB is also unavailable.
- **`DatabaseStatusBarViewModel.ServerName` is updated only in `OnDbEvent` for `LegacyStatus`** — if `InitializeValues` is not called first, `ServerName` remains `null`/empty, leading to incorrect `ActiveDbName`.
- **`DatabaseCopyViewModel.InitializeAsync()` resolves views/models twice** — two separate `Resolve` calls for `IStatusAndProgressBarView`/`IStatusAndProgressBarViewModel` per progress bar, potentially creating duplicate view model instances.
- **No cancellation support** — `CopyDatabase()` and `SwitchRemote()`/`SwitchLocal()` lack cancellation tokens or progress callbacks for user-initiated aborts.
- **`DbOperations._usingCentralizedDB` is a static field** — shared across the app domain; changes in one view model affect others unexpectedly.
- **`DatabaseStatusBarViewModel.ActiveDbName` returns `""` for unhandled `DbType`** — no fallback or exception on unknown types.
- **`DatabaseCopyViewModel` uses `sp_msforeachtable`** — undocumented, unsupported SQL Server stored procedure; may break on future SQL Server versions or non-standard DB configurations.