From c3567fcd59a24b6175d0fe56bc0170398fa200bb Mon Sep 17 00:00:00 2001 From: Jonas Seiler Date: Thu, 3 Apr 2025 11:03:00 +0200 Subject: [PATCH] Infrasctructure: Add StreetRepository --- src/Infrastructure/StreetRepository.cs | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/Infrastructure/StreetRepository.cs diff --git a/src/Infrastructure/StreetRepository.cs b/src/Infrastructure/StreetRepository.cs new file mode 100644 index 0000000..95b5292 --- /dev/null +++ b/src/Infrastructure/StreetRepository.cs @@ -0,0 +1,86 @@ +using Microsoft.EntityFrameworkCore; +using NetTopologySuite.Geometries; + +public class StreetRepository +{ + private readonly StreetDbContext Context; + + public StreetRepository(StreetDbContext context) + { + Context = context; + } + + public async Task GetByNameAsync(string name) + { + return await Context.Streets.FirstOrDefaultAsync(s => s.Name == name); + } + + public async Task ExistsAsync(string name) + { + return await Context.Streets.AnyAsync(s => s.Name == name); + } + + public async Task AddAsync(Street street) + { + await Context.Streets.AddAsync(street); + await Context.SaveChangesAsync(); + } + + public async Task RemoveAsync(string name) + { + var street = await GetByNameAsync(name); + if (street == null) + { + return false; + } + + Context.Streets.Remove(street); + await Context.SaveChangesAsync(); + return true; + } + + public async Task UpdateGeometryInBackend(string name, Geometry point) + { + var street = await GetByNameAsync(name); + + if (street == null) + { + throw new KeyNotFoundException($"Street '{name}' not found."); + } + + street.AddPointToGeometry(point.Coordinate); + + try + { + await Context.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + throw new InvalidOperationException("Concurrency conflict: The street was modified by another transaction."); + } + } + + public async Task UpdateGeometryWithPostGIS(string name, Geometry point) + { + var street = await GetByNameAsync(name); + + if (street == null) + { + throw new KeyNotFoundException($"Street '{name}' not found."); + } + + try + { + // PostgreSQL's UPDATE already checks for concurrency by default + await Context.Database.ExecuteSqlRawAsync( + "UPDATE \"Streets\" SET \"Geometry\" = ST_AddPoint(\"Geometry\", ST_SetSRID(ST_MakePoint({0}, {1}), 4326)) WHERE \"Name\" = {2}", + point.Coordinate.X, point.Coordinate.Y, name + ); + + } + catch (DbUpdateConcurrencyException) + { + throw new InvalidOperationException("Concurrency conflict: The street was modified by another transaction."); + } + } +} \ No newline at end of file