You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
6.0 KiB
173 lines
6.0 KiB
// Author: Gockner, Simon
|
|
// Created: 2020-02-12
|
|
// Copyright(c) 2020 SimonG. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using GBase.Attributes;
|
|
using GBase.Exceptions;
|
|
using GBase.Factories;
|
|
using GBase.Interfaces;
|
|
using GBase.Interfaces.Settings;
|
|
|
|
namespace GBase
|
|
{
|
|
/// <summary>
|
|
/// The base class of the GBase database
|
|
/// </summary>
|
|
public class GBase : IGBase
|
|
{
|
|
private readonly IGBaseTableFactory _gBaseTableFactory;
|
|
|
|
/// <summary>
|
|
/// The base class of the GBase database
|
|
/// </summary>
|
|
/// <param name="settings">The <see cref="IGBaseSettings"/> for this <see cref="GBase"/></param>
|
|
/// <param name="gBaseTableFactory">Factory for the <see cref="IGBaseTable"/></param>
|
|
public GBase(IGBaseSettings settings, IGBaseTableFactory gBaseTableFactory)
|
|
{
|
|
_gBaseTableFactory = gBaseTableFactory;
|
|
|
|
Settings = settings;
|
|
Tables = new List<IGBaseTable>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The name of this <see cref="GBase"/>
|
|
/// </summary>
|
|
public string Name { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The settings of this <see cref="GBase"/>
|
|
/// </summary>
|
|
public IGBaseSettings Settings { get; }
|
|
|
|
/// <summary>
|
|
/// The <see cref="IGBaseTable"/>s of this <see cref="GBase"/>
|
|
/// </summary>
|
|
public List<IGBaseTable> Tables { get; }
|
|
|
|
|
|
/// <summary>
|
|
/// Initialize this <see cref="GBase"/>
|
|
/// </summary>
|
|
/// <param name="name">The name of this <see cref="GBase"/></param>
|
|
/// <param name="databaseAssembly">The <see cref="Assembly"/> of the database</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 name, Assembly databaseAssembly, CancellationToken cancellationToken)
|
|
{
|
|
Name = name;
|
|
|
|
Type[] types = databaseAssembly.GetTypes();
|
|
foreach (var type in types)
|
|
{
|
|
GBaseTableAttribute gBaseTableAttribute = type.GetCustomAttribute<GBaseTableAttribute>();
|
|
if (gBaseTableAttribute == null)
|
|
continue;
|
|
|
|
IGBaseTable gBaseTable = _gBaseTableFactory.Create(type);
|
|
await gBaseTable.Init(type, Settings.DatabasePath, gBaseTableAttribute.FolderName, cancellationToken);
|
|
|
|
AddTable(gBaseTable);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a given <see cref="IGBaseTable"/> to this <see cref="GBase"/>
|
|
/// </summary>
|
|
/// <param name="table">The given <see cref="IGBaseTable"/></param>
|
|
/// <returns>True if successful, false if not</returns>
|
|
public bool AddTable(IGBaseTable table)
|
|
{
|
|
if (Tables.Contains(table))
|
|
return false;
|
|
|
|
if (Tables.Any(t => t.FolderName.Equals(table.FolderName)))
|
|
return false;
|
|
|
|
Tables.Add(table);
|
|
return true;
|
|
}
|
|
|
|
public IGBaseTable<T> GetTable<T>()
|
|
{
|
|
if (Tables.OfType<IGBaseTable<T>>().Any())
|
|
return Tables.OfType<IGBaseTable<T>>().First();
|
|
|
|
throw new MissingTableException<T>();
|
|
// //TODO: This probably doesn't work, because even though t.Type : T, IGBaseTable<t.Type> !: IGBaseTable<T>
|
|
// return (IGBaseTable<T>) Convert.ChangeType(Tables.FirstOrDefault(t => typeof(T).IsAssignableFrom(t.Type)), typeof(IGBaseTable<T>)); //TestMe
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a given <see cref="IGBaseTable"/> from this <see cref="GBase"/>
|
|
/// </summary>
|
|
/// <param name="table">The given <see cref="IGBaseTable"/></param>
|
|
/// <returns>True if successful, false if not</returns>
|
|
public bool RemoveTable(IGBaseTable table)
|
|
{
|
|
if (!Tables.Contains(table))
|
|
return false;
|
|
|
|
return Tables.Remove(table);
|
|
}
|
|
|
|
public async Task<bool> AddEntry<T>(T entry, CancellationToken cancellationToken)
|
|
{
|
|
IGBaseTable<T> table = GetTable<T>();
|
|
if (table == null)
|
|
throw new MissingTableException<T>();
|
|
|
|
return await table.AddEntry(entry, cancellationToken);
|
|
}
|
|
|
|
public async Task SetValue<T, TProperty>(T entry, string propertyName, TProperty value, CancellationToken cancellationToken)
|
|
{
|
|
IGBaseTable<T> table = GetTable<T>();
|
|
if (table == null)
|
|
throw new MissingTableException<T>();
|
|
|
|
await table.SetValue(entry, propertyName, value, cancellationToken);
|
|
}
|
|
|
|
public async Task<TProperty> GetValue<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
|
|
{
|
|
IGBaseTable<T> table = GetTable<T>();
|
|
if (table == null)
|
|
throw new MissingTableException<T>();
|
|
|
|
return await table.GetValue<TProperty>(entry, propertyName, cancellationToken);
|
|
}
|
|
|
|
public async Task<IEnumerable<TProperty>> GetValues<T, TProperty>(T entry, string propertyName, CancellationToken cancellationToken)
|
|
{
|
|
IGBaseTable<T> table = GetTable<T>();
|
|
if (table == null)
|
|
throw new MissingTableException<T>();
|
|
|
|
return await table.GetValues<TProperty>(entry, propertyName, cancellationToken);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Dispose used resources asynchronously
|
|
/// </summary>
|
|
/// <returns>A <see cref="ValueTask"/> to await</returns>
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
foreach (var table in Tables)
|
|
{
|
|
await table.DisposeAsync();
|
|
}
|
|
|
|
Tables.Clear();
|
|
}
|
|
}
|
|
} |