using System.Data.Common; using Dapper; using Database.Connection; using Domain.Entities; using Domain.Exceptions; namespace Features.Users.Repository; /// /// Dapper-based implementation of . /// public class UserProfileRepository(ISqlConnectionFactory connectionFactory) : DapperRepository(connectionFactory), IUserProfileRepository { /// public async Task CreateProfileAsync( Guid userAccountId, string biography, CancellationToken cancellationToken ) { await using DbConnection connection = await CreateConnection(); return await connection.ExecuteScalarAsync( new CommandDefinition( """ INSERT INTO Social.UserProfile (UserAccountID, Biography) OUTPUT INSERTED.UserProfileID VALUES (@UserAccountId, @Biography) """, new { UserAccountId = userAccountId, Biography = biography }, cancellationToken: cancellationToken ) ); } /// public async Task GetProfileIdAsync( Guid userAccountId, CancellationToken cancellationToken ) { await using DbConnection connection = await CreateConnection(); Guid? userProfileId = await connection.ExecuteScalarAsync( new CommandDefinition( """ SELECT UserProfileID FROM Social.UserProfile WHERE UserAccountID = @UserAccountId """, new { UserAccountId = userAccountId }, cancellationToken: cancellationToken ) ); return userProfileId ?? throw new NotFoundException( $"No user profile found for user account ID {userAccountId}" ); } /// public async Task UpdateBiographyAsync( Guid userAccountId, string biography, CancellationToken cancellationToken ) { await using DbConnection connection = await CreateConnection(); int updatedRows = await connection.ExecuteAsync( new CommandDefinition( """ UPDATE Social.UserProfile SET Biography = @Biography WHERE UserAccountID = @UserAccountId """, new { UserAccountId = userAccountId, Biography = biography }, cancellationToken: cancellationToken ) ); if (updatedRows == 0) throw new NotFoundException( $"No user profile found for user account ID {userAccountId}" ); } /// public async Task SaveAvatarAsync(UserAvatar avatar, CancellationToken cancellationToken) { await using DbConnection connection = await CreateConnection(); await using DbTransaction transaction = await connection.BeginTransactionAsync( cancellationToken ); try { await connection.ExecuteAsync( new CommandDefinition( """ UPDATE Social.UserAvatar SET ValidTo = SYSUTCDATETIME() WHERE UserProfileID = @UserProfileId AND ValidTo IS NULL """, new { avatar.UserProfileId }, transaction: transaction, cancellationToken: cancellationToken ) ); await connection.ExecuteAsync( new CommandDefinition( """ INSERT INTO Social.UserAvatar (UserAvatarID, UserProfileID, PhotoID) VALUES (@UserAvatarId, @UserProfileId, @PhotoId) """, new { avatar.UserAvatarId, avatar.UserProfileId, avatar.PhotoId, }, transaction: transaction, cancellationToken: cancellationToken ) ); await transaction.CommitAsync(cancellationToken); } catch { await RollbackQuietlyAsync(transaction); throw; } } }