From 76b22e4d05cbd8d771f678e4b5adc2dc5159afa8 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 14 Nov 2020 22:02:45 +0200 Subject: Moved data store projects to DataStore folder. --- .../DataStore/Tango.DataStore/DataStoreHelper.cs | 160 +++++++++++++++++++++ .../Tango.DataStore/DataStoreProtoObject.cs | 83 +++++++++++ .../DataStore/Tango.DataStore/DataType.cs | 22 +++ .../DataStore/Tango.DataStore/ExtensionMethods.cs | 16 +++ .../Tango.DataStore/IDataStoreCollection.cs | 119 +++++++++++++++ .../DataStore/Tango.DataStore/IDataStoreItem.cs | 44 ++++++ .../DataStore/Tango.DataStore/IDataStoreManager.cs | 28 ++++ .../Tango.DataStore/Properties/AssemblyInfo.cs | 7 + .../Tango.DataStore/Tango.DataStore.csproj | 78 ++++++++++ .../DataStore/Tango.DataStore/packages.config | 5 + 10 files changed, 562 insertions(+) create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/DataType.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/ExtensionMethods.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreCollection.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreItem.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreManager.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/Tango.DataStore.csproj create mode 100644 Software/Visual_Studio/DataStore/Tango.DataStore/packages.config (limited to 'Software/Visual_Studio/DataStore/Tango.DataStore') diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs new file mode 100644 index 000000000..0ca8e484e --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreHelper.cs @@ -0,0 +1,160 @@ +using Google.Protobuf; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.ExtensionMethods; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.DataStore +{ + /// + /// Contains data store helper methods. + /// + public static class DataStoreHelper + { + /// + /// Gets the data store data type by the specified object type. + /// + /// The value. + /// + public static DataType GetDataType(Object value) + { + return GetDataType(value.GetType()); + } + + /// + /// Gets data store data type by the specified .net type. + /// + /// The type. + /// + /// + public static DataType GetDataType(Type type) + { + if (type == typeof(int)) + { + return DataType.Int32; + } + else if (type == typeof(Int64)) + { + return DataType.Int32; + } + else if (type == typeof(float)) + { + return DataType.Float; + } + else if (type == typeof(double)) + { + return DataType.Double; + } + else if (type == typeof(String)) + { + return DataType.String; + } + else if (type == typeof(bool)) + { + return DataType.Boolean; + } + else if (type == typeof(byte[])) + { + return DataType.Bytes; + } + else if (type == typeof(DataStoreProtoObject)) + { + return DataType.Proto; + } + else if (typeof(IMessage).IsAssignableFrom(type)) + { + return DataType.Proto; + } + + throw new NotSupportedException($"The specified type '{type.Name}' is not supported by the data store."); + } + + /// + /// Formats the data store item as a string. + /// + /// The item. + /// + public static String FormatDataStoreItem(IDataStoreItem item) + { + if (item.Type == DataType.Bytes) + { + return GetByteArrayHexString((byte[])item.Value); + } + else if (item.Type == DataType.Proto) + { + return (item.Value as DataStoreProtoObject).Message.ToJsonString(); + } + else + { + return item.Value.ToStringSafe(); + } + } + + /// + /// Returns a byte array string representation in hex format. + /// + /// The data. + /// + public static String GetByteArrayHexString(byte[] data) + { + StringBuilder hex = new StringBuilder(); + foreach (byte b in data) + { + hex.Append(b.ToString("X2") + " "); + } + return hex.ToString(); + } + + /// + /// Parses a data store value from a string. + /// + /// The type. + /// The string. + /// Type of the proto message (if type is Proto). + /// + /// No PMR message type specified. + /// The specified data store type is not supported. + public static Object ParseDataStoreValue(DataType type, String text, MessageType? protoMessageType = null) + { + switch (type) + { + case DataType.String: + return text; + case DataType.Int32: + return int.Parse(text); + case DataType.Float: + return float.Parse(text); + case DataType.Double: + return double.Parse(text); + case DataType.Boolean: + return bool.Parse(text); + case DataType.Proto: + if (protoMessageType == null) throw new ArgumentNullException("No PMR message type specified."); + var messageType = MessageFactory.GetPMRTypeFromMessageType(protoMessageType.Value); + var instance = Activator.CreateInstance(messageType) as IMessage; + instance = instance.GetParser().ParseJson(text); + return DataStoreProtoObject.FromMessage(instance); + case DataType.Bytes: + string[] hexValuesSplit = text.Split(' '); + List bytes = new List(); + foreach (string hex in hexValuesSplit) + { + if (hex.IsNotNullOrEmpty()) + { + byte b = (byte)Convert.ToInt32(hex.Trim(), 16); + bytes.Add(b); + } + } + return bytes.ToArray(); + } + + throw new NotSupportedException("The specified data store type is not supported."); + } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs new file mode 100644 index 000000000..5aa7c5342 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/DataStoreProtoObject.cs @@ -0,0 +1,83 @@ +using Google.Protobuf; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Bson; +using Tango.Core.ExtensionMethods; +using Tango.PMR; +using Tango.PMR.Common; +using Tango.PMR.DataStore; + +namespace Tango.DataStore +{ + public class DataStoreProtoObject + { + public MessageType MessageType { get; set; } + public Type Type { get; set; } + public byte[] Data { get; set; } + + + private IMessage _message; + [JsonIgnore] + public IMessage Message + { + get + { + if (_message == null) + { + _message = MessageFactory.ParseProtoMessage(Data, Type); + } + + return _message; + } + private set { _message = value; } + } + + public byte[] ToBytes() + { + return BsonConvert.Serialize(this); + } + + public static DataStoreProtoObject FromBytes(byte[] data) + { + var instance = BsonConvert.Deserialize(data); + instance.Message = MessageFactory.ParseProtoMessage(instance.Data, instance.Type); + + return instance; + } + + public static DataStoreProtoObject FromMessage(IMessage message) + { + DataStoreProtoObject proto = new DataStoreProtoObject(); + proto.Type = message.GetType(); + proto.MessageType = MessageFactory.ParseMessageType(proto.Type.Name); + proto.Data = message.ToByteArray(); + proto.Message = message; + return proto; + } + + public static DataStoreProtoObject FromJObject(JObject obj) + { + return (obj.ToObject()); + } + + public static DataStoreProtoObject FromPMRDataStoreItem(DataStoreItem item) + { + DataStoreProtoObject proto = new DataStoreProtoObject(); + proto.MessageType = item.ProtoType; + proto.Type = MessageFactory.GetPMRTypeFromMessageType(item.ProtoType); + proto.Data = item.BytesValue.ToByteArray(); + return proto; + } + + public override string ToString() + { + return Message?.ToJsonString(); + } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/DataType.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/DataType.cs new file mode 100644 index 000000000..132bff28e --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/DataType.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore +{ + /// + /// Represents a data store item type. + /// + public enum DataType + { + Int32, + Float, + Double, + Boolean, + String, + Bytes, + Proto + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/ExtensionMethods.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/ExtensionMethods.cs new file mode 100644 index 000000000..acc381a61 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/ExtensionMethods.cs @@ -0,0 +1,16 @@ +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.DataStore; + +public static class ExtensionMethods +{ + public static DataStoreProtoObject ToDataStoreProtoObject(IMessage message) + { + return DataStoreProtoObject.FromMessage(message); + } +} + diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreCollection.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreCollection.cs new file mode 100644 index 000000000..baca95c67 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreCollection.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore +{ + /// + /// Represents a data store collection. + /// + public interface IDataStoreCollection + { + /// + /// Gets the collection name. + /// + String Name { get; } + + /// + /// Upserts the specified key and value. + /// + /// The key. + /// The value. + void Put(String key, Object value); + + /// + /// Upserts the specified key and value of type T. + /// + /// + /// The key. + /// The value. + void Put(String key, T value); + + /// + /// Upserts the specified key and value. + /// The value must be of the specified DataType. + /// + /// The key. + /// The type. + /// The value. + void Put(String key, DataType type, Object value); + + /// + /// Gets the value by the specified key + /// + /// The key. + /// + Object Get(String key); + + /// + /// Gets the value by the specified key + /// + /// The key. + /// Will execute put when the key was not found. + /// + Object Get(String key, Object defaultValue); + + /// + /// Gets the value of type T by the specified key + /// + /// + /// The key. + /// + T Get(String key); + + /// + /// Gets the value of type T by the specified key + /// + /// + /// The key. + /// Will execute put when the key was not found. + /// + T Get(String key, T defaultValue); + + /// + /// Gets the full data store item by the specified key. + /// + /// The key. + /// + IDataStoreItem GetItem(String key); + + /// + /// Gets the full data store item by the specified key. + /// + /// The key. + /// Will execute put when the key was not found. + /// + IDataStoreItem GetItem(String key, Object defaultValue); + + /// + /// Gets all the data store items in the collection. + /// + /// + List GetAll(); + + /// + /// Gets all the data store unsynchronized items in the collection. + /// + /// + List GetUnsynchronized(); + + /// + /// Deleted an item by the specified key. + /// + /// The key. + void Delete(String key); + + /// + /// Deletes all items in the collection. + /// + void DeleteAll(); + + /// + /// Returns the number of items in the collection. + /// + /// + int Count(); + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreItem.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreItem.cs new file mode 100644 index 000000000..9c03f40ee --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreItem.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore +{ + /// + /// Represents a data store item. + /// + public interface IDataStoreItem + { + /// + /// Gets or sets the unique identifier (Use only for synchronization). + /// + String Guid { get; set; } + + /// + /// Gets or sets item id. + /// + String Key { get; set; } + + /// + /// Gets or sets the item type. + /// + DataType Type { get; set; } + + /// + /// Gets or sets the item value. + /// + Object Value { get; set; } + + /// + /// Gets or sets the item update UTC date. + /// + DateTime Date { get; set; } + + /// + /// Gets or sets a value indicating whether this item is synchronized with the remote service. + /// + bool IsSynchronized { get; set; } + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreManager.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreManager.cs new file mode 100644 index 000000000..5443f12e2 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/IDataStoreManager.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore +{ + /// + /// Represents a key/value data store manager. + /// + /// + public interface IDataStoreManager : IDisposable + { + /// + /// Gets the data store collection by name. + /// + /// The name. + /// + IDataStoreCollection GetCollection(String name); + + /// + /// Gets all the collection names. + /// + /// + List GetCollectionNames(); + } +} diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/Properties/AssemblyInfo.cs b/Software/Visual_Studio/DataStore/Tango.DataStore/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..8e9365e03 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Data Store Library")] +[assembly: AssemblyVersion("2.0.4.1608")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/Tango.DataStore.csproj b/Software/Visual_Studio/DataStore/Tango.DataStore/Tango.DataStore.csproj new file mode 100644 index 000000000..d75d39963 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/Tango.DataStore.csproj @@ -0,0 +1,78 @@ + + + + + Debug + AnyCPU + {E0364DFA-0721-4637-9D32-9D22AAC109D6} + Library + Properties + Tango.DataStore + Tango.DataStore + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\Tango.DataStore.xml + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Tango.DataStore.xml + + + + ..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + GlobalVersionInfo.cs + + + + + + + + + + + + + + + + {A34EE0F0-649D-41C8-8489-B6F1CC6924EE} + Tango.Core + + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/DataStore/Tango.DataStore/packages.config b/Software/Visual_Studio/DataStore/Tango.DataStore/packages.config new file mode 100644 index 000000000..026e719c3 --- /dev/null +++ b/Software/Visual_Studio/DataStore/Tango.DataStore/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file -- cgit v1.3.1