Improve data handling #25
master
Simon G 5 years ago committed by GitHub
commit af42ee3297
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      GBase.Api/IGBaseObject.cs
  2. 24
      GBase/Exceptions/GenericMethodNotFoundException.cs
  3. 3
      GBase/Factories/IGBaseColumnFactory.cs
  4. 27
      GBase/FileHandling/FileHandler.cs
  5. 2
      GBase/FileHandling/GBaseFile.cs
  6. 11
      GBase/GBase.cs
  7. 1
      GBase/GBase.csproj
  8. 75
      GBase/GBase.xml
  9. 4
      GBase/GBaseColumn.cs
  10. 4
      GBase/GBaseObject.cs
  11. 43
      GBase/GBaseTable.cs
  12. 108
      GBase/Helpers/GenericMethodCaller.cs
  13. 4
      GBase/Interfaces/FileHandling/IFileHandler.cs
  14. 2
      GBase/Interfaces/FileHandling/IGBaseFile.cs
  15. 11
      GBase/Interfaces/IGBase.cs
  16. 1
      GBase/Interfaces/IGBaseColumn.cs
  17. 2
      GBase/Interfaces/IGBaseTable.cs
  18. 9
      Test.GBase/GBaseIntegrationTest/Group.cs
  19. 12
      Test.GBase/GBaseIntegrationTest/Item.cs
  20. 12
      Test.GBase/GBaseIntegrationTest/Model.cs
  21. 5
      Test.GBase/GBaseTableIntegrationTest.cs
  22. 19
      Test.GBase/TestClasses/Foo.cs
  23. 6
      Test.GBase/TestClasses/UserType.cs

@ -2,6 +2,8 @@
// Created: 2020-02-14
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System.Collections.Generic;
namespace GBase.Api
{
/// <summary>
@ -14,5 +16,7 @@ namespace GBase.Api
/// </summary>
/// <param name="string">The given <see cref="string"/></param>
void InitializeFromString(string @string);
void Initialize(List<object> parameters);
}
}

@ -0,0 +1,24 @@
// Author: Gockner, Simon
// Created: 2020-11-13
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
namespace GBase.Exceptions
{
/// <summary>
/// Could not find generic method
/// </summary>
internal class GenericMethodNotFoundException : Exception
{
/// <summary>
/// Could not find generic method
/// </summary>
/// <param name="functionName">The name of the generic method</param>
public GenericMethodNotFoundException(string functionName)
: base($"Could not find function {functionName}")
{
}
}
}

@ -3,6 +3,7 @@
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using GBase.Interfaces;
namespace GBase.Factories
@ -16,6 +17,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(string name);
IGBaseColumn Create(string name, Type type);
}
}

@ -38,12 +38,26 @@ namespace GBase.FileHandling
/// Initialize this <see cref="IFileHandler"/>
/// </summary>
/// <param name="path">The path of the database</param>
/// <param name="folderName"></param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the asynchronous operation</param>
/// <returns>True if successful, false if not</returns>
public async Task<bool> Init(string path, CancellationToken cancellationToken)
public List<IGBaseFile> Init(string path, string folderName, CancellationToken cancellationToken)
{
_path = path;
return true; //TODO: initialize existing files
string directoryPath = Path.Combine(_path, folderName);
if (!Directory.Exists(directoryPath))
return null;
string[] files = Directory.GetFiles(directoryPath, $"*.{GBASE_TABLE_FILE_EXTENSION}");
foreach (var file in files)
{
FileStream entryFile = File.Open(file, FileMode.OpenOrCreate, FileAccess.ReadWrite);
_files.Add(new GBaseFile(null, entryFile, file));
}
return _files;
}
public IGBaseFile CreateEntryFile<T>(T entry, IGBaseTable table)
@ -55,9 +69,14 @@ namespace GBase.FileHandling
//create new entry file
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
IGBaseFile file = new GBaseFile(entry, entryFile, filePath);
//check if file is already opened
IGBaseFile file = _files.FirstOrDefault(f => f.FilePath.Equals(filePath));
if (file != null)
return file.UseFile();
FileStream entryFile = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
file = new GBaseFile(entry, entryFile, filePath);
_files.Add(file);
return file.UseFile();

