diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-10-21 04:06:23 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-10-21 04:06:23 +0300 |
| commit | e8cec64cf5c35b17fed6a1f8f4ea0665d4ddf39b (patch) | |
| tree | b6818e4199eef7cb0b1e183aaf1af08cdba723e9 | |
| parent | e54736fabf4338e9f98a7b8aba738180ae57c120 (diff) | |
| download | Tango-e8cec64cf5c35b17fed6a1f8f4ea0665d4ddf39b.tar.gz Tango-e8cec64cf5c35b17fed6a1f8f4ea0665d4ddf39b.zip | |
DataStore EF !
29 files changed, 567 insertions, 38 deletions
diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf Binary files differindex 04e72ca45..77b6f4120 100644 --- a/Software/DB/PPC/Tango.mdf +++ b/Software/DB/PPC/Tango.mdf diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf Binary files differindex e8aac16f8..4cfc85ea4 100644 --- a/Software/DB/PPC/Tango_log.ldf +++ b/Software/DB/PPC/Tango_log.ldf diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf Binary files differindex 47b8e26d2..4e178ad92 100644 --- a/Software/DB/Tango.mdf +++ b/Software/DB/Tango.mdf diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf Binary files differindex 88b1f2c1d..6e0fefa06 100644 --- a/Software/DB/Tango_log.ldf +++ b/Software/DB/Tango_log.ldf diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs index 323a1b550..b7325cd48 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs @@ -60,27 +60,55 @@ namespace Tango.FSE.UI.DataStore public List<IDataStoreItem> GetAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest<RemoteDataStoreGetAllRequest, RemoteDataStoreGetAllResponse>(new RemoteDataStoreGetAllRequest() + { + Collection = Name + }).Result; + + return result.Items; } public void Delete(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest<RemoteDataStoreDeleteRequest, RemoteDataStoreDeleteResponse>(new RemoteDataStoreDeleteRequest() + { + Collection = Name, + Key = key + }).Result; } public void DeleteAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest<RemoteDataStoreDeleteAllRequest, RemoteDataStoreDeleteAllResponse>(new RemoteDataStoreDeleteAllRequest() + { + Collection = Name, + }).Result; } public int Count() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest<RemoteDataStoreCountRequest, RemoteDataStoreCountResponse>(new RemoteDataStoreCountRequest() + { + Collection = Name + }).Result; + + return result.Count; } public IDataStoreItem GetItem(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest<RemoteDataStoreGetItemRequest, RemoteDataStoreGetItemResponse>(new RemoteDataStoreGetItemRequest() + { + Collection = Name, + Key = key + }).Result; + + return result.Item; + } + + public List<IDataStoreItem> GetUnsynchronized() + { + return GetAll().Where(x => !x.IsSynchronized).ToList(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index 02d8e1858..e5bec90f2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using Tango.Core.DI; using Tango.DataStore; +using Tango.DataStore.EF; using Tango.DataStore.Lite; using Tango.DataStore.Remote; using Tango.Integration.ExternalBridge; @@ -34,7 +35,7 @@ namespace Tango.PPC.Common.DataStore { if (_manager == null) { - _manager = new LiteDBDataStoreManager(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "DataStore", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".db")); + _manager = new EFDataStoreManager(); } return _manager; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index fec0dfd1a..0a6e57f5d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -383,6 +383,10 @@ <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> <Name>Tango.CSV</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.DataStore.EF\Tango.DataStore.EF.csproj"> + <Project>{88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4}</Project> + <Name>Tango.DataStore.EF</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.DataStore.LiteDB\Tango.DataStore.Lite.csproj"> <Project>{fa96bc0c-4055-475c-9dcc-70a5a9436b10}</Project> <Name>Tango.DataStore.Lite</Name> @@ -507,7 +511,7 @@ </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs index 66fca8e36..bbb0e883b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs @@ -14,9 +14,11 @@ namespace Tango.PPC.Common.Web public bool RequestJobs { get; set; } public bool RequestJobRuns { get; set; } public bool RequestMachineEvents { get; set; } + public bool RequestDataStoreItems { get; set; } public int MaxJobs { get; set; } public int MaxJobRuns { get; set; } public int MaxMachinesEvents { get; set; } + public int MaxDataStoreItems { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs index 5c3f7ba78..e90c7c2ac 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List<JobDTO> Jobs { get; set; } public List<JobRunDTO> JobRuns { get; set; } public List<MachinesEventDTO> MachineEvents { get; set; } + public List<DataStoreItemDTO> DataStoreItems { get; set; } public DownloadMachineDataResponse() { Jobs = new List<JobDTO>(); JobRuns = new List<JobRunDTO>(); MachineEvents = new List<MachinesEventDTO>(); + DataStoreItems = new List<DataStoreItemDTO>(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs index fc135c234..fda7a4666 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List<String> SynchronizedJobs { get; set; } public List<String> SynchronizedJobRuns { get; set; } public List<String> SynchronizedMachineEvents { get; set; } + public List<String> SynchronizedDataStoreItems { get; set; } public NotifyMachineDataDownloadCompletedRequest() { SynchronizedJobs = new List<string>(); SynchronizedJobRuns = new List<string>(); SynchronizedMachineEvents = new List<string>(); + SynchronizedDataStoreItems = new List<string>(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs index d7475819c..8eee667cd 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs @@ -15,6 +15,7 @@ namespace Tango.PPC.Common.Web public List<JobRunDTO> JobRuns { get; set; } public List<MachinesEventDTO> MachineEvents { get; set; } public List<TangoUpdateDTO> OfflineUpdates { get; set; } + public List<DataStoreItemDTO> DataStoreItems { get; set; } public String ApplicationVersion { get; set; } public String FirmwareVersion { get; set; } @@ -24,6 +25,7 @@ namespace Tango.PPC.Common.Web JobRuns = new List<JobRunDTO>(); MachineEvents = new List<MachinesEventDTO>(); OfflineUpdates = new List<TangoUpdateDTO>(); + DataStoreItems = new List<DataStoreItemDTO>(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs index 0119c07b6..ba0b4089b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs @@ -15,6 +15,8 @@ namespace Tango.PPC.Common.Web public List<SynchronizationFailedEntity> FailedJobRuns { get; set; } public List<SynchronizationFailedEntity> FailedMachineEvents { get; set; } public List<SynchronizationFailedEntity> FailedOfflineUpdates { get; set; } + public List<SynchronizationFailedEntity> FailedDataStoreItems { get; set; } + public String NotifyCompletedToken { get; set; } public UploadMachineDataResponse() @@ -23,6 +25,7 @@ namespace Tango.PPC.Common.Web FailedJobRuns = new List<SynchronizationFailedEntity>(); FailedMachineEvents = new List<SynchronizationFailedEntity>(); FailedOfflineUpdates = new List<SynchronizationFailedEntity>(); + FailedDataStoreItems = new List<SynchronizationFailedEntity>(); } } } diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs new file mode 100644 index 000000000..769533445 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs @@ -0,0 +1,117 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreCollection : IDataStoreCollection + { + public string Name { get; } + + public EFDataStoreCollection(String name) + { + Name = name; + } + + public void Put<T>(string key, T value) + { + Put(key, (object)value); + } + + public void Put(string key, object value) + { + Put(key, DataStoreHelper.GetDataType(value), value); + } + + public void Put(string key, DataType type, object value) + { + using (var db = ObservablesContext.CreateDefault()) + { + DataStoreItem item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + item = new DataStoreItem(); + db.DataStoreItems.Add(item); + } + + item.CollectionName = Name; + item.Key = key; + item.DataType = (int)type; + item.Value = EFDataStoreHelper.CreateBytes(type, value); + + db.SaveChanges(); + } + } + + public T Get<T>(string key) + { + return (T)Get(key); + } + + public object Get(string key) + { + return GetItem(key).Value; + } + + public IDataStoreItem GetItem(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + var item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + throw new KeyNotFoundException("The specified data store key was not found."); + } + + return item.ToDataStoreItem(); + } + } + + public List<IDataStoreItem> GetAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public List<IDataStoreItem> GetUnsynchronized() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name && !x.IsSynchronized).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public void Delete(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}' AND KEY = '{key}'"); + } + } + + public void DeleteAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}'"); + } + } + + public int Count() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Count(x => x.CollectionName == Name); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs new file mode 100644 index 000000000..c51c54b7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public static class EFDataStoreHelper + { + public static byte[] CreateBytes(DataType type, Object obj) + { + switch (type) + { + case DataType.Int32: + return BitConverter.GetBytes((int)obj); + case DataType.Float: + return BitConverter.GetBytes((float)obj); + case DataType.Double: + return BitConverter.GetBytes((double)obj); + case DataType.Boolean: + return BitConverter.GetBytes((bool)obj); + case DataType.String: + return Encoding.Default.GetBytes(obj.ToString()); + case DataType.Bytes: + return (byte[])obj; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static Object CreateObject(DataType type, byte[] bytes) + { + switch (type) + { + case DataType.Int32: + return BitConverter.ToInt32(bytes, 0); + case DataType.Float: + return BitConverter.ToSingle(bytes, 0); + case DataType.Double: + return BitConverter.ToDouble(bytes, 0); + case DataType.Boolean: + return BitConverter.ToBoolean(bytes, 0); + case DataType.String: + return Encoding.Default.GetString(bytes); + case DataType.Bytes: + return bytes; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static IDataStoreItem CreateDataStoreItem(DataStoreItem item) + { + return new EFDataStoreItem() + { + Guid = item.Guid, + Date = item.LastUpdated, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + Type = (DataType)item.DataType, + Value = CreateObject((DataType)item.DataType, item.Value) + }; + } + + public static DataStoreItem CreateDbDataStoreItem(IDataStoreItem item) + { + return new DataStoreItem() + { + Guid = item.Guid, + LastUpdated = item.Date, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + DataType = (int)item.Type, + Value = CreateBytes(item.Type, item.Value) + }; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs new file mode 100644 index 000000000..45061c7ef --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreItem : IDataStoreItem + { + public string Guid { get; set; } + public string Key { get; set; } + public DataType Type { get; set; } + public object Value { get; set; } + public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public EFDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } + + public override string ToString() + { + return $"{Key}: {Value}"; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs new file mode 100644 index 000000000..4314a25f9 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreManager : IDataStoreManager + { + public IDataStoreCollection GetCollection(string name) + { + using (var db = ObservablesContext.CreateDefault()) + { + return new EFDataStoreCollection(name); + } + } + + public List<string> GetCollectionNames() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Select(x => x.CollectionName).Distinct().ToList(); + } + } + + public void Dispose() + { + //DO Nothing. + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs new file mode 100644 index 000000000..361a37a7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.DataStore; +using Tango.DataStore.EF; + +public static class ExtensionMethods +{ + public static IDataStoreItem ToDataStoreItem(this DataStoreItem item) + { + return EFDataStoreHelper.CreateDataStoreItem(item); + } + + public static DataStoreItem ToDbDataStoreItem(this IDataStoreItem item) + { + return EFDataStoreHelper.CreateDbDataStoreItem(item); + } +} + diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c59e45461 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Data Store Entity Framework Implementation")] +[assembly: AssemblyVersion("2.0.4.1608")] +[assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj new file mode 100644 index 000000000..53e288584 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Tango.DataStore.EF</RootNamespace> + <AssemblyName>Tango.DataStore.EF</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <Deterministic>true</Deterministic> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath> + </Reference> + <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> + <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.ComponentModel.DataAnnotations" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="EFDataStoreCollection.cs" /> + <Compile Include="EFDataStoreHelper.cs" /> + <Compile Include="EFDataStoreItem.cs" /> + <Compile Include="EFDataStoreManager.cs" /> + <Compile Include="ExtensionMethods.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Tango.BL\Tango.BL.csproj"> + <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project> + <Name>Tango.BL</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.DataStore\Tango.DataStore.csproj"> + <Project>{e0364dfa-0721-4637-9d32-9d22aac109d6}</Project> + <Name>Tango.DataStore</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/packages.config b/Software/Visual_Studio/Tango.DataStore.EF/packages.config new file mode 100644 index 000000000..1127d4e32 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="EntityFramework" version="6.2.0" targetFramework="net461" /> + <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> +</packages>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs index 9c939797a..e61385ab8 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs @@ -35,7 +35,8 @@ namespace Tango.DataStore.Lite Key = key, Date = DateTime.UtcNow, Type = type, - Value = value + Value = value, + IsSynchronized = false, }); } @@ -80,5 +81,10 @@ namespace Tango.DataStore.Lite { return _collection.FindById(key); } + + public List<IDataStoreItem> GetUnsynchronized() + { + return _collection.Find(x => !x.IsSynchronized).ToList(); + } } } diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs index 6a5a44462..544a15b61 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs @@ -9,11 +9,18 @@ namespace Tango.DataStore.Lite { public class LiteDBDataStoreItem : IDataStoreItem { + public String Guid { get; set; } [BsonId] public string Key { get; set; } public DataType Type { get; set; } public object Value { get; set; } public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public LiteDBDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } public override string ToString() { diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs index 45f5d3406..e73d02328 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs @@ -61,6 +61,11 @@ namespace Tango.DataStore /// <returns></returns> List<IDataStoreItem> GetAll(); /// <summary> + /// Gets all the data store unsynchronized items in the collection. + /// </summary> + /// <returns></returns> + List<IDataStoreItem> GetUnsynchronized(); + /// <summary> /// Deleted an item by the specified key. /// </summary> /// <param name="key">The key.</param> diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs index 1e58518ff..9c03f40ee 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs @@ -12,6 +12,11 @@ namespace Tango.DataStore public interface IDataStoreItem { /// <summary> + /// Gets or sets the unique identifier (Use only for synchronization). + /// </summary> + String Guid { get; set; } + + /// <summary> /// Gets or sets item id. /// </summary> String Key { get; set; } @@ -30,5 +35,10 @@ namespace Tango.DataStore /// Gets or sets the item update UTC date. /// </summary> DateTime Date { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this item is synchronized with the remote service. + /// </summary> + bool IsSynchronized { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 0c47f5e34..f8682dd18 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -1786,7 +1786,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "int", DataType = DataType.Int32, @@ -1826,7 +1826,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "float", DataType = DataType.Float, @@ -1866,7 +1866,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "double", DataType = DataType.Double, @@ -1906,7 +1906,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bool", DataType = DataType.Boolean, @@ -1946,7 +1946,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "string", DataType = DataType.String, @@ -1986,7 +1986,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest<PutDataStoreItemRequest, PutDataStoreItemResponse>(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bytes", DataType = DataType.Bytes, diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index 218652c1b..0371c1cca 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -213,6 +213,10 @@ <Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project> <Name>Tango.DAL.Remote</Name> </ProjectReference> + <ProjectReference Include="..\Tango.DataStore.EF\Tango.DataStore.EF.csproj"> + <Project>{88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4}</Project> + <Name>Tango.DataStore.EF</Name> + </ProjectReference> <ProjectReference Include="..\Tango.DataStore.LiteDB\Tango.DataStore.Lite.csproj"> <Project>{fa96bc0c-4055-475c-9dcc-70a5a9436b10}</Project> <Name>Tango.DataStore.Lite</Name> @@ -315,7 +319,7 @@ <Import Project="..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets')" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index c77985b68..615dc2154 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -425,6 +425,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Lite", "Tan EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Remote", "Tango.DataStore.Remote\Tango.DataStore.Remote.csproj", "{29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.EF", "Tango.DataStore.EF\Tango.DataStore.EF.csproj", "{88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4012,6 +4014,26 @@ Global {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x64.Build.0 = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.ActiveCfg = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4157,12 +4179,12 @@ Global {EA4233F1-4B7B-4CCF-A6DE-2D17612EBA90} = {E728CBD9-1AF4-4814-A218-E4BD26E7EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} - BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear - BuildVersion_UpdateAssemblyVersion = True - BuildVersion_UpdateFileVersion = False - BuildVersion_StartDate = 2000/1/1 - BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs BuildVersion_UseGlobalSettings = False + BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs + BuildVersion_StartDate = 2000/1/1 + BuildVersion_UpdateFileVersion = False + BuildVersion_UpdateAssemblyVersion = True + BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear + SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} EndGlobalSection EndGlobal diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2c1c27f52..2eb2b01c4 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -562,26 +562,38 @@ namespace Tango.MachineService.Controllers } } - //Insert JobRuns. - foreach (var dto in request.JobRuns) + //Insert Update DataStore Items + foreach (var dto in request.DataStoreItems) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var run = dto.ToObservable(); - run.ID = 0; - run.IsSynchronized = true; + var dataStoreItem = dto.ToObservable(); + dataStoreItem.MachineGuid = RequestToken.Object.MachineGuid; - if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) + dataStoreItem.ID = 0; + dataStoreItem.IsSynchronized = true; + + var existingItem = db.DataStoreItems.SingleOrDefault(x => x.Guid == dataStoreItem.Guid); + + if (existingItem == null) { - db.JobRuns.Add(run); + db.DataStoreItems.Add(dataStoreItem); + db.SaveChanges(); + } + else if (dataStoreItem.LastUpdated > existingItem.LastUpdated) + { + existingItem.DataType = dataStoreItem.DataType; + existingItem.Value = dataStoreItem.Value; + existingItem.IsSynchronized = true; + existingItem.LastUpdated = dataStoreItem.LastUpdated; db.SaveChanges(); } } catch (Exception ex) { - response.FailedJobRuns.Add(new SynchronizationFailedEntity() + response.FailedDataStoreItems.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -590,26 +602,26 @@ namespace Tango.MachineService.Controllers } } - //Insert MachineEvents. - foreach (var dto in request.MachineEvents) + //Insert JobRuns. + foreach (var dto in request.JobRuns) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var ev = dto.ToObservable(); - ev.ID = 0; - ev.IsSynchronized = true; + var run = dto.ToObservable(); + run.ID = 0; + run.IsSynchronized = true; - if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) { - db.MachinesEvents.Add(ev); + db.JobRuns.Add(run); db.SaveChanges(); } } catch (Exception ex) { - response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + response.FailedJobRuns.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -645,6 +657,34 @@ namespace Tango.MachineService.Controllers } } } + + //Insert MachineEvents. + foreach (var dto in request.MachineEvents) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var ev = dto.ToObservable(); + ev.ID = 0; + ev.IsSynchronized = true; + + if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + { + db.MachinesEvents.Add(ev); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } } catch (Exception ex) { @@ -711,6 +751,18 @@ namespace Tango.MachineService.Controllers response.MachineEvents.Add(dto); } } + + //Send DataStore Items + if (request.RequestDataStoreItems) + { + var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); + + foreach (var item in dataStoreItems) + { + DataStoreItemDTO dto = DataStoreItemDTO.FromObservable(item); + response.DataStoreItems.Add(dto); + } + } } return response; @@ -745,6 +797,11 @@ namespace Tango.MachineService.Controllers { db.Database.ExecuteSqlCommand($"UPDATE MACHINES_EVENTS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedMachineEvents.Select(x => "'" + x + "'"))});"); } + + if (request.SynchronizedDataStoreItems.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE DATA_STORE_ITEMS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedDataStoreItems.Select(x => "'" + x + "'"))});"); + } } return response; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index 11c9ee72a..41fa77771 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.5.0")] +[assembly: AssemblyVersion("3.0.6.0")] |
