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

13 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/Database/DatabaseMigrator/MigrateDatabase.cs
DataPRO/Modules/Database/DatabaseMigrator/MigrationForm.Designer.cs
DataPRO/Modules/Database/DatabaseMigrator/MigrationForm.cs
2026-04-16T04:35:00.160493+00:00 Qwen/Qwen3-Coder-Next-FP8 1 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).