@ -16,7 +16,7 @@ namespace GBase.FileHandling
FilePath = filePath;
}
public object Entry { get; }
public object Entry { get; set; }
public FileStream File { get; }
public string FilePath { get; }
public bool InUse { get; private set; }

@ -8,6 +8,7 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using GBase.Api;
using GBase.Attributes;
using GBase.Exceptions;
using GBase.Factories;
@ -96,7 +97,7 @@ namespace GBase
return true;
}
public IGBaseTable<T> GetTable<T>()
public IGBaseTable<T> GetTable<T>() where T : IGBaseObject, new()
{
if (Tables.OfType<IGBaseTable<T>>().Any())
return Tables.OfType<IGBaseTable<T>>().First();
@ -119,7 +120,7 @@ namespace GBase
return Tables.Remove(table);
}
public async Task<bool> AddEntry<T>(T entry, CancellationToken cancellationToken)
public async Task<bool> AddEntry<T>(T entry, CancellationToken cancellationToken) where T : IGBaseObject, new()
{
IGBaseTable<T> table = GetTable<T>();
if (table == null)
@ -128,7 +129,7 @@ namespace GBase
return await table.AddEntry(entry, cancellationToken);
}
public async Task SetValue<T, TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken)
public async Task SetValue<T, TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken) where T : IGBaseObject, new()
{
IGBaseTable<T> table = GetTable<T>();
if (table == null)
@ -137,7 +138,7 @@ namespace GBase
await table.SetValue(entry, propertyName, value, cancellationToken);
}
public async Task<TProperty> GetValue<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
public async Task<TProperty> GetValue<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken) where T : IGBaseObject, new()
{
IGBaseTable<T> table = GetTable<T>();
if (table == null)
@ -146,7 +147,7 @@ namespace GBase
return await table.GetValue<TProperty>(entry, propertyName, cancellationToken);
}
public async Task<IEnumerable<TProperty>> GetValues<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
public async Task<IEnumerable<TProperty>> GetValues<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken) where T : IGBaseObject, new()
{
IGBaseTable<T> table = GetTable<T>();
if (table == null)

@ -24,6 +24,7 @@
<ItemGroup>
<PackageReference Include="LightweightIocContainer" Version="2.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.5.0-beta2-final" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup>
<ItemGroup>

@ -334,6 +334,17 @@
<exception cref="T:System.ArgumentNullException"><paramref name="propertyName"/></exception>
<exception cref="T:GBase.DataHandling.Exceptions.InvalidXmlFileException">No root element is set</exception>
</member>
<member name="T:GBase.Exceptions.GenericMethodNotFoundException">
<summary>
Could not find generic method
</summary>
</member>
<member name="M:GBase.Exceptions.GenericMethodNotFoundException.#ctor(System.String)">
<summary>
Could not find generic method
</summary>
<param name="functionName">The name of the generic method</param>
</member>
<member name="T:GBase.Exceptions.InterfaceEnumerablePassedException">
<summary>
<see cref="T:System.Exception"/> that an interface was passed as the generic type of an <see cref="T:System.Collections.Generic.IEnumerable`1"/>
@ -395,7 +406,7 @@
Factory for the <see cref="T:GBase.Interfaces.IGBaseColumn"/>
</summary>
</member>
<member name="M:GBase.Factories.IGBaseColumnFactory.Create(System.String)">
<member name="M:GBase.Factories.IGBaseColumnFactory.Create(System.String,System.Type)">
<summary>
Creates an <see cref="T:GBase.Interfaces.IGBaseColumn"/>
</summary>
@ -450,11 +461,12 @@
Internal file handler
</summary>
</member>
<member name="M:GBase.FileHandling.FileHandler.Init(System.String,System.Threading.CancellationToken)">
<member name="M:GBase.FileHandling.FileHandler.Init(System.String,System.String,System.Threading.CancellationToken)">
<summary>
Initialize this <see cref="T:GBase.Interfaces.FileHandling.IFileHandler"/>
</summary>
<param name="path">The path of the database</param>
<param name="folderName"></param>
<param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken"/> to cancel the asynchronous operation</param>
<returns>True if successful, false if not</returns>
</member>
@ -525,7 +537,7 @@
A column of a <see cref="T:GBase.Interfaces.IGBaseTable"/>
</summary>
</member>
<member name="M:GBase.GBaseColumn.#ctor(System.String)">
<member name="M:GBase.GBaseColumn.#ctor(System.String,System.Type)">
<summary>
A column of a <see cref="T:GBase.Interfaces.IGBaseTable"/>
</summary>
@ -647,6 +659,60 @@
<returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:System.Type"/> <typeparamref name="TEnumerable"/></returns>
<exception cref="T:GBase.Exceptions.InterfaceEnumerablePassedException">Interface was passed to an <see cref="T:System.Collections.Generic.IEnumerable`1"/></exception>
</member>
<member name="M:GBase.Helpers.GenericMethodCaller.Call(System.Object,System.String,System.Reflection.BindingFlags,System.Type,System.Object[])">
<summary>
Call a generic method without generic type parameters
</summary>
<param name="caller">The caller of the method</param>
<param name="functionName">The name of the method to call</param>
<param name="bindingFlags">The <see cref="T:System.Reflection.BindingFlags"/> to find the method</param>
<param name="genericParameter">The generic parameter as <see cref="T:System.Type"/> parameter</param>
<param name="parameters">The parameters of the method</param>
<returns>The result of invoking the method</returns>
<exception cref="T:GBase.Exceptions.GenericMethodNotFoundException">Could not find the generic method</exception>
<exception cref="T:System.Exception">Any <see cref="T:System.Exception"/> thrown after invoking the generic method</exception>
</member>
<member name="M:GBase.Helpers.GenericMethodCaller.Call(System.Object,System.String,System.Reflection.BindingFlags,System.Type,System.Type,System.Object[])">
<summary>
Call a generic method without generic type parameters
</summary>
<param name="caller">The caller of the method</param>
<param name="functionName">The name of the method to call</param>
<param name="bindingFlags">The <see cref="T:System.Reflection.BindingFlags"/> to find the method</param>
<param name="genericParameter">The generic parameter as <see cref="T:System.Type"/> parameter</param>
<param name="secondGenericParameter"></param>
<param name="parameters">The parameters of the method</param>
<returns>The result of invoking the method</returns>
<exception cref="T:GBase.Exceptions.GenericMethodNotFoundException">Could not find the generic method</exception>
<exception cref="T:System.Exception">Any <see cref="T:System.Exception"/> thrown after invoking the generic method</exception>
</member>
<member name="M:GBase.Helpers.GenericMethodCaller.CallAsync(System.Object,System.String,System.Reflection.BindingFlags,System.Type,System.Object[])">
<summary>
Call a generic method asynchronously without generic type parameters
</summary>
<param name="caller">The caller of the method</param>
<param name="functionName">The name of the method to call</param>
<param name="bindingFlags">The <see cref="T:System.Reflection.BindingFlags"/> to find the method</param>
<param name="genericParameter">The generic parameter as <see cref="T:System.Type"/> parameter</param>
<param name="parameters">The parameters of the method</param>
<returns>The result of invoking the method</returns>
<exception cref="T:GBase.Exceptions.GenericMethodNotFoundException">Could not find the generic method</exception>
<exception cref="T:System.Exception">Any <see cref="T:System.Exception"/> thrown after invoking the generic method</exception>
</member>
<member name="M:GBase.Helpers.GenericMethodCaller.CallAsync(System.Object,System.String,System.Reflection.BindingFlags,System.Type,System.Type,System.Object[])">
<summary>
Call a generic method asynchronously without generic type parameters
</summary>
<param name="caller">The caller of the method</param>
<param name="functionName">The name of the method to call</param>
<param name="bindingFlags">The <see cref="T:System.Reflection.BindingFlags"/> to find the method</param>
<param name="genericParameter">The generic parameter as <see cref="T:System.Type"/> parameter</param>
<param name="secondGenericParameter"></param>
<param name="parameters">The parameters of the method</param>
<returns>The result of invoking the method</returns>
<exception cref="T:GBase.Exceptions.GenericMethodNotFoundException">Could not find the generic method</exception>
<exception cref="T:System.Exception">Any <see cref="T:System.Exception"/> thrown after invoking the generic method</exception>
</member>
<member name="T:GBase.Installers.DataHandlingInstaller">
<summary>
<see cref="T:LightweightIocContainer.Interfaces.Installers.IIocInstaller"/> for the data handling
@ -904,11 +970,12 @@
Internal file handler
</summary>
</member>
<member name="M:GBase.Interfaces.FileHandling.IFileHandler.Init(System.String,System.Threading.CancellationToken)">
<member name="M:GBase.Interfaces.FileHandling.IFileHandler.Init(System.String,System.String,System.Threading.CancellationToken)">
<summary>
Initialize this <see cref="T:GBase.Interfaces.FileHandling.IFileHandler"/>
</summary>
<param name="path">The path of the database</param>
<param name="folderName"></param>
<param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken"/> to cancel the asynchronous operation</param>
<returns>True if successful, false if not</returns>
</member>

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

@ -14,7 +14,7 @@ namespace GBase
/// <summary>
/// GBase object that supplies inheriting classes with methods to get data from a <see cref="IGBase"/>
/// </summary>
public abstract class GBaseObject<T> : IGBaseObject
public abstract class GBaseObject<T> : IGBaseObject where T : IGBaseObject, new()
{
private readonly IGBaseTable<T> _gBaseTable;
@ -43,5 +43,7 @@ namespace GBase
/// </summary>
/// <param name="string">The given <see cref="string"/></param>
public abstract void InitializeFromString(string @string);
public abstract void Initialize(List<object> parameters);
}
}

