Files
DP44/docs/ai/DataPRO/Modules/Database/DatabaseServices/ViewModel.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/DatabaseServices/ViewModel/DatabaseStatusBarViewModel.cs
DataPRO/Modules/Database/DatabaseServices/ViewModel/DatabaseSwitchViewModel.cs
DataPRO/Modules/Database/DatabaseServices/ViewModel/DatabaseCopyViewModel.cs
2026-04-17T15:41:29.202299+00:00 zai-org/GLM-5-FP8 1 f011aeacca70c45c

Database ViewModels Documentation

1. Purpose

This module provides three MVVM ViewModels for database management within the DatabaseServices namespace:

  • DatabaseStatusBarViewModel: Manages the database status bar UI, displaying the active database connection (Local vs Remote) and providing visual feedback (red background when disconnected from remote in hybrid mode).
  • DatabaseSwitchViewModel: Handles switching between local and remote database connections, including connection testing, authentication setup, and forcing user re-login after database switches.
  • DatabaseCopyViewModel: Implements database copy functionality to synchronize a remote database to a local database, including table-by-table copying with identity column handling and constraint management.

All three ViewModels follow the Prism MVVM pattern, use MEF for dependency injection with shared creation policy, and integrate with the application's event aggregation system.


2. Public Interface

DatabaseStatusBarViewModel

Implements: IDatabaseStatusBarViewModel

Member Signature Description
View public IDatabaseStatusBarView View { get; set; } The associated view instance; DataContext is set to this in constructor.
DatabaseType public DbType DatabaseType { get; private set; } The configured database type (LocalOnly, RemoteOnly, RemoteLocalHybrid).
ServerName public string ServerName { get; private set; } Name of the database server; "Local" when not remote connected.
RemoteConnected public bool RemoteConnected => DbOperations._usingCentralizedDB; Indicates if currently connected to centralized/remote database.
ActiveDbName public string ActiveDbName { get; } Computed display name based on DatabaseType and connection state. Returns localized "Local" string or server name.
BackgroundBrush public Brush BackgroundBrush { get; } Returns Brushes.Red when hybrid mode is disconnected from remote; otherwise Brushes.Transparent.
InitializeValues public void InitializeValues(DbType dbType, string serverName, bool remoteConnected) Initializes the ViewModel's state and triggers PropertyChanged for ActiveDbName and BackgroundBrush.
OnPropertyChanged public void OnPropertyChanged(string propertyName) Raises the PropertyChanged event.
NotificationRequest public InteractionRequest<Notification> NotificationRequest { get; } Prism interaction request for notifications.
ConfirmationRequest public InteractionRequest<Confirmation> ConfirmationRequest { get; } Prism interaction request for confirmations.
IsBusy public bool IsBusy { get; set; } Bound to busy indicator state.
IsMenuIncluded public bool IsMenuIncluded { get; set; } Controls menu visibility.
IsNavigationIncluded public bool IsNavigationIncluded { get; set; } Controls navigation visibility.
IsDirty public bool IsDirty { get; private set; } Tracks unsaved changes state.
Cleanup / CleanupAsync public void Cleanup() / public Task CleanupAsync() No-op cleanup methods.
Initialize overloads void Initialize(), void Initialize(object), void Initialize(object, object) No-op initialization methods.
InitializeAsync overloads Task InitializeAsync(), Task InitializeAsync(object) Return Task.CompletedTask.
Activated public void Activated() No-op activation method.
Unset public void Unset() No-op unset method.

Constructor:

public DatabaseStatusBarViewModel(
    IDatabaseStatusBarView view, 
    IRegionManager regionManager,
    IEventAggregator eventAggregator, 
    IUnityContainer unityContainer)

DatabaseSwitchViewModel

Implements: IDatabaseSwitchViewModel

