#25: file handler now only handles files

pull/27/head
Simon G 5 years ago
parent c433add6f0
commit ca6c75be23
  1. 17
      GBase/FileHandling/Exceptions/FileNotExistingException.cs
  2. 108
      GBase/FileHandling/FileHandler.cs
  3. 32
      GBase/FileHandling/GBaseFile.cs
  4. 48
      GBase/Interfaces/FileHandling/IFileHandler.cs
  5. 19
      GBase/Interfaces/FileHandling/IGBaseFile.cs

@ -0,0 +1,17 @@
// Author: Gockner, Simon
// Created: 2020-11-10
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
namespace GBase.FileHandling.Exceptions
{
public class FileNotExistingException<T> : Exception
{
public FileNotExistingException()
: base($"File for the given type {typeof(T)} is not existing.")
{
}
}
}

@ -2,15 +2,13 @@
// Created: 2020-02-12
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using GBase.FileHandling.Exceptions;
using GBase.Interfaces;
using GBase.Interfaces.DataHandling;
using GBase.Interfaces.DataHandling.Pool;
using GBase.Interfaces.FileHandling;
namespace GBase.FileHandling
@ -18,26 +16,22 @@ namespace GBase.FileHandling
/// <summary>
/// Internal file handler
/// </summary>
public class FileHandler : IFileHandler //TODO: Don't let file handler call data handler, have them parallel and have file handler only handle the files. this also makes more sense with the dataHandlerPool
public class FileHandler : IFileHandler
{
/// <summary>
/// The file extension for all GBase tables
/// </summary>
public const string GBASE_TABLE_FILE_EXTENSION = "gb";
private readonly IDataHandlerPool _dataHandlerPool;
private readonly List<IGBaseFile> _files;
private string _path;
private readonly List<(object entry, FileStream file, string filePath, bool inUse)> _files;
/// <summary>
/// Internal file handler
/// </summary>
/// <param name="dataHandlerPool">The <see cref="IDataHandlerPool"/></param>
public FileHandler(IDataHandlerPool dataHandlerPool)
public FileHandler()
{
_dataHandlerPool = dataHandlerPool;
_files = new List<(object entry, FileStream file, string filePath, bool inUse)>();
_files = new List<IGBaseFile>();
}
/// <summary>
@ -52,7 +46,7 @@ namespace GBase.FileHandling
return true; //TODO: is there anything that needs to be initialized here?
}
public async Task AddEntry<T>(T entry, IGBaseTable table, CancellationToken cancellationToken)
public IGBaseFile CreateEntryFile<T>(T entry, IGBaseTable table)
{
string directoryPath = Path.Combine(_path, table.FolderName);
@ -63,86 +57,50 @@ namespace GBase.FileHandling
string filePath = $"{Path.Combine(directoryPath, entry.ToString())}.{GBASE_TABLE_FILE_EXTENSION}";
FileStream entryFile = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); //TODO: Stream has to be disposed
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.AddEntry(entry, table, entryFile, cancellationToken);
_files.Add((entry, entryFile, filePath, false));
IGBaseFile file = new GBaseFile(entry, entryFile, filePath);
_files.Add(file);
return file.UseFile();
}
public async Task<bool> RemoveEntry<T>(T entry)
public async Task<bool> DeleteEntryFile<T>(T entry)
{
var file = _files.FirstOrDefault(f => f.entry.Equals(entry));
IGBaseFile file = _files.FirstOrDefault(f => f.Entry.Equals(entry));
if (file == default)
return false;
await file.file.DisposeAsync();
File.Delete(file.filePath);
await file.File.DisposeAsync();
File.Delete(file.FilePath);
return true;
}
/// <summary>
/// Set 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="entry"></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>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken)
public async Task<IGBaseFile> RequestEntryFile<T>(T entry)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.SetValue<T, TProperty>(TODO, propertyName, value, 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="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, CancellationToken cancellationToken)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.RemoveValue<T, TProperty>(TODO, propertyName, value, cancellationToken);
}
IGBaseFile file = _files.FirstOrDefault(f => f.Entry.Equals(entry));
if (file == default)
throw new FileNotExistingException<T>();
/// <summary>
/// Get the value for the given property, if multiple values are set the first is returned
/// </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="propertyName">The name of the property</param>
/// <param name="cancellationToken"></param>
/// <returns>The value for the given property</returns>
public async Task<TProperty> GetValue<T, TProperty>(string propertyName, CancellationToken cancellationToken)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
return await dataHandler.GetValue<T, TProperty>(propertyName);
}
if (file.InUse)
await Task.Delay(1000);
/// <summary>
/// Get all the values that are set 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="propertyName">The name of the property</param>
/// <param name="cancellationToken"></param>
/// <returns>An <see cref="IEnumerable{T}"/> with all the values for the property</returns>
public async Task<IEnumerable<TProperty>> GetValues<T, TProperty>(string propertyName, CancellationToken cancellationToken)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
return await dataHandler.GetValues<T, TProperty>(propertyName);
return file.UseFile();
}
/// <summary>
/// Dispose used resources asynchronously
/// </summary>
/// <returns>A <see cref="ValueTask"/> to await</returns>
public async ValueTask DisposeAsync() => await _dataHandlerPool.DisposeAsync();
public async ValueTask DisposeAsync()
{
while (_files.Any(f => f.InUse))
{
await Task.Delay(1000);
}
foreach (var file in _files)
{
await file.File.DisposeAsync();
}
}
}
}