@ -12,6 +12,7 @@ using GBase.Api;
using GBase.Attributes;
using GBase.Factories;
using GBase.FileHandling.Factories;
using GBase.Helpers;
using GBase.Interfaces;
using GBase.Interfaces.DataHandling;
using GBase.Interfaces.DataHandling.Pool;
@ -22,7 +23,7 @@ namespace GBase
/// <summary>
/// A <see cref="IGBase"/> table
/// </summary>
public class GBaseTable<T> : IGBaseTable<T>
public class GBaseTable<T> : IGBaseTable<T> where T : IGBaseObject, new()
{
private readonly IFileHandler _fileHandler;
private readonly IDataHandlerPool _dataHandlerPool;
@ -74,11 +75,10 @@ namespace GBase
/// <param name="folderName"></param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the asynchronous operation</param>
/// <returns>True if successful, false if not</returns>
public async Task<bool> Init(Type type, string databasePath, string folderName, CancellationToken cancellationToken)
public async Task<bool> Init(Type type, string databasePath, string folderName, CancellationToken cancellationToken) //TODO: Remove bool return value?
{
Type = type;
FolderName = folderName;
await _fileHandler.Init(databasePath, cancellationToken);
//TODO: Init columns list depending on GBaseColumnAttributes set for this GBaseTable
foreach (var property in type.GetProperties())
@ -87,10 +87,39 @@ namespace GBase
if (gBaseColumnAttribute == null)
continue;
IGBaseColumn gBaseColumn = _gBaseColumnFactory.Create(property.Name);
IGBaseColumn gBaseColumn = _gBaseColumnFactory.Create(property.Name, property.PropertyType);
AddColumn(gBaseColumn);
}
List<IGBaseFile> files = _fileHandler.Init(databasePath, FolderName, cancellationToken);
if (files == null)
return true;
foreach (var file in files) //create entries for existing files
{
using (file.UseFile())
{
T entry = new T();
List<object> parameters = new List<object>();
foreach (var column in Columns)
{
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
parameters.Add(await GenericMethodCaller.CallAsync(dataHandler,
nameof(IDataHandler.GetValue),
BindingFlags.Public | BindingFlags.Instance,
typeof(T), column.Type,
file.File, column.Name, cancellationToken));
}
entry.Initialize(parameters);
file.Entry = entry;
Entries.Add(entry);
}
}
return true;
}
@ -156,21 +185,21 @@ namespace GBase
public async Task SetValue<TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken)
{
using IGBaseFile file = await _fileHandler.RequestEntryFile(entry);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, CancellationToken.None);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
await dataHandler.SetValue<T, TProperty>(file.File, propertyName, value, cancellationToken);
}
public async Task<TProperty> GetValue<TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
{
using IGBaseFile file = await _fileHandler.RequestEntryFile(entry);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, CancellationToken.None);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
return await dataHandler.GetValue<T, TProperty>(file.File, propertyName, cancellationToken);
}
public async Task<IEnumerable<TProperty>> GetValues<TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
{
using IGBaseFile file = await _fileHandler.RequestEntryFile(entry);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, CancellationToken.None);
IDataHandler dataHandler = await _dataHandlerPool.RequestDataHandler(this, false, cancellationToken);
return await dataHandler.GetValues<T, TProperty>(file.File, propertyName, cancellationToken);
}

