115 lines
7.0 KiB
Markdown
115 lines
7.0 KiB
Markdown
|
|
---
|
||
|
|
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-17T15:55:24.798276+00:00"
|
||
|
|
model: "zai-org/GLM-5-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "0f84be859c5d0bf5"
|
||
|
|
---
|
||
|
|
|
||
|
|
# DatabaseMigrator Module Documentation
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
The `DatabaseMigrator` module is a Windows Forms application that provides a GUI utility for migrating DataPRO databases between versions. It handles SQL Server Express LocalDB instance management, database backup creation, and version upgrades by orchestrating calls to `DbOperations.Connection.UpgradeVersionsIfNeeded`. The module exists to allow developers or administrators to upgrade database schemas from older versions (minimum version 61) to the current database version.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### MigrateDatabase (static class)
|
||
|
|
|
||
|
|
**`static void Main(string[] args)`**
|
||
|
|
- Entry point for the application. Marked with `[STAThread]`.
|
||
|
|
- Currently ignores command-line arguments (parsing logic is commented out).
|
||
|
|
- Sets `targetDir` to `Environment.CurrentDirectory`.
|
||
|
|
- Initializes visual styles and launches `MigrationForm`.
|
||
|
|
|
||
|
|
### MigrationForm (class, inherits from `Form`)
|
||
|
|
|
||
|
|
**`public MigrationForm(string targetDir)`**
|
||
|
|
- Constructor accepting the target directory path where database files reside.
|
||
|
|
- Initializes the form components and stores `targetDir` in a private readonly field.
|
||
|
|
|
||
|
|
**Event Handlers (private, wired to UI controls):**
|
||
|
|
|
||
|
|
- **`void buttonOK_Click(object sender, EventArgs e)`** - Initiates the migration process. Queries current database version, validates against desired version, creates a backup via `CopyLocalDB()`, and calls `DbOperations.Connection.UpgradeVersionsIfNeeded()`. Displays appropriate warnings if versions match or current version exceeds desired.
|
||
|
|
|
||
|
|
- **`void buttonCancel_Click(object sender, EventArgs e)`** - Closes the form without performing migration.
|
||
|
|
|
||
|
|
- **`void MigrationForm_Load(object sender, EventArgs e)`** - Initializes `numericUpDownDesiredVersion` with minimum 61, maximum `DbOperations.CURRENT_DB_VERSION`, and default value of current version. Checks for existing local database and populates `TbDatabasePath`.
|
||
|
|
|
||
|
|
- **`void numericUpDownDesiredVersion_ValueChanged(object sender, EventArgs e)`** - Updates `_desiredDatabaseVersion` field from the numeric control.
|
||
|
|
|
||
|
|
**Helper Methods (private):**
|
||
|
|
|
||
|
|
- **`int GetDatabaseVersion(bool usingLocalDatabase)`** - Retrieves current database version by calling stored procedure `sp_DbVersionGet`. Returns 0 on failure.
|
||
|
|
|
||
|
|
- **`bool CopyLocalDB()`** - Creates timestamped backup copies of `.mdf` and `_log.ldf` files.
|
||
|
|
|
||
|
|
- **`string InstallDatabase()`** - Configures SQL LocalDB instance by stopping, deleting, creating, and starting `DataPROInstance`, then attaches both DataPRO and ISO databases.
|
||
|
|
|
||
|
|
- **`static string ProcessSqlLocalDbCommand(string command)`** - Executes SQL LocalDB utility commands.
|
||
|
|
|
||
|
|
- **`static string AttachDatabase(string targetDir, string dbName, string sqlDbFileName, string sqlLogFileName)`** - Attaches a database using `sqlcmd.exe` via batch file.
|
||
|
|
|
||
|
|
- **`static string GetSqlServerLocalDBPath()`** - Queries Windows Registry to find the highest installed SQL Server LocalDB version path.
|
||
|
|
|
||
|
|
- **`static string SqlCommandProcessor(string sqlLocalDbExeFileName, string command)`** - Executes a SQL command-line utility and captures output.
|
||
|
|
|
||
|
|
- **`static string BatchCommandProcessor(string batchFileName, string dbName, string sqlDbFileName, string sqlLogFileName, string fullSqlcmdPath)`** - Executes a batch file for database operations.
|
||
|
|
|
||
|
|
- **`bool LocalDataExists()`** - Checks for existence of `DataPRO.mdf` (SQL LocalDB) or `datapro.db` (SQLite) files.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
- **Version bounds**: `numericUpDownDesiredVersion.Minimum` is always 61; `numericUpDownDesiredVersion.Maximum` is always `DbOperations.CURRENT_DB_VERSION`.
|
||
|
|
- **Database name**: The database name is hardcoded as `"DataPRO"` throughout the module.
|
||
|
|
- **Form behavior**: The form is always `TopMost = true` and centered on screen (`StartPosition = CenterScreen`).
|
||
|
|
- **Backup naming**: Backup files are named with timestamp format `YYYY_MM_DD HH_MM` appended before the file extension.
|
||
|
|
- **SQL LocalDB instance name**: The instance name is `DataPROInstance` (from `Settings.Default.LocalDbDataPROInstance`).
|
||
|
|
- **Migration direction**: Migration only proceeds if `currentDatabaseVersion < _desiredDatabaseVersion`. Equal or greater versions result in user warnings and no migration.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### This module depends on:
|
||
|
|
- `System.Windows.Forms` - Windows Forms UI framework
|
||
|
|
- `System.Data.SqlClient` - SQL Server database connectivity
|
||
|
|
- `Microsoft.Win32` - Registry access for SQL LocalDB path detection
|
||
|
|
- `DTS.Common.Storage` - Contains `DbOperations` and `DbOperationsEnum`
|
||
|
|
- `DTS.Common.Enums` - Contains `MigrationResult` enum
|
||
|
|
- `DTS.Common.Utils.Database` - Contains `GetODBCToolsPath()` method
|
||
|
|
- `DatabaseMigrator.Properties.Settings` - Application settings for paths, instance names, and message strings
|
||
|
|
|
||
|
|
### External dependencies (inferred from usage):
|
||
|
|
- `DbOperations.Connection` - Must provide `UpgradeVersionsIfNeeded()`, `Server`, `DBName`, `DbVersion` properties
|
||
|
|
- `DbOperations.CURRENT_DB_VERSION` - Constant defining maximum supported version
|
||
|
|
- `DbOperations.GetSQLCommand()` - Factory method for SQL commands
|
||
|
|
- `MigrationResult` enum with values: `OK`, `ExceptionThrown`, `WarningAllowStreamingModesWasNotMigrated`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
1. **Dead code**: Command-line argument parsing in `Main()` is fully commented out. The application always uses `Environment.CurrentDirectory` regardless of arguments passed.
|
||
|
|
|
||
|
|
2. **Hardcoded values with "fix this" comments**: Multiple locations contain hardcoded values that were intended to be configurable:
|
||
|
|
- `GetDatabaseVersion(true)` - parameter is ignored; `true` is hardcoded
|
||
|
|
- Database name `"DataPRO"` is hardcoded instead of using `tbDBName.Text` (commented out)
|
||
|
|
- `UpgradeVersionsIfNeeded` receives hardcoded strings `"previousdir"`, `"targetdir"`, `"applicationSettings"` with a "fix this" comment
|
||
|
|
|
||
|
|
3. **SQLite support is incomplete**: The code contains commented-out SQLite handling in `GetDatabaseVersion()` and `LocalDataExists()`. The `localSQLiteDataExists` flag is set but never acted upon.
|
||
|
|
|
||
|
|
4. **Silent failures**: `GetDatabaseVersion()` catches all exceptions and returns 0 without logging or rethrowing. This could mask connectivity or schema issues.
|
||
|
|
|
||
|
|
5. **Static mutable state**: The `StringBuilder sb` field is static and reused across `SqlCommandProcessor` and `BatchCommandProcessor`. While it's cleared before each use, this could cause issues if methods are called concurrently.
|
||
|
|
|
||
|
|
6. **Commented-out exit codes**: Multiple `Environment.Exit()` calls are commented out after error conditions, meaning errors display a message box but allow the application to continue.
|
||
|
|
|
||
|
|
7. **Process output handling asymmetry**: `SqlCommandProcessor` and `BatchCommandProcessor` redirect both stdout and stderr, but only stderr is read asynchronously via `OutputHandler`, while stdout is read synchronously with `ReadToEnd()`.
|