#25: adapt XmlDataHandler

pull/27/head
Simon G 5 years ago
parent 84d98a5dee
commit 1cfa80c199
  1. 25
      GBase/DataHandling/XmlDataHandler.cs
  2. 20
      GBase/DataHandling/XmlDataWriter.cs
  3. 2
      GBase/Factories/IGBaseColumnFactory.cs
  4. 4
      GBase/FileHandling/FileHandler.cs
  5. 6
      GBase/GBaseColumn.cs
  6. 2
      GBase/GBaseTable.cs
  7. 10
      GBase/Interfaces/DataHandling/IDataHandler.cs
  8. 13
      GBase/Interfaces/DataHandling/IDataWriter.cs
  9. 2
      GBase/Interfaces/IGBaseColumn.cs
  10. 4
      Test.GBase/DataHandling/XmlDataHandlerLocalIntegrationTest.cs
  11. 18
      Test.GBase/DataHandling/XmlDataHandlerTest.cs

@ -7,6 +7,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using GBase.DataHandling.Cache.Factories;
@ -91,6 +92,17 @@ namespace GBase.DataHandling
foreach (var column in table.Columns)
{
//TODO: Set value for each column
PropertyInfo property = entry.GetType().GetProperty(column.Name);
if (property == null)
continue; //TODO: What to do in this case? (Shouldn't really happen...)
string valueString;
if (property.PropertyType != typeof(string) && property.GetValue(entry) is IEnumerable enumerable)
valueString = enumerable.ToGBaseString();
else
valueString = property.GetValue(entry).ToString();
await _xmlDataWriter.Write<T>(entryFile, property.Name, valueString, property.PropertyType, _overwrite, cancellationToken);
}
return true;
@ -106,10 +118,12 @@ namespace GBase.DataHandling
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> that implements the property</typeparam>
/// <typeparam name="TProperty">The <see cref="Type"/> of the property</typeparam>
/// <param name="entryFile"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value to set</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
public async Task SetValue<T, TProperty>(string propertyName, TProperty value)
public async Task SetValue<T, TProperty>(FileStream entryFile, string propertyName, TProperty value, CancellationToken cancellationToken)
{
if (value == null)
return;
@ -121,7 +135,7 @@ namespace GBase.DataHandling
valueString = value.ToString();
await _cache.SetValue<T, TProperty>(propertyName, value, _overwrite);
await _xmlDataWriter.Write<T, TProperty>(TODO, propertyName, valueString, _overwrite, TODO);
await _xmlDataWriter.Write<T, TProperty>(entryFile, propertyName, valueString, _overwrite, cancellationToken);
}
/// <summary>
@ -129,10 +143,12 @@ namespace GBase.DataHandling
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the property</typeparam>
/// <typeparam name="TProperty">The <see cref="Type"/> of the property</typeparam>
/// <param name="entryFile"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value to set</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
public async Task RemoveValue<T, TProperty>(string propertyName, TProperty value)
public async Task RemoveValue<T, TProperty>(FileStream entryFile, string propertyName, TProperty value, CancellationToken cancellationToken)
{
if (value == null)
return;
@ -144,7 +160,7 @@ namespace GBase.DataHandling
valueString = value.ToString();
await _cache.TryRemoveValue<T, TProperty>(propertyName, value);
await _xmlDataWriter.Remove<T, TProperty>(TODO, propertyName, valueString, TODO);
await _xmlDataWriter.Remove<T, TProperty>(entryFile, propertyName, valueString, cancellationToken);
}
/// <summary>
@ -183,7 +199,6 @@ namespace GBase.DataHandling
public async ValueTask DisposeAsync()
{
await _xmlDataReader.DisposeAsync();
await _xmlDataWriter.DisposeAsync();
}
}
}

@ -44,7 +44,7 @@ namespace GBase.DataHandling
/// <summary>
/// Write the data of a property
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> that implements the property</typeparam>
/// <typeparam name="T">The <see cref="Type"/></typeparam>
/// <typeparam name="TProperty">The <see cref="Type"/> of the property</typeparam>
/// <param name="file"></param>
/// <param name="propertyName">The name of the property</param>
@ -52,9 +52,23 @@ namespace GBase.DataHandling
/// <param name="overwrite">If true an existing value is overwritten, if false an additional value is added</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
public async Task Write<T, TProperty>(FileStream file, string propertyName, string value, bool overwrite, CancellationToken cancellationToken) =>
await Write<T>(file, propertyName, value, typeof(TProperty), overwrite, cancellationToken);
/// <summary>
/// Write the data of a property
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> that implements the property</typeparam>
/// <param name="file"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value of the property</param>
/// <param name="propertyType"></param>
/// <param name="overwrite">If true an existing value is overwritten, if false an additional value is added</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
/// <exception cref="ArgumentNullException"><paramref name="propertyName"/></exception>
/// <exception cref="InvalidXmlFileException">No root element is set</exception>
public async Task Write<T, TProperty>(FileStream file, string propertyName, string value, bool overwrite, CancellationToken cancellationToken)
public async Task Write<T>(FileStream file, string propertyName, string value, Type propertyType, bool overwrite, CancellationToken cancellationToken)
{
string typeName = typeof(T).FullName;
if (typeName == null)
@ -87,7 +101,7 @@ namespace GBase.DataHandling
else //property element doesn't exist
{
propertyElement = new XElement(propertyName, new XElement(XmlDataHandler.VALUE_ELEMENT_NAME) { Value = value }); //create the new property element with the value element
propertyElement.SetAttributeValue(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME, typeof(TProperty).FullName); //add the property type attribute
propertyElement.SetAttributeValue(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME, propertyType.FullName); //add the property type attribute
rootElement.Add(propertyElement); //create new property element with the value element
}

@ -16,6 +16,6 @@ namespace GBase.Factories
/// Creates an <see cref="IGBaseColumn"/>
/// </summary>
/// <returns>A newly created instance of the implementation for <see cref="IGBaseColumn"/></returns>
IGBaseColumn Create();
IGBaseColumn Create(string name);
}
}

