From de762e7e5b346af5a12eff04cbaa0696eec15b8c Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Wed, 19 Dec 2018 12:57:04 +0200 Subject: Moved all web transport to json :/ --- .../MachineSetup/MachineSetupResponse.cs | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs') diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs new file mode 100644 index 000000000..89450a1d1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.PPC.Common.MachineSetup +{ + public class MachineSetupResponse : WebResponseMessage + { + public String Version { get; set; } + + public String BlobAddress { get; set; } + + public String DbAddress { get; set; } + public String DbUserName { get; set; } + public String DbPassword { get; set; } + + public String OSKey { get; set; } + + public bool SetupActivation { get; set; } + public bool SetupRemoteAssistance { get; set; } + public bool SetupUWF { get; set; } + public bool SetupFirmware { get; set; } + public bool IsDemo { get; set; } + } +} -- cgit v1.3.1 From e0b0859f62924d38c8cd7ac9975303c4bfb08624 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 20 Dec 2018 14:24:19 +0200 Subject: Added environments support for users & roles !! --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 20578304 -> 20578304 bytes .../Build/Shortcuts/Machine Emulator.lnk | Bin 1471 -> 1445 bytes .../Build/Shortcuts/Proto Compiler GUI.lnk | Bin 1464 -> 1444 bytes .../Build/Shortcuts/Stubs Execution GUI.lnk | Bin 1547 -> 1462 bytes .../Build/Shortcuts/Transport Router.lnk | Bin 1578 -> 1493 bytes .../MachineSetup/MachineSetupManager.cs | 35 ++---- .../MachineSetup/MachineSetupResponse.cs | 6 +- .../MachineUpdate/DownloadUpdateResponse.cs | 5 +- .../MachineUpdate/MachineUpdateManager.cs | 47 +++---- .../MachineUpdate/UpdateDBResponse.cs | 5 +- .../Visual_Studio/Tango.BL/Entities/Machine.cs | 123 ++++++++++++++++++ Software/Visual_Studio/Tango.BL/Entities/Rml.cs | 90 +++++++++++++ .../Tango.BL/Enumerations/Permissions.cs | 30 ++++- .../Visual_Studio/Tango.BL/Enumerations/Roles.cs | 32 ++++- Software/Visual_Studio/Tango.Core/DB/DbManager.cs | 5 + Software/Visual_Studio/Tango.Core/DataSource.cs | 12 ++ .../Visual_Studio/Tango.DAL.Remote/DB/MACHINE.cs | 4 + Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs | 5 + .../Tango.DAL.Remote/DB/RemoteADO.edmx | 53 +++++++- .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 139 +++++++++++---------- .../ExaminerConfigurationBuilder.cs | 34 +++-- .../ExaminerSequenceConfigurationRunner.cs | 14 +-- .../Tango.UnitTesting/SQLExaminer_TST.cs | 66 ++++++---- .../ObservablesGenerator.cs | 3 +- .../Controllers/MachineStudioController.cs | 2 +- .../Controllers/PPCController.cs | 37 ++++-- 27 files changed, 551 insertions(+), 196 deletions(-) (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 29c02c4ab..952f63196 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 1c5b90031..24819348d 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk index 612ccab34..7bbdf66b4 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk and b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk index 6f203ca29..ab1bc5eed 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk and b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk index 26bdb7c64..5b8ad68a5 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk and b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk index 355f4b364..febffabca 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk and b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index 1f86e0953..b8638b158 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -207,22 +207,20 @@ namespace Tango.PPC.Common.MachineSetup //Synchronize database UpdateProgress("Updating Database", "Initializing..."); - String db_name = "Tango"; - String localAddress = SettingsManager.Default.GetOrCreate().DataSource.Address; - String remote_address = setup_response.DbAddress; + var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; - LogManager.Log($"Synchronizing database '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + LogManager.Log($"Synchronizing database '{setup_response.DataSource.ToString()}' => '{localDataSource.ToString()}'..."); UpdateProgress("Updating Database", "Connecting to local database..."); - LogManager.Log($"Connecting to local database at {localAddress}..."); - DbManager db = DbManager.FromAddress(localAddress); + LogManager.Log($"Connecting to local database at {localDataSource}..."); + DbManager db = DbManager.FromAddress(localDataSource.Address); - LogManager.Log($"Ensuring {db_name} database exists on the local machine..."); - if (!db.Exists(db_name)) + LogManager.Log($"Ensuring {localDataSource.Catalog} database exists on the local machine..."); + if (!db.Exists(localDataSource.Catalog)) { UpdateProgress("Updating Database", "Creating new database..."); LogManager.Log("Database does not exist. Creating new database..."); - db.Create(db_name); + db.Create(localDataSource.Catalog); } else { @@ -232,7 +230,7 @@ namespace Tango.PPC.Common.MachineSetup db.Dispose(); LogManager.Log("Initializing database manager..."); - db = DbManager.FromAddressAndName(localAddress, db_name); + db = DbManager.FromDataSource(localDataSource); UpdateProgress("Updating Database", "Clearing current database..."); LogManager.Log("Clearing database..."); @@ -248,20 +246,9 @@ namespace Tango.PPC.Common.MachineSetup ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( Path.Combine(_newPackageTempFolder, "Provision Scripts", "config.xml"), Path.Combine(_newPackageTempFolder, "Provision Scripts"), - new ExaminerSequenceDataSource() - { - Address = remote_address, - DataBaseName = db_name, - IntegratedSecurity = false, - UserName = setup_response.DbUserName, - Password = setup_response.DbPassword, - }, - new ExaminerSequenceDataSource() - { - Address = localAddress, - DataBaseName = db_name, - IntegratedSecurity = true, - }, serialNumber); + setup_response.DataSource, + localDataSource, + serialNumber); runner.Log += (x, msg) => { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs index 89450a1d1..5e8885af7 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupResponse.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core; using Tango.Transport.Web; namespace Tango.PPC.Common.MachineSetup @@ -13,9 +14,7 @@ namespace Tango.PPC.Common.MachineSetup public String BlobAddress { get; set; } - public String DbAddress { get; set; } - public String DbUserName { get; set; } - public String DbPassword { get; set; } + public DataSource DataSource { get; set; } public String OSKey { get; set; } @@ -23,6 +22,7 @@ namespace Tango.PPC.Common.MachineSetup public bool SetupRemoteAssistance { get; set; } public bool SetupUWF { get; set; } public bool SetupFirmware { get; set; } + public bool SetupFPGA { get; set; } public bool IsDemo { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/DownloadUpdateResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/DownloadUpdateResponse.cs index c42c06f3b..de978ed66 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/DownloadUpdateResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/DownloadUpdateResponse.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core; using Tango.Transport.Web; namespace Tango.PPC.Common.MachineUpdate @@ -13,8 +14,6 @@ namespace Tango.PPC.Common.MachineUpdate public String BlobAddress { get; set; } - public String DbAddress { get; set; } - public String DbUserName { get; set; } - public String DbPassword { get; set; } + public DataSource DataSource { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs index 6df7117d7..69df627fb 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -164,18 +164,16 @@ namespace Tango.PPC.Common.MachineUpdate //Synchronize database UpdateProgress("Updating Database", "Initializing..."); - String db_name = "Tango"; - String localAddress = SettingsManager.Default.GetOrCreate().DataSource.Address; - String remote_address = update_response.DbAddress; + var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; - LogManager.Log($"Synchronizing database '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + LogManager.Log($"Synchronizing database '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'..."); UpdateProgress("Updating Database", "Connecting to local database..."); LogManager.Log("Initializing database manager..."); - DbManager db = DbManager.FromAddressAndName(localAddress, db_name); + DbManager db = DbManager.FromDataSource(localDataSource); LogManager.Log("Checking Tango database exists on the local machine..."); - if (!db.Exists(db_name)) + if (!db.Exists(localDataSource.Catalog)) { throw new InvalidProgramException("Database tango does not exists."); } @@ -190,20 +188,9 @@ namespace Tango.PPC.Common.MachineUpdate ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"), Path.Combine(_newPackageTempFolder, "Update Scripts"), - new ExaminerSequenceDataSource() - { - Address = remote_address, - DataBaseName = db_name, - IntegratedSecurity = false, - UserName = update_response.DbUserName, - Password = update_response.DbPassword, - }, - new ExaminerSequenceDataSource() - { - Address = localAddress, - DataBaseName = db_name, - IntegratedSecurity = true, - }, serialNumber); + update_response.DataSource, + localDataSource, + serialNumber); runner.Log += (x, msg) => { @@ -331,15 +318,13 @@ namespace Tango.PPC.Common.MachineUpdate UpdateDBResponse update_response = dbCompareResult.UpdateDBResponse; - String db_name = "Tango"; - String localAddress = SettingsManager.Default.GetOrCreate().DataSource.Address; - String remote_address = update_response.DbAddress; + var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; - LogManager.Log($"Overriding database static tables '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + LogManager.Log($"Overriding database static tables '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'..."); ExaminerConfigurationBuilder builder = new ExaminerConfigurationBuilder(config_file); - builder.SetSourceServer(remote_address, db_name, false, update_response.DbUserName, update_response.DbPassword); - builder.SetTargetServer(localAddress, db_name, true); + builder.SetSource(update_response.DataSource); + builder.SetTarget(localDataSource); builder.Synchronize(); var config = builder.Build(); @@ -410,17 +395,15 @@ namespace Tango.PPC.Common.MachineUpdate LogManager.Log($"Update DB response received: {Environment.NewLine}{update_response.ToJsonString()}"); - String db_name = "Tango"; - String localAddress = SettingsManager.Default.GetOrCreate().DataSource.Address; - String remote_address = update_response.DbAddress; + var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; - LogManager.Log($"Comparing database static tables '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + LogManager.Log($"Comparing database static tables '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'..."); var report_file = TemporaryManager.CreateFile(".xml"); ExaminerConfigurationBuilder builder = new ExaminerConfigurationBuilder(config_file); - builder.SetSourceServer(remote_address, db_name, false, update_response.DbUserName, update_response.DbPassword); - builder.SetTargetServer(localAddress, db_name, true); + builder.SetSource(update_response.DataSource); + builder.SetTarget(localDataSource); builder.SetReportFile(report_file); var config = builder.Build(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdateDBResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdateDBResponse.cs index 212cd02d2..36be14750 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdateDBResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdateDBResponse.cs @@ -3,14 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core; using Tango.Transport.Web; namespace Tango.PPC.Common.MachineUpdate { public class UpdateDBResponse : WebResponseMessage { - public String DbAddress { get; set; } - public String DbUserName { get; set; } - public String DbPassword { get; set; } + public DataSource DataSource { get; set; } } } diff --git a/Software/Visual_Studio/Tango.BL/Entities/Machine.cs b/Software/Visual_Studio/Tango.BL/Entities/Machine.cs index 383492905..92ed46850 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/Machine.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/Machine.cs @@ -21,6 +21,11 @@ using Tango.Core; namespace Tango.BL.Entities { + + /// + /// + /// + [Table("MACHINES")] public partial class Machine : ObservableEntity { @@ -51,8 +56,12 @@ namespace Tango.BL.Entities public event EventHandler SetupFirmwareChanged; + public event EventHandler SetupFpgaChanged; + public event EventHandler IsDemoChanged; + public event EventHandler EnvironmentChanged; + public event EventHandler> CatsChanged; public event EventHandler DefaultColorSpaceChanged; @@ -71,6 +80,8 @@ namespace Tango.BL.Entities public event EventHandler DefaultRmlChanged; + public event EventHandler LoadedRmlChanged; + public event EventHandler DefaultSpoolTypeChanged; protected String _serialnumber; @@ -261,6 +272,32 @@ namespace Tango.BL.Entities } } + protected String _loadedrmlguid; + + /// + /// Gets or sets the machine loaded rml guid. + /// + + [Column("LOADED_RML_GUID")] + [ForeignKey("LoadedRml")] + + public String LoadedRmlGuid + { + get + { + return _loadedrmlguid; + } + + set + { + if (_loadedrmlguid != value) + { + _loadedrmlguid = value; + RaisePropertyChanged(nameof(LoadedRmlGuid)); + } + } + } + protected String _targetjobtypes; /// @@ -593,6 +630,34 @@ namespace Tango.BL.Entities } } + protected Boolean _setupfpga; + + /// + /// Gets or sets the machine setup fpga. + /// + + [Column("SETUP_FPGA")] + + public Boolean SetupFpga + { + get + { + return _setupfpga; + } + + set + { + if (_setupfpga != value) + { + _setupfpga = value; + + SetupFpgaChanged?.Invoke(this, value); + + RaisePropertyChanged(nameof(SetupFpga)); + } + } + } + protected Boolean _isdemo; /// @@ -621,6 +686,36 @@ namespace Tango.BL.Entities } } + protected Int32 _environment; + + /// + /// 0 = DEV + /// 1 = TEST + /// 2 = PROD + /// + + [Column("ENVIRONMENT")] + + public Int32 Environment + { + get + { + return _environment; + } + + set + { + if (_environment != value) + { + _environment = value; + + EnvironmentChanged?.Invoke(this, value); + + RaisePropertyChanged(nameof(Environment)); + } + } + } + protected SynchronizedObservableCollection _cats; /// @@ -865,6 +960,34 @@ namespace Tango.BL.Entities } } + protected Rml _loadedrml; + + /// + /// Gets or sets the machine rml1. + /// + + [XmlIgnore] + [JsonIgnore] + public virtual Rml LoadedRml + { + get + { + return _loadedrml; + } + + set + { + if (_loadedrml != value) + { + _loadedrml = value; + + LoadedRmlChanged?.Invoke(this, value); + + RaisePropertyChanged(nameof(LoadedRml)); + } + } + } + protected SpoolType _defaultspooltype; /// diff --git a/Software/Visual_Studio/Tango.BL/Entities/Rml.cs b/Software/Visual_Studio/Tango.BL/Entities/Rml.cs index c7c3077d7..b79736ad4 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/Rml.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/Rml.cs @@ -51,6 +51,10 @@ namespace Tango.BL.Entities public event EventHandler EstimatedThreadDiameterChanged; + public event EventHandler RankChanged; + + public event EventHandler ThumbnailChanged; + public event EventHandler> CatsChanged; public event EventHandler> CctsChanged; @@ -67,6 +71,8 @@ namespace Tango.BL.Entities public event EventHandler> MachinesChanged; + public event EventHandler> Machines1Changed; + public event EventHandler MediaColorChanged; public event EventHandler MediaConditionChanged; @@ -623,6 +629,62 @@ namespace Tango.BL.Entities } } + protected Int32 _rank; + + /// + /// Gets or sets the rml rank. + /// + + [Column("RANK")] + + public Int32 Rank + { + get + { + return _rank; + } + + set + { + if (_rank != value) + { + _rank = value; + + RankChanged?.Invoke(this, value); + + RaisePropertyChanged(nameof(Rank)); + } + } + } + + protected Byte[] _thumbnail; + + /// + /// Gets or sets the rml thumbnail. + /// + + [Column("THUMBNAIL")] + + public Byte[] Thumbnail + { + get + { + return _thumbnail; + } + + set + { + if (_thumbnail != value) + { + _thumbnail = value; + + ThumbnailChanged?.Invoke(this, value); + + RaisePropertyChanged(nameof(Thumbnail)); + } + } + } + protected SynchronizedObservableCollection _cats; /// @@ -837,6 +899,32 @@ namespace Tango.BL.Entities } } + protected SynchronizedObservableCollection _machines1; + + /// + /// Gets or sets the rml machines1. + /// + + public virtual SynchronizedObservableCollection Machines1 + { + get + { + return _machines1; + } + + set + { + if (_machines1 != value) + { + _machines1 = value; + + Machines1Changed?.Invoke(this, value); + + RaisePropertyChanged(nameof(Machines1)); + } + } + } + protected MediaColor _mediacolor; /// @@ -991,6 +1079,8 @@ namespace Tango.BL.Entities Machines = new SynchronizedObservableCollection(); + Machines1 = new SynchronizedObservableCollection(); + ProcessParametersTablesGroups = new SynchronizedObservableCollection(); } diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs index 5e5c7390d..721057ad0 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs @@ -50,10 +50,10 @@ namespace Tango.BL.Enumerations RunMachineStudio = 6, /// - /// (Allows publishing of new Machine Studio release version to the Machine Studio Service.) + /// (Allows publishing of new Machine Studio versions.) /// - [Description("Allows publishing of new Machine Studio release version to the Machine Studio Service.")] - PublishMachineStudioVersion = 7, + [Description("Allows publishing of new Machine Studio versions.")] + PublishMachineStudioVersions = 7, /// /// (Allows loading the stubs module in machine studio) @@ -127,5 +127,29 @@ namespace Tango.BL.Enumerations [Description("Allows running the hardware versions module in Machine Studio.")] RunHardwareVersionsModule = 19, + /// + /// (Grants access to the development environment.) + /// + [Description("Grants access to the development environment.")] + AccessDevelopmentDataSource = 20, + + /// + /// (Grants access to the test environment.) + /// + [Description("Grants access to the test environment.")] + AccessTestDataSource = 21, + + /// + /// (Grants access to the production environment.) + /// + [Description("Grants access to the production environment.")] + AccessProductionDataSource = 22, + + /// + /// (Allows publishing of new PPC application versions.) + /// + [Description("Allows publishing of new PPC application versions.")] + PublishPPCVersions = 23, + } } diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/Roles.cs b/Software/Visual_Studio/Tango.BL/Enumerations/Roles.cs index 626dc8f40..0ee332c6a 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/Roles.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/Roles.cs @@ -38,9 +38,9 @@ namespace Tango.BL.Enumerations Technician = 2, /// - /// (Publish new Machine Studio Versions) + /// (Machine Studio versions publisher.) /// - [Description("Publish new Machine Studio Versions")] + [Description("Machine Studio versions publisher.")] MachineStudioPublisher = 4, /// @@ -56,9 +56,9 @@ namespace Tango.BL.Enumerations PPCUser = 9, /// - /// (Manage organizations users and roles) + /// (Manages organizations users and roles) /// - [Description("Manage organizations users and roles")] + [Description("Manages organizations users and roles")] UsersAndRolesManager = 7, /// @@ -79,5 +79,29 @@ namespace Tango.BL.Enumerations [Description("Twine Software Developer")] SoftwareDeveloper = 6, + /// + /// (Specifies that a user should work against a development environment data source.) + /// + [Description("Specifies that a user should work against a development environment data source.")] + DevelopmentEnvironmentUser = 10, + + /// + /// (Specifies that a user should work against a testing environment data source.) + /// + [Description("Specifies that a user should work against a testing environment data source.")] + TestEnvironmentUser = 11, + + /// + /// (Specifies that a user should work against a production environment data source.) + /// + [Description("Specifies that a user should work against a production environment data source.")] + ProductionEnvironmentUser = 12, + + /// + /// (PPC Application Publisher) + /// + [Description("PPC Application Publisher")] + PPCPublisher = 13, + } } diff --git a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs index 0a9123164..1d90b30e8 100644 --- a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs +++ b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs @@ -41,6 +41,11 @@ namespace Tango.Core.DB return new DbManager(new SqlConnection(String.Format("Server={0};Integrated security=SSPI;Initial Catalog={1}", address, database))); } + public static DbManager FromDataSource(DataSource dataSource) + { + return new DbManager(dataSource.ToConnection() as SqlConnection); + } + public static DbManager FromCredentials(String address, String database, String userName, String password) { return new DbManager(new SqlConnection(String.Format("Server={0};Initial Catalog={1};User Id={2};Password={3}", address, database, userName, password))); diff --git a/Software/Visual_Studio/Tango.Core/DataSource.cs b/Software/Visual_Studio/Tango.Core/DataSource.cs index c5c58cf09..fd7d5e3ec 100644 --- a/Software/Visual_Studio/Tango.Core/DataSource.cs +++ b/Software/Visual_Studio/Tango.Core/DataSource.cs @@ -66,6 +66,7 @@ namespace Tango.Core /// public DbConnection ToConnection() { + switch (Type) { case DataSourceType.SQLite: @@ -121,5 +122,16 @@ namespace Tango.Core return null; } } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return $"{Address}\\{Catalog}"; + } } } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/MACHINE.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/MACHINE.cs index 341f2aa2a..54b7a6231 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/MACHINE.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/MACHINE.cs @@ -33,6 +33,7 @@ namespace Tango.DAL.Remote.DB public string MACHINE_VERSION_GUID { get; set; } public string CONFIGURATION_GUID { get; set; } public string DEFAULT_RML_GUID { get; set; } + public string LOADED_RML_GUID { get; set; } public string TARGET_JOB_TYPES { get; set; } public string DEFAULT_COLOR_SPACE_GUID { get; set; } public double DEFAULT_SEGMENT_LENGTH { get; set; } @@ -45,7 +46,9 @@ namespace Tango.DAL.Remote.DB public bool SETUP_REMOTE_ASSISTANCE { get; set; } public bool SETUP_UWF { get; set; } public bool SETUP_FIRMWARE { get; set; } + public bool SETUP_FPGA { get; set; } public bool IS_DEMO { get; set; } + public int ENVIRONMENT { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection CATS { get; set; } @@ -60,6 +63,7 @@ namespace Tango.DAL.Remote.DB public virtual ICollection MACHINES_EVENTS { get; set; } public virtual ORGANIZATION ORGANIZATION { get; set; } public virtual RML RML { get; set; } + public virtual RML RML1 { get; set; } public virtual SPOOL_TYPES SPOOL_TYPES { get; set; } } } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs index ab767508c..a7a5b1deb 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs @@ -22,6 +22,7 @@ namespace Tango.DAL.Remote.DB this.JOBS = new HashSet(); this.LIQUID_TYPES_RMLS = new HashSet(); this.MACHINES = new HashSet(); + this.MACHINES1 = new HashSet(); this.PROCESS_PARAMETERS_TABLES_GROUPS = new HashSet(); } @@ -48,6 +49,8 @@ namespace Tango.DAL.Remote.DB public double TENSILE_STRENGTH { get; set; } public double ELONGATION_AT_BREAK_PERCENTAGE { get; set; } public double ESTIMATED_THREAD_DIAMETER { get; set; } + public int RANK { get; set; } + public byte[] THUMBNAIL { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection CATS { get; set; } @@ -62,6 +65,8 @@ namespace Tango.DAL.Remote.DB public virtual ICollection LIQUID_TYPES_RMLS { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection MACHINES { get; set; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public virtual ICollection MACHINES1 { get; set; } public virtual MEDIA_COLORS MEDIA_COLORS { get; set; } public virtual MEDIA_CONDITIONS MEDIA_CONDITIONS { get; set; } public virtual MEDIA_MATERIALS MEDIA_MATERIALS { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index 86cf4ed6a..ed932c954 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -700,6 +700,7 @@ + @@ -712,7 +713,9 @@ + + @@ -810,7 +813,7 @@ - + @@ -882,6 +885,8 @@ + + @@ -1876,6 +1881,18 @@ + + + + + + + + + + + + @@ -2483,6 +2500,10 @@ + + + + @@ -2929,6 +2950,10 @@ + + + + @@ -3792,6 +3817,7 @@ + @@ -3804,7 +3830,9 @@ + + @@ -3814,6 +3842,7 @@ + @@ -3927,7 +3956,7 @@ - + @@ -4003,6 +4032,8 @@ + + @@ -4011,6 +4042,7 @@ + @@ -5129,6 +5161,18 @@ + + + + + + + + + + + + @@ -6055,7 +6099,9 @@ + + @@ -6068,6 +6114,7 @@ + @@ -6236,6 +6283,8 @@ + + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index cf9ff4f22..886074e80 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,81 +5,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - + + + + + @@ -149,6 +149,7 @@ + diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerConfigurationBuilder.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerConfigurationBuilder.cs index 7123553a6..dbed95b77 100644 --- a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerConfigurationBuilder.cs +++ b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerConfigurationBuilder.cs @@ -30,7 +30,7 @@ namespace Tango.SQLExaminer _config.DataSources.Clear(); } - public ExaminerConfigurationBuilder SetSourceServer(String address, String databaseName, bool integratedSecurity = true, String userName = null, String password = null) + public ExaminerConfigurationBuilder SetSource(Core.DataSource dataSource) { DataSource d1 = _config.DataSources.SingleOrDefault(x => x.ID == 1); @@ -41,20 +41,25 @@ namespace Tango.SQLExaminer } d1.ID = 1; - d1.DataBase = databaseName; - d1.Server = address; - d1.UserName = userName; - d1.Password = password; + d1.DataBase = dataSource.Catalog; + d1.Server = dataSource.Address; + d1.UserName = dataSource.UserName; + d1.Password = dataSource.Password; - if (integratedSecurity) + if (dataSource.IntegratedSecurity) { d1.IntegratedSecurity = "True"; } + if (dataSource.Type == Core.DataSourceType.Azure) + { + d1.Type = "SqlAzure"; + } + return this; } - public ExaminerConfigurationBuilder SetTargetServer(String address, String databaseName, bool integratedSecurity = true, String userName = null, String password = null) + public ExaminerConfigurationBuilder SetTarget(Core.DataSource dataSource) { DataSource d2 = _config.DataSources.SingleOrDefault(x => x.ID == 2); @@ -65,17 +70,22 @@ namespace Tango.SQLExaminer } d2.ID = 2; - d2.DataBase = databaseName; - d2.Server = address; - d2.UserName = userName; - d2.Password = password; + d2.DataBase = dataSource.Catalog; + d2.Server = dataSource.Address; + d2.UserName = dataSource.UserName; + d2.Password = dataSource.Password; - if (integratedSecurity) + if (dataSource.IntegratedSecurity) { d2.IntegratedSecurity = "True"; } + if (dataSource.Type == Core.DataSourceType.Azure) + { + d2.Type = "SqlAzure"; + } + return this; } diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs index b9ee986bc..de146ead3 100644 --- a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs +++ b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs @@ -14,9 +14,9 @@ namespace Tango.SQLExaminer public String SequenceFile { get; private set; } - public ExaminerSequenceDataSource Source { get; private set; } + public Core.DataSource Source { get; private set; } - public ExaminerSequenceDataSource Target { get; private set; } + public Core.DataSource Target { get; private set; } public String MachineSerialNumber { get; private set; } @@ -24,7 +24,7 @@ namespace Tango.SQLExaminer public ExaminerSequenceConfiguration Configuration { get; private set; } - public ExaminerSequenceConfigurationRunner(String sequenceFile, String scriptsFolder, ExaminerSequenceDataSource source, ExaminerSequenceDataSource target, String machineSerialNumber) + public ExaminerSequenceConfigurationRunner(String sequenceFile, String scriptsFolder, Core.DataSource source, Core.DataSource target, String machineSerialNumber) { SequenceFile = sequenceFile; ScriptsFolder = scriptsFolder; @@ -49,13 +49,13 @@ namespace Tango.SQLExaminer if (item.Direction == ExaminerSequenceItemDirection.SourceToTarget) { - builder.SetSourceServer(Source.Address, Source.DataBaseName, Source.IntegratedSecurity, Source.UserName, Source.Password); - builder.SetTargetServer(Target.Address, Target.DataBaseName, Target.IntegratedSecurity, Target.UserName, Target.Password); + builder.SetSource(Source); + builder.SetTarget(Target); } else { - builder.SetSourceServer(Target.Address, Target.DataBaseName, Target.IntegratedSecurity, Target.UserName, Target.Password); - builder.SetTargetServer(Source.Address, Source.DataBaseName, Source.IntegratedSecurity, Source.UserName, Source.Password); + builder.SetSource(Target); + builder.SetTarget(Source); } if (item.RequiresSerialNumber) diff --git a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer_TST.cs index 5b7ce16ca..5863aca74 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer_TST.cs @@ -20,6 +20,28 @@ namespace Tango.UnitTesting [TestCategory("SQL Examiner")] public class SQLExaminer_TST { + private Core.DataSource GetSource(String catalog = "Tango") + { + return new Core.DataSource() + { + Type = DataSourceType.SQLServer, + Address = "localhost\\SQLEXPRESS", + Catalog = catalog, + IntegratedSecurity = true, + }; + } + + private Core.DataSource GetTarget(String catalog = "Test") + { + return new Core.DataSource() + { + Type = DataSourceType.SQLServer, + Address = "localhost\\SQLEXPRESS", + Catalog = catalog, + IntegratedSecurity = true, + }; + } + [TestMethod] public void Generate_Schema_Synchronization_Script() { @@ -28,8 +50,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango", false, "Synchronizer", "Aa123456"). - SetTargetServer("twine01\\SQLTWINE", "Tango"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetBackupFile(Path.Combine(temp_folder, "db.bak")). SetReportFile(Path.Combine(temp_folder, "report.xml")); @@ -50,8 +72,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango", false, "Synchronizer", "Aa123456"). - SetTargetServer("twine01\\SQLTWINE", "Tango"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetReportFile(Path.Combine(temp_folder, "report.xml")). SetMachineSerialNumber("1111"); @@ -72,8 +94,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango", false, "Synchronizer", "Aa123456"). - SetTargetServer("twine01\\SQLTWINE", "Tango"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetReportFile(Path.Combine(temp_folder, "report.xml")); var config = builder.Build(); @@ -101,8 +123,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango"). - SetTargetServer("localhost\\SQLEXPRESS", "Test"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetReportFile("C:\\Data\\Report.xml"); var config = builder.Build(); @@ -125,8 +147,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango"). - SetTargetServer("localhost\\SQLEXPRESS", "Test"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetReportFile("C:\\DATA\\report_data.xml"); var config = builder.Build(); @@ -153,8 +175,8 @@ namespace Tango.UnitTesting var temp_folder = Helper.GetTempFolderPath(); builder. - SetSourceServer("localhost\\SQLEXPRESS", "Tango"). - SetTargetServer("localhost\\SQLEXPRESS", "Test"). + SetSource(GetSource()). + SetTarget(GetTarget()). SetMachineSerialNumber("1111"); var config = builder.Build(); @@ -216,8 +238,8 @@ namespace Tango.UnitTesting ExaminerConfigurationBuilder builder = new ExaminerConfigurationBuilder(ExaminerConfigurationType.Schema); builder. - SetSourceServer("localhost\\SQLEXPRESS", source_db). - SetTargetServer("localhost\\SQLEXPRESS", target_db). + SetSource(GetSource(source_db)). + SetTarget(GetTarget(target_db)). Synchronize(). SetReportFile(report_file); @@ -236,8 +258,8 @@ namespace Tango.UnitTesting builder = new ExaminerConfigurationBuilder(ExaminerConfigurationType.OverrideData); builder. - SetSourceServer("localhost\\SQLEXPRESS", source_db). - SetTargetServer("localhost\\SQLEXPRESS", target_db). + SetSource(GetSource(source_db)). + SetTarget(GetTarget(target_db)). Synchronize(). SetReportFile(report_file); @@ -255,8 +277,8 @@ namespace Tango.UnitTesting builder = new ExaminerConfigurationBuilder(ExaminerConfigurationType.ProvisionMachine); builder. - SetSourceServer("localhost\\SQLEXPRESS", source_db). - SetTargetServer("localhost\\SQLEXPRESS", target_db). + SetSource(GetSource(source_db)). + SetTarget(GetTarget(target_db)). SetMachineSerialNumber(machine_serial_number). Synchronize(). SetReportFile(report_file); @@ -308,8 +330,8 @@ namespace Tango.UnitTesting builder = new ExaminerConfigurationBuilder(ExaminerConfigurationType.UpdateTwineDB); builder. - SetSourceServer("localhost\\SQLEXPRESS", target_db). - SetTargetServer("localhost\\SQLEXPRESS", source_db). + SetSource(GetTarget(target_db)). + SetTarget(GetSource(source_db)). Synchronize(). SetReportFile(report_file); @@ -341,8 +363,8 @@ namespace Tango.UnitTesting builder = new ExaminerConfigurationBuilder(ExaminerConfigurationType.UpdateMachine); builder. - SetSourceServer("localhost\\SQLEXPRESS", source_db). - SetTargetServer("localhost\\SQLEXPRESS", target_db). + SetSource(GetSource(source_db)). + SetTarget(GetTarget(target_db)). SetMachineSerialNumber(machine_serial_number). Synchronize(). SetReportFile(report_file); diff --git a/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/ObservablesGenerator.cs b/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/ObservablesGenerator.cs index 876639b78..e45815046 100644 --- a/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/ObservablesGenerator.cs +++ b/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/ObservablesGenerator.cs @@ -103,11 +103,12 @@ namespace Tango.DBObservablesGenerator.CLI codeField.Name = codeField.Type; codeField.XmlIgnore = true; - var fk = foreignKeys.SingleOrDefault(x => x.Contains(codeField.Name)); + var fk = foreignKeys.FirstOrDefault(x => x.Contains(codeField.Name)); if (fk != null) { codeField.Name = fk; + foreignKeys.Remove(fk); } codeField.Complex = true; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs index 245c18b9b..ed1a807be 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs @@ -100,7 +100,7 @@ namespace Tango.MachineService.Controllers var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); - if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersion)) + if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersions)) { var latestVersion = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); Version currentVersion = Version.Parse(request.Version); diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 9ce22bbb0..662883223 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -18,6 +18,7 @@ using Tango.BL; using Tango.BL.Builders; using Tango.BL.Entities; using Tango.BL.Enumerations; +using Tango.Core; using Tango.Core.DB; using Tango.Core.Helpers; using Tango.Core.IO; @@ -101,9 +102,15 @@ namespace Tango.MachineService.Controllers }); } - response.DbAddress = Config.DB_ADDRESS; - response.DbUserName = credentials.UserName; - response.DbPassword = credentials.Password; + response.DataSource = new DataSource() + { + Address = Config.DB_ADDRESS, + Catalog = Config.DB_CATALOG, + UserName = credentials.UserName, + Password = credentials.Password, + Type = DataSourceType.SQLServer, + }; + response.OSKey = machine.OsKey; response.SetupActivation = machine.SetupActivation; response.SetupRemoteAssistance = machine.SetupRemoteAssistance; @@ -160,9 +167,14 @@ namespace Tango.MachineService.Controllers }); } - response.DbAddress = Config.DB_ADDRESS; - response.DbUserName = credentials.UserName; - response.DbPassword = credentials.Password; + response.DataSource = new DataSource() + { + Address = Config.DB_ADDRESS, + Catalog = Config.DB_CATALOG, + UserName = credentials.UserName, + Password = credentials.Password, + Type = DataSourceType.SQLServer, + }; } return response; @@ -231,9 +243,14 @@ namespace Tango.MachineService.Controllers }); } - response.DbAddress = Config.DB_ADDRESS; - response.DbUserName = credentials.UserName; - response.DbPassword = credentials.Password; + response.DataSource = new DataSource() + { + Address = Config.DB_ADDRESS, + Catalog = Config.DB_CATALOG, + UserName = credentials.UserName, + Password = credentials.Password, + Type = DataSourceType.SQLServer, + }; } return response; @@ -290,7 +307,7 @@ namespace Tango.MachineService.Controllers var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); - if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersion)) + if (user != null && user.HasPermission(Permissions.PublishPPCVersions)) { var versions = db.TangoVersions.ToList().Where(x => x.MachineVersionGuid == request.MachineVersionGuid).OrderByDescending(x => Version.Parse(x.Version)).ToList(); -- cgit v1.3.1