Member Signature Description
View public IDatabaseSwitchView View { get; set; } The associated view instance.
DefaultDbName public string DefaultDbName { get; private set; } Default database name for connections.
DbHost public string DbHost { get; private set; } Remote database host address.
NTLMAuthentication public bool NTLMAuthentication { get; private set; } Whether NTLM authentication is enabled.
DbUser public string DbUser { get; private set; } Database username for SQL authentication.
DbPassword public string DbPassword { get; private set; } Database password for SQL authentication.
RemoteIsActive public bool RemoteIsActive => DbOperations._usingCentralizedDB; Indicates if remote database is currently active.
SwitchRemote public void SwitchRemote() Switches to remote database connection. Tests connection, falls back to local on failure, publishes DbStatusEvent and LogoutUserEvent.
SwitchLocal public void SwitchLocal() Switches to local database. Validates local files exist, publishes status events and forces logout.
InitializeDbSettings public void InitializeDbSettings(string defaultDbName, string dbHost, bool ntlmAuthentication, string dbUser, string dbPassword) Stores database connection settings for use by switch methods.
IsBusy, IsMenuIncluded, IsNavigationIncluded, IsDirty Same as DatabaseStatusBarViewModel Standard ViewModel properties.
NotificationRequest, ConfirmationRequest Same as DatabaseStatusBarViewModel Prism interaction requests.
Lifecycle methods Same pattern as DatabaseStatusBarViewModel Cleanup, CleanupAsync, Initialize*, Activated, Unset are no-ops or return completed tasks.

Constructor:

public DatabaseSwitchViewModel(
    IDatabaseSwitchView view, 
    IRegionManager regionManager,
    IEventAggregator eventAggregator, 
    IUnityContainer unityContainer)

DatabaseCopyViewModel

Implements: IDatabaseCopyViewModel

Member Signature Description
View public IDatabaseCopyView View { get; set; } The associated view instance.
DatabaseType public DTS.Common.Enums.Database.DbType DatabaseType { get; private set; } Current database type configuration.
DbName public string DbName { get; private set; } Name of the database being copied.
CopyEnabled public bool CopyEnabled => DatabaseType == DbType.RemoteLocalHybrid && DbOperations._usingCentralizedDB; Copy is only enabled in hybrid mode when connected to remote.
IsCopyVisible public bool IsCopyVisible { get; set; } Controls visibility of copy UI; defaults to true.
OverallProgressBarView public IStatusAndProgressBarView OverallProgressBarView { get; private set; } Progress bar view for overall copy progress.
CurrentTaskProgressBarView public IStatusAndProgressBarView CurrentTaskProgressBarView { get; private set; } Progress bar view for current table copy progress.
CopyDatabase public void CopyDatabase() Initiates async database copy via Task.Run(() => CopyFunc()). Publishes AppStatusEvent.Busy.
InitializeState public void InitializeState(DTS.Common.Enums.Database.DbType dbType, string dbName) Sets up initial state, resets progress bars, triggers OnPropertyChanged("CopyEnabled").
InitializeAsync public Task InitializeAsync() Resolves and initializes progress bar views via Unity container.
_allDBTables private static readonly List<string> Hardcoded list of 73 database table names to copy.
_tablesWithIdentities private static readonly HashSet<string> Hardcoded set of 48 table names that have identity columns.
MAX_BATCH_SIZE private const int MAX_BATCH_SIZE = 20; Maximum rows per batch insert to avoid SQL Server's 2100 parameter limit.
CurrentTaskBar private const string CurrentTaskBar = "CurrentTaskStatus"; Identifier for current task progress bar.
OverallTaskBar private const string OverallTaskBar = "OverallStatus"; Identifier for overall progress bar.
Lifecycle methods Same pattern as other ViewModels Standard no-op implementations except InitializeAsync.

Constructor:

public DatabaseCopyViewModel(
    IDatabaseCopyView view, 
    IRegionManager regionManager,
    IEventAggregator eventAggregator, 
    IUnityContainer unityContainer)

3. Invariants

DatabaseStatusBarViewModel

  • ActiveDbName returns empty string for unhandled DbType values (not LocalOnly, RemoteOnly, or RemoteLocalHybrid).
  • BackgroundBrush only returns Brushes.Red for DbType.RemoteLocalHybrid when RemoteConnected is false; all other cases return Brushes.Transparent.
  • RemoteConnected is directly coupled to DbOperations._usingCentralizedDB static field.

