mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 01:54:43 +00:00
updates
This commit is contained in:
@@ -23,27 +23,27 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
IBreweryRepository
|
IBreweryRepository
|
||||||
{
|
{
|
||||||
private const string SelectColumns = """
|
private const string SelectColumns = """
|
||||||
bp.BreweryPostID,
|
bp.BreweryPostID,
|
||||||
bp.PostedByID,
|
bp.PostedByID,
|
||||||
bp.BreweryName,
|
bp.BreweryName,
|
||||||
bp.Description,
|
bp.Description,
|
||||||
bp.CreatedAt,
|
bp.CreatedAt,
|
||||||
bp.UpdatedAt,
|
bp.UpdatedAt,
|
||||||
bp.RowVersion,
|
bp.RowVersion,
|
||||||
bpl.BreweryPostLocationID,
|
bpl.BreweryPostLocationID,
|
||||||
bpl.CityID,
|
bpl.CityID,
|
||||||
bpl.AddressLine1,
|
bpl.AddressLine1,
|
||||||
bpl.AddressLine2,
|
bpl.AddressLine2,
|
||||||
bpl.PostalCode,
|
bpl.PostalCode,
|
||||||
bpl.Coordinates,
|
bpl.Coordinates,
|
||||||
c.CityName,
|
c.CityName,
|
||||||
c.StateProvinceID,
|
c.StateProvinceID,
|
||||||
sp.StateProvinceName,
|
sp.StateProvinceName,
|
||||||
sp.ISO3166_2,
|
sp.ISO3166_2,
|
||||||
sp.CountryID,
|
sp.CountryID,
|
||||||
co.CountryName,
|
co.CountryName,
|
||||||
co.ISO3166_1
|
co.ISO3166_1
|
||||||
""";
|
""";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Joins from <c>dbo.BreweryPost</c> down to <c>dbo.Country</c> so a row carries everything needed
|
/// Joins from <c>dbo.BreweryPost</c> down to <c>dbo.Country</c> so a row carries everything needed
|
||||||
@@ -52,12 +52,12 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
/// behavior), since a brewery post may have no location.
|
/// behavior), since a brewery post may have no location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const string FromJoins = """
|
private const string FromJoins = """
|
||||||
dbo.BreweryPost bp
|
dbo.BreweryPost bp
|
||||||
LEFT JOIN dbo.BreweryPostLocation bpl ON bp.BreweryPostID = bpl.BreweryPostID
|
LEFT JOIN dbo.BreweryPostLocation bpl ON bp.BreweryPostID = bpl.BreweryPostID
|
||||||
LEFT JOIN dbo.City c ON bpl.CityID = c.CityID
|
LEFT JOIN dbo.City c ON bpl.CityID = c.CityID
|
||||||
LEFT JOIN dbo.StateProvince sp ON c.StateProvinceID = sp.StateProvinceID
|
LEFT JOIN dbo.StateProvince sp ON c.StateProvinceID = sp.StateProvinceID
|
||||||
LEFT JOIN dbo.Country co ON sp.CountryID = co.CountryID
|
LEFT JOIN dbo.Country co ON sp.CountryID = co.CountryID
|
||||||
""";
|
""";
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<BreweryPost?> GetByIdAsync(Guid id)
|
public async Task<BreweryPost?> GetByIdAsync(Guid id)
|
||||||
@@ -65,10 +65,10 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
await using DbConnection connection = await CreateConnection();
|
await using DbConnection connection = await CreateConnection();
|
||||||
await using DbCommand command = connection.CreateCommand();
|
await using DbCommand command = connection.CreateCommand();
|
||||||
command.CommandText = $"""
|
command.CommandText = $"""
|
||||||
SELECT {SelectColumns}
|
SELECT {SelectColumns}
|
||||||
FROM {FromJoins}
|
FROM {FromJoins}
|
||||||
WHERE bp.BreweryPostID = @BreweryPostId
|
WHERE bp.BreweryPostID = @BreweryPostId
|
||||||
""";
|
""";
|
||||||
AddParameter(command, "@BreweryPostId", id);
|
AddParameter(command, "@BreweryPostId", id);
|
||||||
|
|
||||||
await using DbDataReader reader = await command.ExecuteReaderAsync();
|
await using DbDataReader reader = await command.ExecuteReaderAsync();
|
||||||
@@ -76,16 +76,17 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<IEnumerable<BreweryPost>> GetAllAsync(int? limit, int? offset)
|
public async Task<IEnumerable<BreweryPost>> GetAllAsync(int? limit,
|
||||||
|
int? offset)
|
||||||
{
|
{
|
||||||
await using DbConnection connection = await CreateConnection();
|
await using DbConnection connection = await CreateConnection();
|
||||||
await using DbCommand command = connection.CreateCommand();
|
await using DbCommand command = connection.CreateCommand();
|
||||||
command.CommandText = $"""
|
command.CommandText = $"""
|
||||||
SELECT {SelectColumns}
|
SELECT {SelectColumns}
|
||||||
FROM {FromJoins}
|
FROM {FromJoins}
|
||||||
ORDER BY bp.CreatedAt DESC
|
ORDER BY bp.CreatedAt DESC
|
||||||
OFFSET @Offset ROWS FETCH NEXT @Limit ROWS ONLY
|
OFFSET @Offset ROWS FETCH NEXT @Limit ROWS ONLY
|
||||||
""";
|
""";
|
||||||
AddParameter(command, "@Offset", offset ?? 0);
|
AddParameter(command, "@Offset", offset ?? 0);
|
||||||
AddParameter(command, "@Limit", limit ?? int.MaxValue);
|
AddParameter(command, "@Limit", limit ?? int.MaxValue);
|
||||||
|
|
||||||
@@ -102,19 +103,25 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
public async Task<BreweryPost> UpdateAsync(BreweryPost brewery)
|
public async Task<BreweryPost> UpdateAsync(BreweryPost brewery)
|
||||||
{
|
{
|
||||||
await using DbConnection connection = await CreateConnection();
|
await using DbConnection connection = await CreateConnection();
|
||||||
await using DbTransaction transaction = await connection.BeginTransactionAsync();
|
await using DbTransaction transaction =
|
||||||
|
await connection.BeginTransactionAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool breweryExists =
|
bool breweryExists =
|
||||||
await connection.ExecuteScalarAsync<int?>(
|
await connection.ExecuteScalarAsync<int?>(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"SELECT 1 FROM dbo.BreweryPost WHERE BreweryPostID = @BreweryPostId",
|
"""
|
||||||
new { brewery.BreweryPostId },
|
SELECT 1 FROM
|
||||||
transaction
|
dbo.BreweryPost
|
||||||
|
WHERE
|
||||||
|
BreweryPostID = @BreweryPostId
|
||||||
|
""",
|
||||||
|
new { brewery.BreweryPostId },
|
||||||
|
transaction
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
is not null;
|
||||||
is not null;
|
|
||||||
|
|
||||||
if (!breweryExists)
|
if (!breweryExists)
|
||||||
throw new NotFoundException("Brewery not found.");
|
throw new NotFoundException("Brewery not found.");
|
||||||
@@ -123,13 +130,13 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
{
|
{
|
||||||
bool cityExists =
|
bool cityExists =
|
||||||
await connection.ExecuteScalarAsync<int?>(
|
await connection.ExecuteScalarAsync<int?>(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"SELECT 1 FROM dbo.City WHERE CityID = @CityId",
|
"SELECT 1 FROM dbo.City WHERE CityID = @CityId",
|
||||||
new { brewery.Location.CityId },
|
new { brewery.Location.CityId },
|
||||||
transaction
|
transaction
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
is not null;
|
||||||
is not null;
|
|
||||||
|
|
||||||
if (!cityExists)
|
if (!cityExists)
|
||||||
throw new NotFoundException("City not found.");
|
throw new NotFoundException("City not found.");
|
||||||
@@ -139,8 +146,12 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"""
|
"""
|
||||||
UPDATE dbo.BreweryPost
|
UPDATE dbo.BreweryPost
|
||||||
SET BreweryName = @BreweryName, Description = @Description, UpdatedAt = GETDATE()
|
SET BreweryName = @BreweryName,
|
||||||
WHERE BreweryPostID = @BreweryPostId AND RowVersion = @RowVersion
|
Description = @Description,
|
||||||
|
UpdatedAt = GETDATE()
|
||||||
|
WHERE
|
||||||
|
BreweryPostID = @BreweryPostId
|
||||||
|
AND RowVersion = @RowVersion
|
||||||
""",
|
""",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
@@ -163,7 +174,11 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
// No location supplied: clear any existing location for this brewery.
|
// No location supplied: clear any existing location for this brewery.
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"DELETE FROM dbo.BreweryPostLocation WHERE BreweryPostID = @BreweryPostId",
|
"""
|
||||||
|
DELETE FROM
|
||||||
|
dbo.BreweryPostLocation
|
||||||
|
WHERE BreweryPostID = @BreweryPostId
|
||||||
|
""",
|
||||||
new { brewery.BreweryPostId },
|
new { brewery.BreweryPostId },
|
||||||
transaction
|
transaction
|
||||||
)
|
)
|
||||||
@@ -173,21 +188,28 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
{
|
{
|
||||||
bool locationExists =
|
bool locationExists =
|
||||||
await connection.ExecuteScalarAsync<int?>(
|
await connection.ExecuteScalarAsync<int?>(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"SELECT 1 FROM dbo.BreweryPostLocation WHERE BreweryPostID = @BreweryPostId",
|
"""
|
||||||
new { brewery.BreweryPostId },
|
SELECT 1
|
||||||
transaction
|
FROM dbo.BreweryPostLocation
|
||||||
|
WHERE BreweryPostID = @BreweryPostId
|
||||||
|
""",
|
||||||
|
new { brewery.BreweryPostId },
|
||||||
|
transaction
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
is not null;
|
||||||
is not null;
|
|
||||||
|
|
||||||
if (locationExists)
|
if (locationExists)
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"""
|
"""
|
||||||
UPDATE dbo.BreweryPostLocation
|
UPDATE dbo.BreweryPostLocation
|
||||||
SET CityID = @CityId, AddressLine1 = @AddressLine1, AddressLine2 = @AddressLine2,
|
SET CityID = @CityId,
|
||||||
PostalCode = @PostalCode, Coordinates = @Coordinates
|
AddressLine1 = @AddressLine1,
|
||||||
|
AddressLine2 = @AddressLine2,
|
||||||
|
PostalCode = @PostalCode,
|
||||||
|
Coordinates = @Coordinates
|
||||||
WHERE BreweryPostID = @BreweryPostId
|
WHERE BreweryPostID = @BreweryPostId
|
||||||
""",
|
""",
|
||||||
new
|
new
|
||||||
@@ -247,9 +269,9 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return await GetByIdAsync(brewery.BreweryPostId)
|
return await GetByIdAsync(brewery.BreweryPostId)
|
||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException(
|
||||||
$"Brewery '{brewery.BreweryPostId}' was not found after a successful update."
|
$"Brewery '{brewery.BreweryPostId}' was not found after a successful update."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -257,7 +279,12 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
{
|
{
|
||||||
await using DbConnection connection = await CreateConnection();
|
await using DbConnection connection = await CreateConnection();
|
||||||
int rows = await connection.ExecuteAsync(
|
int rows = await connection.ExecuteAsync(
|
||||||
"DELETE FROM dbo.BreweryPost WHERE BreweryPostID = @BreweryPostId",
|
"""
|
||||||
|
DELETE FROM
|
||||||
|
dbo.BreweryPost
|
||||||
|
WHERE
|
||||||
|
BreweryPostID = @BreweryPostId
|
||||||
|
""",
|
||||||
new { BreweryPostId = id }
|
new { BreweryPostId = id }
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -269,35 +296,49 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
public async Task CreateAsync(BreweryPost brewery)
|
public async Task CreateAsync(BreweryPost brewery)
|
||||||
{
|
{
|
||||||
if (brewery.Location is null)
|
if (brewery.Location is null)
|
||||||
throw new ArgumentException("Location must be provided when creating a brewery.");
|
throw new ArgumentException(
|
||||||
|
"Location must be provided when creating a brewery.");
|
||||||
|
|
||||||
await using DbConnection connection = await CreateConnection();
|
await using DbConnection connection = await CreateConnection();
|
||||||
await using DbTransaction transaction = await connection.BeginTransactionAsync();
|
await using DbTransaction transaction =
|
||||||
|
await connection.BeginTransactionAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool userExists =
|
bool userExists =
|
||||||
await connection.ExecuteScalarAsync<int?>(
|
await connection.ExecuteScalarAsync<int?>(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"SELECT 1 FROM dbo.UserAccount WHERE UserAccountID = @PostedById",
|
"""
|
||||||
new { brewery.PostedById },
|
SELECT 1
|
||||||
transaction
|
FROM
|
||||||
|
dbo.UserAccount
|
||||||
|
WHERE
|
||||||
|
UserAccountID = @PostedById
|
||||||
|
""",
|
||||||
|
new { brewery.PostedById },
|
||||||
|
transaction
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
is not null;
|
||||||
is not null;
|
|
||||||
|
|
||||||
if (!userExists)
|
if (!userExists)
|
||||||
throw new NotFoundException("User not found.");
|
throw new NotFoundException("User not found.");
|
||||||
|
|
||||||
bool cityExists =
|
bool cityExists =
|
||||||
await connection.ExecuteScalarAsync<int?>(
|
await connection.ExecuteScalarAsync<int?>(
|
||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"SELECT 1 FROM dbo.City WHERE CityID = @CityId",
|
"""
|
||||||
new { brewery.Location.CityId },
|
SELECT 1
|
||||||
transaction
|
FROM
|
||||||
|
dbo.City
|
||||||
|
WHERE
|
||||||
|
CityID = @CityId
|
||||||
|
""",
|
||||||
|
new { brewery.Location.CityId },
|
||||||
|
transaction
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
is not null;
|
||||||
is not null;
|
|
||||||
|
|
||||||
if (!cityExists)
|
if (!cityExists)
|
||||||
throw new NotFoundException("City not found.");
|
throw new NotFoundException("City not found.");
|
||||||
@@ -306,15 +347,9 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"""
|
"""
|
||||||
INSERT INTO dbo.BreweryPost
|
INSERT INTO dbo.BreweryPost
|
||||||
(BreweryPostID,
|
(BreweryPostID, BreweryName, Description, PostedByID)
|
||||||
BreweryName,
|
|
||||||
Description,
|
|
||||||
PostedByID)
|
|
||||||
VALUES
|
VALUES
|
||||||
(@BreweryPostId,
|
(@BreweryPostId, @BreweryName, @Description, @PostedById)
|
||||||
@BreweryName,
|
|
||||||
@Description,
|
|
||||||
@PostedById)
|
|
||||||
""",
|
""",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
@@ -331,8 +366,20 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
new CommandDefinition(
|
new CommandDefinition(
|
||||||
"""
|
"""
|
||||||
INSERT INTO dbo.BreweryPostLocation
|
INSERT INTO dbo.BreweryPostLocation
|
||||||
(BreweryPostLocationID, BreweryPostID, CityID, AddressLine1, AddressLine2, PostalCode, Coordinates)
|
(BreweryPostLocationID,
|
||||||
VALUES (@BreweryPostLocationId, @BreweryPostId, @CityId, @AddressLine1, @AddressLine2, @PostalCode, @Coordinates)
|
BreweryPostID,
|
||||||
|
CityID,
|
||||||
|
AddressLine1,
|
||||||
|
AddressLine2,
|
||||||
|
PostalCode,
|
||||||
|
Coordinates)
|
||||||
|
VALUES (@BreweryPostLocationId,
|
||||||
|
@BreweryPostId,
|
||||||
|
@CityId,
|
||||||
|
@AddressLine1,
|
||||||
|
@AddressLine2,
|
||||||
|
@PostalCode,
|
||||||
|
@Coordinates)
|
||||||
""",
|
""",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
@@ -378,7 +425,9 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
BreweryName = reader.GetString(ordBreweryName),
|
BreweryName = reader.GetString(ordBreweryName),
|
||||||
Description = reader.GetString(ordDescription),
|
Description = reader.GetString(ordDescription),
|
||||||
CreatedAt = reader.GetDateTime(ordCreatedAt),
|
CreatedAt = reader.GetDateTime(ordCreatedAt),
|
||||||
UpdatedAt = reader.IsDBNull(ordUpdatedAt) ? null : reader.GetDateTime(ordUpdatedAt),
|
UpdatedAt = reader.IsDBNull(ordUpdatedAt)
|
||||||
|
? null
|
||||||
|
: reader.GetDateTime(ordUpdatedAt),
|
||||||
RowVersion = reader.IsDBNull(ordRowVersion)
|
RowVersion = reader.IsDBNull(ordRowVersion)
|
||||||
? null
|
? null
|
||||||
: reader.GetFieldValue<byte[]>(ordRowVersion),
|
: reader.GetFieldValue<byte[]>(ordRowVersion),
|
||||||
@@ -396,7 +445,8 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
BreweryPostId = brewery.BreweryPostId,
|
BreweryPostId = brewery.BreweryPostId,
|
||||||
CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
|
CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
|
||||||
City = MapCity(reader),
|
City = MapCity(reader),
|
||||||
AddressLine1 = reader.GetString(reader.GetOrdinal("AddressLine1")),
|
AddressLine1 =
|
||||||
|
reader.GetString(reader.GetOrdinal("AddressLine1")),
|
||||||
AddressLine2 = reader.IsDBNull(ordAddressLine2)
|
AddressLine2 = reader.IsDBNull(ordAddressLine2)
|
||||||
? null
|
? null
|
||||||
: reader.GetString(ordAddressLine2),
|
: reader.GetString(ordAddressLine2),
|
||||||
@@ -421,24 +471,30 @@ public class BreweryRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
{
|
{
|
||||||
CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
|
CityId = reader.GetGuid(reader.GetOrdinal("CityId")),
|
||||||
CityName = reader.GetString(reader.GetOrdinal("CityName")),
|
CityName = reader.GetString(reader.GetOrdinal("CityName")),
|
||||||
StateProvinceId = reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
|
StateProvinceId =
|
||||||
|
reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
|
||||||
StateProvince = new StateProvince
|
StateProvince = new StateProvince
|
||||||
{
|
{
|
||||||
StateProvinceId = reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
|
StateProvinceId =
|
||||||
StateProvinceName = reader.GetString(reader.GetOrdinal("StateProvinceName")),
|
reader.GetGuid(reader.GetOrdinal("StateProvinceId")),
|
||||||
|
StateProvinceName =
|
||||||
|
reader.GetString(reader.GetOrdinal("StateProvinceName")),
|
||||||
ISO3166_2 = reader.GetString(reader.GetOrdinal("ISO3166_2")),
|
ISO3166_2 = reader.GetString(reader.GetOrdinal("ISO3166_2")),
|
||||||
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
|
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
|
||||||
Country = new Country
|
Country = new Country
|
||||||
{
|
{
|
||||||
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
|
CountryId = reader.GetGuid(reader.GetOrdinal("CountryId")),
|
||||||
CountryName = reader.GetString(reader.GetOrdinal("CountryName")),
|
CountryName =
|
||||||
ISO3166_1 = reader.GetString(reader.GetOrdinal("ISO3166_1")),
|
reader.GetString(reader.GetOrdinal("CountryName")),
|
||||||
|
ISO3166_1 =
|
||||||
|
reader.GetString(reader.GetOrdinal("ISO3166_1")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddParameter(DbCommand command, string name, object? value)
|
private static void AddParameter(DbCommand command, string name,
|
||||||
|
object? value)
|
||||||
{
|
{
|
||||||
DbParameter p = command.CreateParameter();
|
DbParameter p = command.CreateParameter();
|
||||||
p.ParameterName = name;
|
p.ParameterName = name;
|
||||||
|
|||||||
Reference in New Issue
Block a user