using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using DTS.Common.Events;
using DTS.Common.Events.Database;
using Prism.Events;
using Prism.Regions;
using Unity;
using DTS.Common.Interactivity;
using Prism.Commands;
using DTS.Common.Interface.Database;
using DTS.Common.Storage;
using DTS.Common.Utilities.Logging;
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace DatabaseServices
{
///
/// this class handles DatabaseCopy functionality
///
[PartCreationPolicy(CreationPolicy.Shared)]
public class DatabaseCopyViewModel : IDatabaseCopyViewModel
{
///
/// The DatabaseCopy view
///
public IDatabaseCopyView View { get; set; }
private IEventAggregator _eventAggregator { get; }
private IUnityContainer UnityContainer { get; }
public InteractionRequest NotificationRequest { get; }
public InteractionRequest ConfirmationRequest { get; }
///
///
/// Occurs when a property value changes.
///
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region constructors and initializers
///
/// Creates a new instance of the DatabaseCopyViewModel
///
///
/// The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.
/// The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.
/// The unityContainer.
public DatabaseCopyViewModel(IDatabaseCopyView view, IRegionManager regionManager,
IEventAggregator eventAggregator, IUnityContainer unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest();
ConfirmationRequest = new InteractionRequest();
_eventAggregator = eventAggregator;
UnityContainer = unityContainer;
_eventAggregator.GetEvent().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent().Subscribe(OnBusyIndicatorNotification);
}
#endregion
#region Methods
public void Unset()
{
}
public void CopyDatabase()
{
_eventAggregator.GetEvent().Publish(AppStatusArg.Busy);
_ = Task.Run(() => { CopyFunc(); });
}
public void InitializeState(DTS.Common.Enums.Database.DbType dbType, string dbName)
{
DbName = dbName;
DatabaseType = dbType;
_eventAggregator.GetEvent().Publish(new ProgressBarEventArg(CurrentTaskBar, Colors.White,
System.Windows.Visibility.Collapsed, 0D, ""));
_eventAggregator.GetEvent().Publish(new ProgressBarEventArg(OverallTaskBar, Colors.White,
System.Windows.Visibility.Collapsed, 0D, ""));
OnPropertyChanged("CopyEnabled");
}
private void SetStatus(string bar, double percentage, string text)
{
_eventAggregator.GetEvent()
.Publish(new ProgressBarEventArg(bar, Colors.White, System.Windows.Visibility.Visible, percentage, text));
}
private static readonly List _allDBTables = new List()
{
"AddOrRemove",
"AnalogDiagnostics",
"CalculatedChannelOperation",
"CalculatedChannels",
"CalibrationType",
"ChannelCodes",
"ChannelCodeType",
"Channels",
"ChannelSettings",
"CustomerDetails",
"DAS",
"DASChannels",
"DataPRODbVersion",
"DbTableVersions",
"DefaultProperties",
"DiagnosticRuns",
"GroupChannelSettings",
"GroupHardware",
"Groups",
"LabratoryDetails",
"LastUsedHardware",
"LevelTriggers",
"LockedItemCategories",
"LockedItems",
"RecordingMode",
"RecordingModes",
"ROIPeriodChannels",
"SensorBridgeLegMode",
"SensorBridgeType",
"SensorCalibrationRecord",
"SensorCalibrationRecordIRTracc",
"SensorCalibrationRecordPolynomial",
"SensorCalibrations",
"SensorChangeHistory",
"SensorChangeType",
"SensorCouplingMode",
"SensorDigitalOutputMode",
"SensorModels",
"Sensors",
"SensorsAnalog",
"SensorsDigitalIn",
"SensorsDigitalOut",
"SensorSettingMode",
"SensorShunt",
"SensorSquibFireMode",
"SensorSquibMeasurementType",
"SensorsSquib",
"SensorsStreamInput",
"SensorsStreamOutput",
"SensorStatus",
"SensorsType",
"SensorsUART",
"SensorTestHistory",
"Settings",
"SoftwareFilters",
"StoredProcedureVersions",
"TagAssignments",
"TagObjectType",
"Tags",
"tblDataPRODbVersion",
"TestEngineerDetails",
"TestGraphs",
"TestHistory",
"TestSetupGroups",
"TestSetupHardware",
"TestSetupObjectMetaData",
"TestSetupROIs",
"TestSetups",
"TestSetupSettings",
"UIItems",
"UIItemSettings",
"UserProperties",
"Users",
"UsersRoles"
};
private static readonly HashSet _tablesWithIdentities = new HashSet()
{
"AnalogDiagnostics",
"CalculatedChannels",
"ChannelCodes",
"ChannelCodeType",
"Channels",
"ChannelSettings",
"CustomerDetails",
"DAS",
"DASChannels",
"DiagnosticRuns",
"GroupHardware",
"Groups",
"LabratoryDetails",
"LastUsedHardware",
"LevelTriggers",
"LockedItemCategories",
"LockedItems",
"ROIPeriodChannels",
"SensorCalibrationRecord",
"SensorCalibrationRecordIRTracc",
"SensorCalibrationRecordPolynomial",
"SensorCalibrations",
"SensorChangeHistory",
"SensorChangeType",
"SensorModels",
"Sensors",
"SensorsAnalog",
"SensorsDigitalIn",
"SensorsDigitalOut",
"SensorsSquib",
"SensorsStreamInput",
"SensorsStreamOutput",
"SensorsUART",
"SensorTestHistory",
"Settings",
"SoftwareFilters",
"Tags",
"TestEngineerDetails",
"TestGraphs",
"TestHistory",
"TestSetupGroups",
"TestSetupHardware",
"TestSetupObjectMetaData",
"TestSetupROIs",
"TestSetups",
"UIItems",
"UIItemSettings",
"Users"
};
private void CopyFunc()
{
try
{
DTS.Common.Storage.DatabaseServices.BackupLocalDatabase(DbName);
}
catch (System.IO.FileNotFoundException ex)
{
_eventAggregator.GetEvent()
.Publish(new DbStatusArg(DbStatusArg.EventTypes.FailedToBackupLocalFileNotFound, ex));
APILogger.Log(ex);
return;
}
catch (Exception ex)
{
_eventAggregator.GetEvent()
.Publish(new DbStatusArg(DbStatusArg.EventTypes.FailedToBackupLocal, null));
APILogger.Log(ex);
return;
}
try
{
//get list of all tables
//I'd like to do this through SQL, but ran into problems
var allTables = _allDBTables;
SetStatus(OverallTaskBar, 0, "");
SetStatus(CurrentTaskBar, 0, "");
double steps = 2 + allTables.Count;
//turn off all constraints
SetStatus(OverallTaskBar, 0, Resources.StringResources.ClearingLocalDb);
using (var cmd = LocalOnlyOperations.GetSQLCommand(true))
{
try
{
cmd.CommandText = "EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
finally
{
cmd.Connection.Dispose();
}
}
double currentStep = 1;
SetStatus(OverallTaskBar, 100D * currentStep / steps, "");
//Copy remote table to local)
foreach (var table in allTables)
{
SetStatus(OverallTaskBar, 100D * currentStep / steps,
$"{Resources.StringResources.CopyingTable} {table}");
SetStatus(CurrentTaskBar, 0D, "");
CopyRemoteTable(table, _tablesWithIdentities.Contains(table));
currentStep++;
}
//Change any DASId columns in the Channels table from 0 to NULL
try
{
using (var cmd = LocalOnlyOperations.GetSQLCommand(true))
{
try
{
cmd.CommandText = "UPDATE Channels SET DASId = NULL WHERE DASId = 0";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
finally { cmd.Connection.Dispose(); }
}
}
catch (Exception ex)
{
APILogger.Log(ex);
}
//turn on all constraints
SetStatus(OverallTaskBar, 100D * currentStep / steps, Resources.StringResources.EnablingConstraints);
try
{
using (var cmd = LocalOnlyOperations.GetSQLCommand(true))
{
try
{
cmd.CommandText = "EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
_eventAggregator.GetEvent().Publish(new DbStatusArg(DbStatusArg.EventTypes.Complete, null));
}
finally
{
cmd.Connection.Dispose();
}
}
}
catch (Exception ex)
{
APILogger.Log(ex);
}
}
catch (Exception ex)
{
APILogger.Log(ex);
_eventAggregator.GetEvent()
.Publish(new DbStatusArg(DbStatusArg.EventTypes.FailedToCopy, ex));
try
{
DTS.Common.Storage.DatabaseServices.RestoreLocalDatabase(DbName);
}
catch (Exception)
{
APILogger.Log(ex);
_eventAggregator.GetEvent().Publish(
new DbStatusArg(DbStatusArg.EventTypes.FailedToRestoreLocal, null));
}
}
finally
{
_eventAggregator.GetEvent().Publish(new ProgressBarEventArg(OverallTaskBar,
Colors.White, System.Windows.Visibility.Collapsed, 0D, ""));
_eventAggregator.GetEvent().Publish(new ProgressBarEventArg(CurrentTaskBar,
Colors.White, System.Windows.Visibility.Collapsed, 0D, ""));
_eventAggregator.GetEvent().Publish(AppStatusArg.Available);
}
}
private void CopyRemoteTable(string tableName, bool bIndentityTable)
{
using (var cmd = LocalOnlyOperations.GetSQLCommand(true))
{
cmd.CommandText = $"DELETE FROM [dbo].[{tableName}]";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
cmd.Connection.Dispose();
}
DataColumnCollection columns = null;
var objects = new List