DatabaseSwitchViewModel

  • SwitchRemote always publishes LogoutUserEvent with reason DatabaseSwitch on success.
  • SwitchRemote calls SwitchLocal() as fallback if connection test fails.
  • SwitchLocal checks for local database file existence before proceeding; returns early with error if files not found.
  • SwitchLocal always publishes LogoutUserEvent with reason DatabaseSwitch on success.

DatabaseCopyViewModel

  • CopyEnabled is only true when DatabaseType == DbType.RemoteLocalHybrid AND DbOperations._usingCentralizedDB is true.
  • Copy operation disables constraints before copying and re-enables them after.
  • If copy fails, attempts to restore from backup via DTS.Common.Storage.DatabaseServices.RestoreLocalDatabase(DbName).
  • Batch inserts are limited to MAX_BATCH_SIZE (20 rows) or when parameter count would exceed 2100.
  • Identity insert is enabled/disabled per batch for tables in _tablesWithIdentities.
  • DASId columns with value 0 are explicitly set to NULL in the Channels table after copy.

4. Dependencies

External Dependencies (from imports)

  • Prism Framework: Prism.Events, Prism.Regions, Prism.Commands - Event aggregation, region management, commanding
  • Unity Container: Unity - Dependency injection container
  • MEF: System.ComponentModel.Composition - Part creation policy
  • WPF: System.Windows.Media, System.ComponentModel - UI types, INotifyPropertyChanged
  • DTS.Common.Enums.Database: DbType enum
  • DTS.Common.Events: RaiseNotification, BusyIndicatorChangeNotification, AppStatusEvent, AppStatusArg, ProgressBarEvent, ProgressBarEventArg, PageErrorEvent, PageErrorArg
  • DTS.Common.Events.Database: DbStatusEvent, DbStatusArg, LogoutUserEvent, LogoutUserArg
  • DTS.Common.Interactivity: InteractionRequest<T>, Notification, Confirmation, NotificationContentEventArgs
  • DTS.Common.Interface.Database: IDatabaseStatusBarView, IDatabaseSwitchView, IDatabaseCopyView, IDatabaseStatusBarViewModel, IDatabaseSwitchViewModel, IDatabaseCopyViewModel
  • DTS.Common.Interface: IStatusAndProgressBarView, IStatusAndProgressBarViewModel
  • DTS.Common.Storage: DbOperations, LocalOnlyOperations, DatabaseServices (static class)
  • DTS.Common.Utilities.Logging: APILogger
  • DTS.Common.Utils.Database: CheckLocalDatabaseFilesExist
  • Resources.StringResources: Localized strings

Static Couplings

  • DbOperations._usingCentralizedDB - Static field accessed directly by all three ViewModels
  • DbOperations.Connection.Server - Server name accessed directly
  • DbOperations.GetSQLCommand() - SQL command creation for remote DB
  • LocalOnlyOperations.GetSQLCommand() - SQL command creation for local DB
  • LocalOnlyOperations.BeginStatement, LocalOnlyOperations.CommitStatement - Transaction statements
  • LocalOnlyOperations.CreateParam() - Parameter creation helper

5. Gotchas

XML Documentation Mismatch

  • DatabaseStatusBarViewModel and DatabaseSwitchViewModel XML summary comments state "this class handles DatabaseCopy functionality" which is incorrect (copy-paste error from DatabaseCopyViewModel).

Parameterless Constructors

  • All three ViewModels have public parameterless constructors in addition to the DI constructor. The parameterless constructors perform no initialization, which could lead to null reference exceptions if used incorrectly.

Static Table Lists

  • DatabaseCopyViewModel._allDBTables and _tablesWithIdentities are hardcoded lists. Any database schema changes require code updates. Comment in source states: "I'd like to do this through SQL, but ran into problems".

Thread Safety Concerns

  • DatabaseCopyViewModel.CopyDatabase() uses Task.Run() to execute CopyFunc() on a background thread, but SetStatus() publishes UI events directly. The BusyIndicatorChangeNotification subscription in DatabaseStatusBarViewModel uses ThreadOption.PublisherThread with `keepSubscriberReferenceAlive: true