@ -0,0 +1,108 @@
// Author: Gockner, Simon
// Created: 2020-11-13
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Reflection;
using System.Threading.Tasks;
using GBase.Exceptions;
namespace GBase.Helpers
{
internal static class GenericMethodCaller
{
/// <summary>
/// Call a generic method without generic type parameters
/// </summary>
/// <param name="caller">The caller of the method</param>
/// <param name="functionName">The name of the method to call</param>
/// <param name="bindingFlags">The <see cref="BindingFlags"/> to find the method</param>
/// <param name="genericParameter">The generic parameter as <see cref="Type"/> parameter</param>
/// <param name="parameters">The parameters of the method</param>
/// <returns>The result of invoking the method</returns>
/// <exception cref="GenericMethodNotFoundException">Could not find the generic method</exception>
/// <exception cref="Exception">Any <see cref="Exception"/> thrown after invoking the generic method</exception>
public static object Call(object caller, string functionName, BindingFlags bindingFlags, Type genericParameter, params object[] parameters) =>
GetGenericMethod(caller, functionName, bindingFlags, genericParameter).InvokeGenericMethod(caller, parameters);
/// <summary>
/// Call a generic method without generic type parameters
/// </summary>
/// <param name="caller">The caller of the method</param>
/// <param name="functionName">The name of the method to call</param>
/// <param name="bindingFlags">The <see cref="BindingFlags"/> to find the method</param>
/// <param name="genericParameter">The generic parameter as <see cref="Type"/> parameter</param>
/// <param name="secondGenericParameter"></param>
/// <param name="parameters">The parameters of the method</param>
/// <returns>The result of invoking the method</returns>
/// <exception cref="GenericMethodNotFoundException">Could not find the generic method</exception>
/// <exception cref="Exception">Any <see cref="Exception"/> thrown after invoking the generic method</exception>
public static object Call(object caller, string functionName, BindingFlags bindingFlags, Type genericParameter, Type secondGenericParameter,params object[] parameters) =>
GetGenericMethod(caller, functionName, bindingFlags, genericParameter, secondGenericParameter).InvokeGenericMethod(caller, parameters);
/// <summary>
/// Call a generic method asynchronously without generic type parameters
/// </summary>
/// <param name="caller">The caller of the method</param>
/// <param name="functionName">The name of the method to call</param>
/// <param name="bindingFlags">The <see cref="BindingFlags"/> to find the method</param>
/// <param name="genericParameter">The generic parameter as <see cref="Type"/> parameter</param>
/// <param name="parameters">The parameters of the method</param>
/// <returns>The result of invoking the method</returns>
/// <exception cref="GenericMethodNotFoundException">Could not find the generic method</exception>
/// <exception cref="Exception">Any <see cref="Exception"/> thrown after invoking the generic method</exception>
public static async Task<object> CallAsync(object caller, string functionName, BindingFlags bindingFlags, Type genericParameter, params object[] parameters) =>
await GetGenericMethod(caller, functionName, bindingFlags, genericParameter).InvokeGenericMethodAsync(caller, parameters);
/// <summary>
/// Call a generic method asynchronously without generic type parameters
/// </summary>
/// <param name="caller">The caller of the method</param>
/// <param name="functionName">The name of the method to call</param>
/// <param name="bindingFlags">The <see cref="BindingFlags"/> to find the method</param>
/// <param name="genericParameter">The generic parameter as <see cref="Type"/> parameter</param>
/// <param name="secondGenericParameter"></param>
/// <param name="parameters">The parameters of the method</param>
/// <returns>The result of invoking the method</returns>
/// <exception cref="GenericMethodNotFoundException">Could not find the generic method</exception>
/// <exception cref="Exception">Any <see cref="Exception"/> thrown after invoking the generic method</exception>
public static async Task<object> CallAsync(object caller, string functionName, BindingFlags bindingFlags, Type genericParameter, Type secondGenericParameter, params object[] parameters) =>
await GetGenericMethod(caller, functionName, bindingFlags, genericParameter, secondGenericParameter).InvokeGenericMethodAsync(caller, parameters);
private static MethodInfo GetGenericMethod(object caller, string functionName, BindingFlags bindingFlags, params Type[] genericParameters)
{
MethodInfo genericMethod = caller.GetType().GetMethod(functionName, bindingFlags)?.MakeGenericMethod(genericParameters);
if (genericMethod == null)
throw new GenericMethodNotFoundException(functionName);
return genericMethod;
}
private static object InvokeGenericMethod(this MethodInfo genericMethod, object caller, params object[] parameters)
{
try //exceptions thrown by methods called with invoke are wrapped into another exception, the exception thrown by the invoked method can be returned by `Exception.GetBaseException()`
{
return genericMethod.Invoke(caller, parameters);
}
catch (Exception ex)
{
throw ex.GetBaseException();
}
}
private static async Task<object> InvokeGenericMethodAsync(this MethodInfo genericMethod, object caller, params object[] parameters)
{
try //exceptions thrown by methods called with invoke are wrapped into another exception, the exception thrown by the invoked method can be returned by `Exception.GetBaseException()`
{
dynamic awaitable = genericMethod.Invoke(caller, parameters);
await awaitable;
return awaitable.GetAwaiter().GetResult();
}
catch (Exception ex)
{
throw ex.GetBaseException();
}
}
}
}

