Files
Tabletop/Tabletop.Core/Services/AbilityService.cs
2025-12-30 02:22:44 +01:00

210 lines
8.1 KiB
C#

using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class AbilityService : IModelService<Ability, int, AbilityFilter>
{
public async Task CreateAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Fractions
(
Quality,
Force
)
VALUES
(
@QUALITY,
@FORCE
); {dbController.GetLastIdSql()}";
input.AbilityId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO AbilityDescription
(
AbilityId,
Code,
Name,
Description,
Mechanic
)
VALUES
(
@ABILITY_ID,
@CODE,
@NAME,
@DESCRIPTION,
@MECHANIC
)";
var parameters = new
{
ABILTIY_ID = input.AbilityId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Abilities WHERE AbilityId = @ABILITY_ID";
await dbController.QueryAsync(sql, new
{
ABILITY_ID = input.AbilityId
}, cancellationToken);
}
public static async Task<List<Ability>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Abilities";
var list = await dbController.SelectDataAsync<Ability>(sql, cancellationToken: cancellationToken);
await LoadClassDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<Ability?> GetAsync(int abilityId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"SELECT * FROM Abilities WHERE AbilityId = @ABILITY_ID";
var ability = await dbController.GetFirstAsync<Ability>(sql, new
{
ABILITY_ID = abilityId
}, cancellationToken);
return ability;
}
private static async Task LoadClassDescriptionsAsync(List<Ability> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> abilityIds = list.Select(x => x.AbilityId);
string sql = $"SELECT * FROM AbilityDescription WHERE AbilityId IN ({string.Join(",", abilityIds)})";
List<AbilityDescription> descriptions = await dbController.SelectDataAsync<AbilityDescription>(sql, null, cancellationToken);
foreach (var item in list)
{
item.Description = [.. descriptions.Where(x => x.AbilityId == item.AbilityId)];
}
}
}
public async Task UpdateAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"UPDATE Abilities SET
Quality = @QUALITY,
Force = @FORCE
WHERE AbilityId = @ABILITY_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE AbilityDescription SET
Name = @NAME,
Description = @DESCRIPTION,
Mechanic = @MECHANIC
WHERE AbilityId = @ABILITY_ID AND Code = @CODE";
var parameters = new
{
ABILITY_ID = input.AbilityId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description,
MECHANIC = description.Mechanic
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task<List<Ability>> GetAsync(AbilityFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT ad.Name, a.* " +
"FROM AbilityDescription ad " +
"INNER JOIN Abilities a " +
"ON (a.AbilityId = ad.AbilityId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
// Zum Debuggen schreiben wir den Wert einmal als Variabel
string sql = sqlBuilder.ToString();
List<Ability> list = await dbController.SelectDataAsync<Ability>(sql, GetFilterParameter(filter), cancellationToken);
await LoadAbilityDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<int> GetTotalAsync(AbilityFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM AbilityDescription WHERE 1 = 1 ");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public string GetFilterWhere(AbilityFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sqlBuilder.ToString();
return sql;
}
public Dictionary<string, object?> GetFilterParameter(AbilityFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
private static async Task LoadAbilityDescriptionsAsync(List<Ability> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> abilityIds = list.Select(x => x.AbilityId);
string sql = $"SELECT * FROM AbilityDescription WHERE AbilityId IN ({string.Join(",", abilityIds)})";
List<AbilityDescription> descriptions = await dbController.SelectDataAsync<AbilityDescription>(sql, null, cancellationToken);
foreach (var ability in list)
{
ability.Description = [.. descriptions.Where(x => x.AbilityId == ability.AbilityId)];
}
}
}
}
}