diff --git a/GBase/DataHandling/XmlDataHandler.cs b/GBase/DataHandling/XmlDataHandler.cs index 83de8eb..b61a2dd 100644 --- a/GBase/DataHandling/XmlDataHandler.cs +++ b/GBase/DataHandling/XmlDataHandler.cs @@ -67,20 +67,15 @@ namespace GBase.DataHandling /// Initialize the /// /// If true an existing value is overwritten, if false an additional value is added - /// A to cancel the async operation /// Returns true if successful, false if not - public async Task Init(bool overwrite, CancellationToken cancellationToken) + public bool Init(bool overwrite) { if (_isInitialized) return false; _overwrite = overwrite; - if (!await _xmlDataReader.Init(cancellationToken)) - return false; - _isInitialized = true; - return true; } @@ -168,11 +163,13 @@ namespace GBase.DataHandling /// /// The that implements the property /// The of the property + /// /// The name of the property + /// /// The value for the given property - public async Task GetValue(string propertyName) + public async Task GetValue(FileStream file, string propertyName, CancellationToken cancellationToken) { - IEnumerable enumerable = await GetValues(propertyName); + IEnumerable enumerable = await GetValues(file, propertyName, cancellationToken); return enumerable == null ? default : enumerable.FirstOrDefault(); } @@ -181,24 +178,17 @@ namespace GBase.DataHandling /// /// The that implements the property /// The of the property + /// /// The name of the property + /// /// An with all the values for the property - public async Task> GetValues(string propertyName) + public async Task> GetValues(FileStream file, string propertyName, CancellationToken cancellationToken) { IEnumerable cachedValues = await _cache.TryGetValues(propertyName); if (cachedValues != null) return cachedValues; - return await _xmlDataReader.Read(propertyName); - } - - /// - /// Dispose used resources asynchronously - /// - /// A to await - public async ValueTask DisposeAsync() - { - await _xmlDataReader.DisposeAsync(); + return await _xmlDataReader.Read(file, propertyName, cancellationToken); } } } \ No newline at end of file diff --git a/GBase/DataHandling/XmlDataReader.cs b/GBase/DataHandling/XmlDataReader.cs index 03b7396..e83ba65 100644 --- a/GBase/DataHandling/XmlDataReader.cs +++ b/GBase/DataHandling/XmlDataReader.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; +using GBase.DataHandling.Exceptions; using GBase.Helpers; using GBase.Interfaces.DataHandling; using GBase.Interfaces.DataHandling.Xml; @@ -21,65 +22,34 @@ namespace GBase.DataHandling /// public class XmlDataReader : IXmlDataReader { - private readonly FileStream _file; - private XDocument _xmlDocument; - private XElement _rootElement; - - private bool _isInitialized; - private CancellationToken _cancellationToken; - - /// - /// A that reads from a xml file - /// - /// The path to the xml file - public XmlDataReader(string path) - { - _file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - } - - /// - /// Initialize the - /// - /// A to cancel the async operation - /// Returns true if successful, false if not - /// No root element found - public async Task Init(CancellationToken cancellationToken) - { - if (_isInitialized) - return false; - - _cancellationToken = cancellationToken; - _xmlDocument = await XDocument.LoadAsync(_file, LoadOptions.None, _cancellationToken); - - _rootElement = _xmlDocument.Root; - if (_rootElement == null) - throw new Exception("No root element found."); - - _isInitialized = true; - - return true; - } - /// /// Read the data of a property /// /// The /// The of the property + /// /// The name of the property + /// /// The data of the given property, null if no data found /// /// Invalid found for the read object - public async Task> Read(string propertyName) + public async Task> Read(FileStream file, string propertyName, CancellationToken cancellationToken) //TODO: Read currently doesn't work for newly added items -> probably because file was loaded before new items were added; is probably not a problem -> cache { string typeName = typeof(T).FullName; if (typeName == null) throw new ArgumentNullException(nameof(typeName)); + XDocument xmlDocument = await XDocument.LoadAsync(file, LoadOptions.None, cancellationToken); + file.Seek(0, SeekOrigin.Begin); //reset stream to it's beginning to be able to save it + return await Task.Run(() => { - XElement typeElement = _rootElement.Element(typeName); - XElement propertyElement = typeElement?.Element(propertyName); + XElement rootElement = xmlDocument.Root; + if (rootElement == null) + throw new InvalidXmlFileException("No root element is set."); + + XElement propertyElement = rootElement.Element(propertyName); XAttribute propertyTypeAttribute = propertyElement?.Attribute(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME); if (propertyTypeAttribute == null) return null; @@ -98,16 +68,7 @@ namespace GBase.DataHandling return values.Select(Enumerables.ConvertToGBaseEnumerable).ToList(); return values.Select(value => (TProperty)Convert.ChangeType(value, typeof(TProperty))).ToList(); - }, _cancellationToken); - } - - /// - /// Dispose used resources asynchronously - /// - /// A to await - public async ValueTask DisposeAsync() - { - await _file.DisposeAsync(); + }, cancellationToken); } } } \ No newline at end of file diff --git a/GBase/Interfaces/DataHandling/IDataHandler.cs b/GBase/Interfaces/DataHandling/IDataHandler.cs index 7ff4d30..afab835 100644 --- a/GBase/Interfaces/DataHandling/IDataHandler.cs +++ b/GBase/Interfaces/DataHandling/IDataHandler.cs @@ -13,15 +13,14 @@ namespace GBase.Interfaces.DataHandling /// /// Interface for data handlers to implement /// - public interface IDataHandler : IAsyncDisposable + public interface IDataHandler { /// /// Initialize the /// /// If true an existing value is overwritten, if false an additional value is added - /// A to cancel the async operation /// Returns true if successful, false if not - Task Init(bool overwrite, CancellationToken cancellationToken); + bool Init(bool overwrite); Task AddEntry(T entry, IGBaseTable table, FileStream entryFile, CancellationToken cancellationToken); @@ -37,8 +36,7 @@ namespace GBase.Interfaces.DataHandling /// The value to set /// /// A to await - Task SetValue(FileStream entryFile, string propertyName, TProperty value, - CancellationToken cancellationToken); + Task SetValue(FileStream entryFile, string propertyName, TProperty value, CancellationToken cancellationToken); /// /// Remove the value for the given property @@ -50,25 +48,28 @@ namespace GBase.Interfaces.DataHandling /// The value to set /// /// A to await - Task RemoveValue(FileStream entryFile, string propertyName, TProperty value, - CancellationToken cancellationToken); + Task RemoveValue(FileStream entryFile, string propertyName, TProperty value, CancellationToken cancellationToken); /// /// Get the value for the given property, if multiple values are set the first is returned /// /// The of the property /// The of the property + /// /// The name of the property + /// /// The value for the given property - Task GetValue(string propertyName); + Task GetValue(FileStream file, string propertyName, CancellationToken cancellationToken); /// /// Get all the values that are set for the given property /// /// The of the property /// The of the property + /// /// The name of the property + /// /// An with all the values for the property - Task> GetValues(string propertyName); + Task> GetValues(FileStream file, string propertyName, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/GBase/Interfaces/DataHandling/IDataReader.cs b/GBase/Interfaces/DataHandling/IDataReader.cs index e6d34da..cacdfb5 100644 --- a/GBase/Interfaces/DataHandling/IDataReader.cs +++ b/GBase/Interfaces/DataHandling/IDataReader.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading; using System.Threading.Tasks; @@ -12,22 +13,17 @@ namespace GBase.Interfaces.DataHandling /// /// Interface for data readers to implement /// - public interface IDataReader : IAsyncDisposable + public interface IDataReader { - /// - /// Initialize the - /// - /// A to cancel the async operation - /// Returns true if successful, false if not - Task Init(CancellationToken cancellationToken); - /// /// Read the data of a property /// /// The /// The of the property + /// /// The name of the property + /// /// The data of the given property, null if no data found - Task> Read(string propertyName); + Task> Read(FileStream file, string propertyName, CancellationToken cancellationToken); } } \ No newline at end of file