@ -3,6 +3,7 @@
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -17,9 +18,10 @@ namespace GBase.Interfaces.FileHandling
/// Initialize this <see cref="IFileHandler"/>
/// </summary>
/// <param name="path">The path of the database</param>
/// <param name="folderName"></param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the asynchronous operation</param>
/// <returns>True if successful, false if not</returns>
Task<bool> Init(string path, CancellationToken cancellationToken);
List<IGBaseFile> Init(string path, string folderName, CancellationToken cancellationToken);
IGBaseFile CreateEntryFile<T>(T entry, IGBaseTable table);

@ -9,7 +9,7 @@ namespace GBase.Interfaces.FileHandling
{
public interface IGBaseFile : IDisposable
{
object Entry { get; }
object Entry { get; set; }
FileStream File { get; }
string FilePath { get; }
bool InUse { get; }

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using GBase.Api;
using GBase.Interfaces.Settings;
namespace GBase.Interfaces
@ -48,7 +49,7 @@ namespace GBase.Interfaces
/// <returns>True if successful, false if not</returns>
bool AddTable(IGBaseTable table);
IGBaseTable<T> GetTable<T>();
IGBaseTable<T> GetTable<T>() where T : IGBaseObject, new();
/// <summary>
/// Removes a given <see cref="IGBaseTable"/> from this <see cref="IGBase"/>
@ -57,10 +58,10 @@ namespace GBase.Interfaces
/// <returns>True if successful, false if not</returns>
bool RemoveTable(IGBaseTable table);
Task<bool> AddEntry<T>(T entry, CancellationToken cancellationToken);
Task<bool> AddEntry<T>(T entry, CancellationToken cancellationToken) where T : IGBaseObject, new();
Task SetValue<T, TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken);
Task<TProperty> GetValue<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken);
Task<IEnumerable<TProperty>> GetValues<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken);
Task SetValue<T, TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken) where T : IGBaseObject, new();
Task<TProperty> GetValue<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken) where T : IGBaseObject, new();
Task<IEnumerable<TProperty>> GetValues<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken) where T : IGBaseObject, new();
}
}

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