@ -0,0 +1,32 @@
// Author: Gockner, Simon
// Created: 2020-11-10
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System.IO;
using GBase.Interfaces.FileHandling;
namespace GBase.FileHandling
{
public class GBaseFile : IGBaseFile
{
public GBaseFile(object entry, FileStream file, string filePath)
{
Entry = entry;
File = file;
FilePath = filePath;
}
public object Entry { get; }
public FileStream File { get; }
public string FilePath { get; }
public bool InUse { get; private set; }
public IGBaseFile UseFile()
{
InUse = true;
return this;
}
public void Dispose() => InUse = false;
}
}

@ -3,7 +3,6 @@
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -22,51 +21,10 @@ namespace GBase.Interfaces.FileHandling
/// <returns>True if successful, false if not</returns>
Task<bool> Init(string path, CancellationToken cancellationToken);
Task AddEntry<T>(T entry, IGBaseTable table, CancellationToken cancellationToken);
IGBaseFile CreateEntryFile<T>(T entry, IGBaseTable table);
Task<bool> RemoveEntry<T>(T entry);
Task<bool> DeleteEntryFile<T>(T entry);
/// <summary>
/// Set 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="entry"></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>(T entry, 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="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, CancellationToken cancellationToken);
/// <summary>
/// Get the value for the given property, if multiple values are set the first is returned
/// </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="propertyName">The name of the property</param>
/// <param name="cancellationToken"></param>
/// <returns>The value for the given property</returns>
Task<TProperty> GetValue<T, TProperty>(string propertyName, CancellationToken cancellationToken);
/// <summary>
/// Get all the values that are set 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="propertyName">The name of the property</param>
/// <param name="cancellationToken"></param>
/// <returns>An <see cref="IEnumerable{T}"/> with all the values for the property</returns>
Task<IEnumerable<TProperty>> GetValues<T, TProperty>(string propertyName, CancellationToken cancellationToken);
Task<IGBaseFile> RequestEntryFile<T>(T entry);
}
}

@ -0,0 +1,19 @@
// Author: Gockner, Simon
// Created: 2020-11-10
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.IO;
namespace GBase.Interfaces.FileHandling
{
public interface IGBaseFile : IDisposable
{
object Entry { get; }
FileStream File { get; }
string FilePath { get; }
bool InUse { get; }
IGBaseFile UseFile();
}
}
Loading…
Cancel
Save