@ -81,7 +81,7 @@ namespace GBase.FileHandling
public async Task SetValue<T, TProperty>(string propertyName, TProperty value, CancellationToken cancellationToken)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.SetValue<T, TProperty>(propertyName, value);
await dataHandler.SetValue<T, TProperty>(TODO, propertyName, value, cancellationToken);
}
/// <summary>
@ -96,7 +96,7 @@ namespace GBase.FileHandling
public async Task RemoveValue<T, TProperty>(string propertyName, TProperty value, CancellationToken cancellationToken)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.RemoveValue<T, TProperty>(propertyName, value);
await dataHandler.RemoveValue<T, TProperty>(TODO, propertyName, value, cancellationToken);
}
/// <summary>

@ -16,11 +16,13 @@ namespace GBase
/// <summary>
/// A column of a <see cref="IGBaseTable"/>
/// </summary>
public GBaseColumn()
public GBaseColumn(string name)
{
Name = name;
}
public string Name { get; }
/// <summary>
/// The <see cref="IAsyncDisposable.DisposeAsync"/> method
/// </summary>

@ -80,7 +80,7 @@ namespace GBase
if (gBaseColumnAttribute == null)
continue;
IGBaseColumn gBaseColumn = _gBaseColumnFactory.Create();
IGBaseColumn gBaseColumn = _gBaseColumnFactory.Create(property.Name);
AddColumn(gBaseColumn);
}

@ -32,20 +32,26 @@ namespace GBase.Interfaces.DataHandling
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the property</typeparam>
/// <typeparam name="TProperty">The <see cref="Type"/> of the property</typeparam>
/// <param name="entryFile"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value to set</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
Task SetValue<T, TProperty>(string propertyName, TProperty value);
Task SetValue<T, TProperty>(FileStream entryFile, string propertyName, TProperty value,
CancellationToken cancellationToken);
/// <summary>
/// Remove the value for the given property
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> of the property</typeparam>
/// <typeparam name="TProperty">The <see cref="Type"/> of the property</typeparam>
/// <param name="entryFile"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value to set</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
Task RemoveValue<T, TProperty>(string propertyName, TProperty value);
Task RemoveValue<T, TProperty>(FileStream entryFile, string propertyName, TProperty value,
CancellationToken cancellationToken);
/// <summary>
/// Get the value for the given property, if multiple values are set the first is returned

@ -36,6 +36,19 @@ namespace GBase.Interfaces.DataHandling
/// <returns>A <see cref="Task"/> to await</returns>
Task Write<T, TProperty>(FileStream file, string propertyName, string value, bool overwrite, CancellationToken cancellationToken);
/// <summary>
/// Write the data of a property
/// </summary>
/// <typeparam name="T">The <see cref="Type"/></typeparam>
/// <param name="file"></param>
/// <param name="propertyName">The name of the property</param>
/// <param name="value">The value of the property</param>
/// <param name="propertyType"></param>
/// <param name="overwrite">If true an existing value is overwritten, if false an additional value is added</param>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="Task"/> to await</returns>
Task Write<T>(FileStream file, string propertyName, string value, Type propertyType, bool overwrite, CancellationToken cancellationToken);
/// <summary>
/// Remove the value for the given property
/// </summary>

@ -11,6 +11,6 @@ namespace GBase.Interfaces
/// </summary>
public interface IGBaseColumn : IAsyncDisposable //TODO: Make column generic (generic type is type of the value of the column?)?
{
string Name { get; }
}
}

@ -55,10 +55,10 @@ namespace Test.GBase.DataHandling
//
//await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, string>(nameof(TestProperty), TestProperty);
//await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, string>(nameof(TestProperty), "empty");
await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, string>(nameof(TestProperty), "test");
await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, string>(TODO, nameof(TestProperty), "test", TODO);
//await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, string>(nameof(TestProperty), "OverwrittenString");
//
await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, int>(nameof(TestInt), 1);
await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, int>(TODO, nameof(TestInt), 1, TODO);
//await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, int>(nameof(TestInt), 2);
//await xmlDataHandler.SetValue<XmlDataHandlerLocalIntegrationTest, int>(nameof(TestInt), 3);
TestProperty = await xmlDataHandler.GetValue<XmlDataHandlerLocalIntegrationTest, string>(nameof(TestProperty));