@ -10,7 +10,7 @@ using GBase.Api;
namespace GBase.Interfaces
{
public interface IGBaseTable<T> : IGBaseTable
public interface IGBaseTable<T> : IGBaseTable where T : IGBaseObject, new()
{
/// <summary>
/// The entries of this <see cref="IGBaseTable"/>

@ -10,6 +10,11 @@ namespace Test.GBase.GBaseIntegrationTest
[GBaseTable("Groups")]
public class Group : IGroup
{
public Group()
{
Items = new List<IItem>();
}
public Group(int key)
{
Key = key;
@ -22,5 +27,9 @@ namespace Test.GBase.GBaseIntegrationTest
public override string ToString() => $"{Key}";
public void InitializeFromString(string @string) => Key = int.Parse(@string);
public void Initialize(List<object> parameters)
{
Key = (int) parameters[0];
}
}
}

@ -2,6 +2,7 @@
// Created: 2020-09-18
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System.Collections.Generic;
using GBase.Attributes;
namespace Test.GBase.GBaseIntegrationTest
@ -9,6 +10,11 @@ namespace Test.GBase.GBaseIntegrationTest
[GBaseTable("Items")]
public class Item : IItem
{
public Item()
{
}
public Item(string name, int key)
{
Name = name;
@ -30,5 +36,11 @@ namespace Test.GBase.GBaseIntegrationTest
Key = int.Parse(properties[0]);
Name = properties[1];
}
public void Initialize(List<object> parameters)
{
Name = (string) parameters[0];
Key = (int) parameters[1];
}
}
}

@ -30,13 +30,13 @@ namespace Test.GBase.GBaseIntegrationTest
{
await _gBase.Init("DB", Assembly.GetExecutingAssembly(), cancellationToken);
// IGBaseTable<Item> itemsTable = _gBase.GetTable<Item>();
// Items = itemsTable.Entries.Cast<IItem>().ToList();
Items = (await _gBase.GetValues<Model, Item>(this, nameof(Items), cancellationToken)).Cast<IItem>().ToList();
IGBaseTable<Item> itemsTable = _gBase.GetTable<Item>();
Items = itemsTable.Entries.Cast<IItem>().ToList();
//Items = (await _gBase.GetValues<Model, Item>(this, nameof(Items), cancellationToken)).Cast<IItem>().ToList();
// IGBaseTable<Group> groupsTable = _gBase.GetTable<Group>();
// Groups = groupsTable.Entries.Cast<IGroup>().ToList();
Groups = (await _gBase.GetValues<Model, Group>(this, nameof(Groups), cancellationToken)).Cast<IGroup>().ToList();
IGBaseTable<Group> groupsTable = _gBase.GetTable<Group>();
Groups = groupsTable.Entries.Cast<IGroup>().ToList();
//Groups = (await _gBase.GetValues<Model, Group>(this, nameof(Groups), cancellationToken)).Cast<IGroup>().ToList();
}
public async Task AddItem(Item item, CancellationToken cancellationToken)

@ -2,6 +2,7 @@
// Created: 2020-03-09
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Threading;
using GBase;
using GBase.Factories;
@ -26,8 +27,8 @@ namespace Test.GBase
IGBaseColumn gBaseColumn = null;
Mock<IGBaseColumnFactory> gBaseColumnFactoryMock = new Mock<IGBaseColumnFactory>();
gBaseColumnFactoryMock.Setup(c => c.Create(It.IsAny<string>()))
.Callback<string>(name => { gBaseColumn = new GBaseColumn(name); })
gBaseColumnFactoryMock.Setup(c => c.Create(It.IsAny<string>(), It.IsAny<Type>()))
.Callback<string, Type>((name, type) => { gBaseColumn = new GBaseColumn(name, type); })
.Returns(gBaseColumn);
Mock<IDataHandlerPool> dataHandlerPoolMock = new Mock<IDataHandlerPool>();

@ -2,16 +2,23 @@
// Created: 2020-01-27
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using GBase.Api;
using GBase.Attributes;
namespace Test.GBase.TestClasses
{
[GBaseTable("Foo")]
public class Foo : NotifyGBaseEntryChanged
public class Foo : NotifyGBaseEntryChanged, IGBaseObject
{
private string _name;
public Foo()
{
}
public Foo(string name)
{
Name = name;
@ -27,5 +34,15 @@ namespace Test.GBase.TestClasses
RaiseGBaseEntryChanged(this, nameof(Name), _name);
}
}
public void InitializeFromString(string @string)
{
throw new NotImplementedException();
}
public void Initialize(List<object> parameters)
{
throw new NotImplementedException();
}
}
}

@ -3,6 +3,7 @@
// Copyright(c) 2020 SimonG. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test.GBase.TestClasses
@ -27,6 +28,11 @@ namespace Test.GBase.TestClasses
Number = Convert.ToInt32(numberString);
}
public void Initialize(List<object> parameters)
{
throw new NotImplementedException();
}
public override string ToString() => $"{nameof(UserType)}_{nameof(Number)}_{Number}";
public override bool Equals(object obj)

Loading…
Cancel
Save