KoogleApp/Koogle.Infrastrcuture/Repositories/PlayerRepository.cs

316 lines
9.9 KiB
C#

using KoogleApp.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using Koogle.Domain.Interfaces;
using Microsoft.Extensions.Logging;
namespace KoogleApp.Data.Repository
{
public class InMemoryPlayerRepository : IPlayerRepository
{
private readonly List<Player> _data = new();
private readonly List<PlayerExpense> _playerExpenses = new();
private int _nextId = 1;
private readonly SemaphoreSlim _lock = new(1, 1);
public InMemoryPlayerRepository()
{
// Seed-Daten für Entwicklung
_data.AddRange(new[]
{
new Player
{
Id = _nextId++,
Name = "Christian Kauer",
//Description = "Beschreibung 1",
CreatedAt = DateTime.UtcNow.AddDays(-5)
},
new Player
{
Id = _nextId++,
Name = "Michael Thöne",
//Description = "Beschreibung 2",
CreatedAt = DateTime.UtcNow.AddDays(-3)
},
new Player
{
Id = _nextId++,
Name = "Christian Hermann",
//Description = "Beschreibung 3",
CreatedAt = DateTime.UtcNow.AddDays(-1)
},
new Player
{
Id = _nextId++,
Name = "Stefan Meinerzhagen",
//Description = "Beschreibung 3",
CreatedAt = DateTime.UtcNow.AddDays(-1)
}
});
_playerExpenses.AddRange([
new PlayerExpense()
{
Id = 1,
PlayerId = _data[0].Id,
Name = "Expense 1",
CreatedAt = DateTime.UtcNow.AddDays(-1)
}
]);
}
public async Task<List<Player>> GetAllAsync(bool includeExpenses = false)
{
await _lock.WaitAsync();
try
{
// Simuliere Datenbanklatenz
await Task.Delay(100);
return _data.Select(d => new Player
{
Id = d.Id,
Name = d.Name,
//Description = d.Description,
CreatedAt = d.CreatedAt,
ModifiedAt = d.ModifiedAt,
ModifiedBy = d.ModifiedBy,
Expenses = includeExpenses
? _playerExpenses.Where(p => p.PlayerId == d.Id)
.OrderBy(p => p.CreatedAt)
.ToList()
: new List<PlayerExpense>()
}).ToList();
}
finally
{
_lock.Release();
}
}
public async Task<Player?> GetByIdAsync(int id, bool includeExpenses = false)
{
await _lock.WaitAsync();
try
{
await Task.Delay(50);
var item = _data.FirstOrDefault(d => d.Id == id);
if (item == null) return null;
return new Player
{
Id = item.Id,
Name = item.Name,
//Description = item.Description,
CreatedAt = item.CreatedAt,
ModifiedAt = item.ModifiedAt,
ModifiedBy = item.ModifiedBy,
Expenses = includeExpenses
? _playerExpenses.Where(p => p.PlayerId == id)
.OrderBy(p => p.CreatedAt)
.ToList()
: new List<PlayerExpense>()
};
}
finally
{
_lock.Release();
}
}
public async Task<Player> CreateAsync(Player item)
{
await _lock.WaitAsync();
try
{
await Task.Delay(100);
item.Id = _nextId++;
item.CreatedAt = DateTime.UtcNow;
// Positionen IDs setzen
foreach (var pos in item.Expenses)
{
pos.Id = _playerExpenses.Any() ? _playerExpenses.Max(p => p.Id) + 1 : 1;
pos.PlayerId = item.Id;
_playerExpenses.Add(pos);
}
_data.Add(item);
return item;
}
finally
{
_lock.Release();
}
}
public async Task<Player> UpdateAsync(Player item)
{
await _lock.WaitAsync();
try
{
await Task.Delay(100);
var existing = _data.FirstOrDefault(d => d.Id == item.Id);
if (existing == null)
throw new KeyNotFoundException($"Item with ID {item.Id} not found");
existing.Name = item.Name;
existing.PlayerStatus = item.PlayerStatus;
//existing.Description = item.Description;
existing.ModifiedAt = DateTime.UtcNow;
existing.ModifiedBy = item.ModifiedBy;
// Positionen aktualisieren (einfache Strategie: alte löschen, neue hinzufügen)
_playerExpenses.RemoveAll(p => p.PlayerId == item.Id);
foreach (var pos in item.Expenses)
{
if (pos.Id == 0)
pos.Id = _playerExpenses.Any() ? _playerExpenses.Max(p => p.Id) + 1 : 1;
pos.PlayerId = item.Id;
_playerExpenses.Add(pos);
}
existing.Expenses = item.Expenses;
return existing;
}
finally
{
_lock.Release();
}
}
public async Task<bool> DeleteAsync(int id)
{
await _lock.WaitAsync();
try
{
await Task.Delay(50);
var item = _data.FirstOrDefault(d => d.Id == id);
if (item == null) return false;
// Cascade Delete - Positionen auch löschen
_playerExpenses.RemoveAll(p => p.PlayerId == id);
_data.Remove(item);
return true;
}
finally
{
_lock.Release();
}
}
}
public class PlayerRepository : IPlayerRepository
{
private readonly IDbContextFactory<AppDbContext> _contextFactory;
private readonly ILogger<IPlayerRepository> _logger;
public PlayerRepository(
IDbContextFactory<AppDbContext> contextFactory,
ILogger<IPlayerRepository> logger)
{
_contextFactory = contextFactory;
_logger = logger;
}
public async Task<List<Player>> GetAllAsync(bool includeExpenses = false)
{
try
{
await using var context = await _contextFactory.CreateDbContextAsync();
return await context.Players
.OrderByDescending(d => d.CreatedAt)
.ToListAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading all data items");
throw;
}
}
public async Task<Player?> GetByIdAsync(int id, bool includeExpenses = false)
{
try
{
await using var context = await _contextFactory.CreateDbContextAsync();
return await context.Players
.FirstOrDefaultAsync(d => d.Id == id);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading data item {Id}", id);
throw;
}
}
public async Task<Player> CreateAsync(Player item)
{
try
{
await using var context = await _contextFactory.CreateDbContextAsync();
item.CreatedAt = DateTime.UtcNow;
context.Players.Add(item);
await context.SaveChangesAsync();
return item;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating data item");
throw;
}
}
public async Task<Player> UpdateAsync(Player item)
{
try
{
await using var context = await _contextFactory.CreateDbContextAsync();
var existing = await context.Players.FindAsync(item.Id);
if (existing == null)
throw new KeyNotFoundException($"Item with ID {item.Id} not found");
existing.Name = item.Name;
existing.PlayerStatus = item.PlayerStatus;
//existing.Description = item.Description;
existing.ModifiedAt = DateTime.UtcNow;
existing.ModifiedBy = item.ModifiedBy;
await context.SaveChangesAsync();
return existing;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating data item {Id}", item.Id);
throw;
}
}
public async Task<bool> DeleteAsync(int id)
{
try
{
await using var context = await _contextFactory.CreateDbContextAsync();
var item = await context.Players.FindAsync(id);
if (item == null) return false;
context.Players.Remove(item);
await context.SaveChangesAsync();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting data item {Id}", id);
throw;
}
}
}
}