@ -137,10 +137,10 @@ namespace Test.GBase.DataHandling
XmlDataHandler xmlDataHandler = new XmlDataHandler("path", xmlDataReaderFactoryMock.Object,
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
await xmlDataHandler.SetValue<XmlDataHandlerTest, string>("property", "SomeString");
await xmlDataHandler.SetValue<XmlDataHandlerTest, string>(TODO, "property", "SomeString", TODO);
xmlDataHandlerCacheMock.Verify(c => c.SetValue<XmlDataHandlerTest, string>("property", "SomeString", false), Times.Once);
xmlDataWriterMock.Verify(w => w.Write<XmlDataHandlerTest, string>(TODO, "property", "SomeString", false, TODO), Times.Once);
xmlDataWriterMock.Verify(w => w.Write<XmlDataHandlerTest, string>(TODO, "property", "SomeString", TODO, false, TODO), Times.Once);
}
[Test]
@ -162,10 +162,10 @@ namespace Test.GBase.DataHandling
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
List<string> stringList = new List<string>() {"string", "secondString", "thirdString"};
await xmlDataHandler.SetValue<XmlDataHandlerTest, List<string>>("property", stringList);
await xmlDataHandler.SetValue<XmlDataHandlerTest, List<string>>(TODO, "property", stringList, TODO);
xmlDataHandlerCacheMock.Verify(c => c.SetValue<XmlDataHandlerTest, List<string>>("property", stringList, false), Times.Once);
xmlDataWriterMock.Verify(w => w.Write<XmlDataHandlerTest, List<string>>(TODO, "property", $"{stringList[0]},{stringList[1]},{stringList[2]}", false, TODO), Times.Once);
xmlDataWriterMock.Verify(w => w.Write<XmlDataHandlerTest, List<string>>(TODO, "property", $"{stringList[0]},{stringList[1]},{stringList[2]}", TODO, false, TODO), Times.Once);
}
[Test]
@ -186,10 +186,10 @@ namespace Test.GBase.DataHandling
XmlDataHandler xmlDataHandler = new XmlDataHandler("path", xmlDataReaderFactoryMock.Object,
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
await xmlDataHandler.SetValue<XmlDataHandlerTest, string>("property", null);
await xmlDataHandler.SetValue<XmlDataHandlerTest, string>(TODO, "property", null, TODO);
xmlDataHandlerCacheMock.Verify(c => c.SetValue<It.IsValueType, It.IsValueType>(It.IsAny<string>(), It.IsAny<It.IsValueType>(), It.IsAny<bool>()), Times.Never);
xmlDataWriterMock.Verify(w => w.Write<It.IsValueType, It.IsValueType>(TODO, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), TODO), Times.Never);
xmlDataWriterMock.Verify(w => w.Write<It.IsValueType, It.IsValueType>(TODO, It.IsAny<string>(), It.IsAny<string>(), TODO, It.IsAny<bool>(), TODO), Times.Never);
}
[Test]
@ -210,7 +210,7 @@ namespace Test.GBase.DataHandling
XmlDataHandler xmlDataHandler = new XmlDataHandler("path", xmlDataReaderFactoryMock.Object,
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, string>("property", "SomeString");
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, string>(TODO, "property", "SomeString", TODO);
xmlDataHandlerCacheMock.Verify(c => c.TryRemoveValue<XmlDataHandlerTest, string>("property", "SomeString"), Times.Once);
xmlDataWriterMock.Verify(w => w.Remove<XmlDataHandlerTest, string>(TODO, "property", "SomeString", TODO), Times.Once);
@ -235,7 +235,7 @@ namespace Test.GBase.DataHandling
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
List<string> stringList = new List<string>() { "string", "secondString", "thirdString" };
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, List<string>>("property", stringList);
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, List<string>>(TODO, "property", stringList, TODO);
xmlDataHandlerCacheMock.Verify(c => c.TryRemoveValue<XmlDataHandlerTest, List<string>>("property", stringList), Times.Once);
xmlDataWriterMock.Verify(w => w.Remove<XmlDataHandlerTest, List<string>>(TODO, "property", $"{stringList[0]},{stringList[1]},{stringList[2]}", TODO), Times.Once);
@ -259,7 +259,7 @@ namespace Test.GBase.DataHandling
XmlDataHandler xmlDataHandler = new XmlDataHandler("path", xmlDataReaderFactoryMock.Object,
xmlDataWriterFactoryMock.Object, xmlDataHandlerCacheFactoryMock.Object);
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, string>("property", null);
await xmlDataHandler.RemoveValue<XmlDataHandlerTest, string>(TODO, "property", null, TODO);
xmlDataHandlerCacheMock.Verify(c => c.TryRemoveValue<It.IsValueType, It.IsValueType>(It.IsAny<string>(), It.IsAny<It.IsValueType>()), Times.Never);
xmlDataWriterMock.Verify(w => w.Remove<It.IsValueType, It.IsValueType>(TODO, It.IsAny<string>(), It.IsAny<string>(), TODO), Times.Never);

Loading…
Cancel
Save