196 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Dapper;
 | 
						|
using GestionIntegral.Api.Models.Radios;
 | 
						|
using Microsoft.Extensions.Logging;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Data;
 | 
						|
using System.Linq;
 | 
						|
using System.Text;
 | 
						|
using System.Threading.Tasks;
 | 
						|
 | 
						|
namespace GestionIntegral.Api.Data.Repositories.Radios
 | 
						|
{
 | 
						|
    public class CancionRepository : ICancionRepository
 | 
						|
    {
 | 
						|
        private readonly DbConnectionFactory _cf;
 | 
						|
        private readonly ILogger<CancionRepository> _log;
 | 
						|
 | 
						|
        public CancionRepository(DbConnectionFactory cf, ILogger<CancionRepository> log)
 | 
						|
        {
 | 
						|
            _cf = cf;
 | 
						|
            _log = log;
 | 
						|
        }
 | 
						|
 | 
						|
        private string SelectWithAlias() => @"
 | 
						|
            SELECT 
 | 
						|
                Id, Tema, CompositorAutor, Interprete, Sello, Placa, Pista, Introduccion, 
 | 
						|
                Ritmo AS IdRitmo, -- Mapear columna Ritmo a propiedad IdRitmo del modelo Cancion
 | 
						|
                Formato, Album
 | 
						|
            FROM dbo.rad_dtCanciones";
 | 
						|
 | 
						|
 | 
						|
        public async Task<IEnumerable<Cancion>> GetAllAsync(string? temaFilter, string? interpreteFilter, int? idRitmoFilter)
 | 
						|
        {
 | 
						|
            var sqlBuilder = new StringBuilder(SelectWithAlias());
 | 
						|
            sqlBuilder.Append(" WHERE 1=1");
 | 
						|
            var parameters = new DynamicParameters();
 | 
						|
 | 
						|
            if (!string.IsNullOrWhiteSpace(temaFilter))
 | 
						|
            {
 | 
						|
                sqlBuilder.Append(" AND Tema LIKE @TemaParam");
 | 
						|
                parameters.Add("TemaParam", $"%{temaFilter}%");
 | 
						|
            }
 | 
						|
            if (!string.IsNullOrWhiteSpace(interpreteFilter))
 | 
						|
            {
 | 
						|
                sqlBuilder.Append(" AND Interprete LIKE @InterpreteParam");
 | 
						|
                parameters.Add("InterpreteParam", $"%{interpreteFilter}%");
 | 
						|
            }
 | 
						|
            if (idRitmoFilter.HasValue)
 | 
						|
            {
 | 
						|
                sqlBuilder.Append(" AND Ritmo = @IdRitmoParam"); // La columna en DB es "Ritmo"
 | 
						|
                parameters.Add("IdRitmoParam", idRitmoFilter.Value);
 | 
						|
            }
 | 
						|
            sqlBuilder.Append(" ORDER BY Tema, Interprete;");
 | 
						|
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                return await connection.QueryAsync<Cancion>(sqlBuilder.ToString(), parameters);
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al obtener todas las Canciones.");
 | 
						|
                return Enumerable.Empty<Cancion>();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public async Task<Cancion?> GetByIdAsync(int id)
 | 
						|
        {
 | 
						|
            var sql = SelectWithAlias() + " WHERE Id = @IdParam";
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                return await connection.QuerySingleOrDefaultAsync<Cancion>(sql, new { IdParam = id });
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al obtener Canción por ID: {IdCancion}", id);
 | 
						|
                return null;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public async Task<bool> ExistsByTemaAndInterpreteAsync(string tema, string interprete, int? excludeId = null)
 | 
						|
        {
 | 
						|
            // La unicidad puede ser más compleja si se consideran otros campos como Álbum.
 | 
						|
            // Por ahora, un ejemplo simple.
 | 
						|
            var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.rad_dtCanciones WHERE Tema = @TemaParam AND Interprete = @InterpreteParam");
 | 
						|
            var parameters = new DynamicParameters();
 | 
						|
            parameters.Add("TemaParam", tema);
 | 
						|
            parameters.Add("InterpreteParam", interprete);
 | 
						|
            if (excludeId.HasValue)
 | 
						|
            {
 | 
						|
                sqlBuilder.Append(" AND Id != @ExcludeIdParam");
 | 
						|
                parameters.Add("ExcludeIdParam", excludeId.Value);
 | 
						|
            }
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                return await connection.ExecuteScalarAsync<bool>(sqlBuilder.ToString(), parameters);
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error en ExistsByTemaAndInterpreteAsync. Tema: {Tema}, Interprete: {Interprete}", tema, interprete);
 | 
						|
                return true; // Asumir que existe en caso de error
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        public async Task<Cancion?> CreateAsync(Cancion nuevaCancion /*, int idUsuario, IDbTransaction transaction */)
 | 
						|
        {
 | 
						|
            // El modelo Cancion usa IdRitmo, pero la tabla rad_dtCanciones usa la columna "Ritmo" para el FK a rad_dtRitmos.Id
 | 
						|
            const string sqlInsert = @"
 | 
						|
                INSERT INTO dbo.rad_dtCanciones (Tema, CompositorAutor, Interprete, Sello, Placa, Pista, Introduccion, Ritmo, Formato, Album)
 | 
						|
                OUTPUT INSERTED.Id, INSERTED.Tema, INSERTED.CompositorAutor, INSERTED.Interprete, INSERTED.Sello, INSERTED.Placa, 
 | 
						|
                       INSERTED.Pista, INSERTED.Introduccion, INSERTED.Ritmo AS IdRitmo, INSERTED.Formato, INSERTED.Album
 | 
						|
                VALUES (@Tema, @CompositorAutor, @Interprete, @Sello, @Placa, @Pista, @Introduccion, @IdRitmo, @Formato, @Album);";
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                // El objeto nuevaCancion tiene la propiedad IdRitmo, que Dapper mapeará al parámetro @IdRitmo
 | 
						|
                return await connection.QuerySingleAsync<Cancion>(sqlInsert, nuevaCancion);
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al crear Canción: {Tema} por {Interprete}", nuevaCancion.Tema, nuevaCancion.Interprete);
 | 
						|
                return null;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public async Task<bool> UpdateAsync(Cancion cancionAActualizar /*, int idUsuario, IDbTransaction transaction */)
 | 
						|
        {
 | 
						|
            // Similar a Create, la columna en DB es "Ritmo"
 | 
						|
            const string sqlUpdate = @"
 | 
						|
                UPDATE dbo.rad_dtCanciones SET 
 | 
						|
                    Tema = @Tema, CompositorAutor = @CompositorAutor, Interprete = @Interprete, Sello = @Sello,
 | 
						|
                    Placa = @Placa, Pista = @Pista, Introduccion = @Introduccion, Ritmo = @IdRitmo, 
 | 
						|
                    Formato = @Formato, Album = @Album
 | 
						|
                WHERE Id = @Id;";
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                var rowsAffected = await connection.ExecuteAsync(sqlUpdate, cancionAActualizar);
 | 
						|
                return rowsAffected == 1;
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al actualizar Canción ID: {IdCancion}", cancionAActualizar.Id);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public async Task<bool> DeleteAsync(int id /*, int idUsuario, IDbTransaction transaction */)
 | 
						|
        {
 | 
						|
            // IsInUseAsync no se implementó porque no hay dependencias directas obvias que impidan borrar una canción
 | 
						|
            // (a menos que las listas generadas se guarden y referencien IDs de canciones).
 | 
						|
            const string sqlDelete = "DELETE FROM dbo.rad_dtCanciones WHERE Id = @IdParam";
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                var rowsAffected = await connection.ExecuteAsync(sqlDelete, new { IdParam = id });
 | 
						|
                return rowsAffected == 1;
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al eliminar Canción ID: {IdCancion}", id);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        // IsInUseAsync podría ser relevante si las listas generadas referencian el Id de la canción
 | 
						|
        // Por ahora, lo omitimos.
 | 
						|
        public Task<bool> IsInUseAsync(int id)
 | 
						|
        {
 | 
						|
            _log.LogWarning("IsInUseAsync no implementado para CancionRepository.");
 | 
						|
            return Task.FromResult(false); // Asumir que no está en uso por ahora
 | 
						|
        }
 | 
						|
 | 
						|
        public async Task<IEnumerable<Cancion>> GetRandomCancionesAsync(int count)
 | 
						|
        {
 | 
						|
            // El modelo Cancion tiene la propiedad "Ritmo" que es el IdRitmo.
 | 
						|
            // El SelectWithAlias no es necesario aquí si solo tomamos las columnas que ya tiene Cancion.
 | 
						|
            // Si el modelo Cancion no tuviera la propiedad Ritmo (IdRitmo), entonces necesitarías el alias.
 | 
						|
            // Por simplicidad, y dado que el modelo Cancion sí tiene Ritmo (que es IdRitmo), no necesitamos un alias específico aquí.
 | 
						|
            var sql = $"SELECT TOP ({count}) Id, Tema, CompositorAutor, Interprete, Sello, Placa, Pista, Introduccion, Ritmo, Formato, Album FROM dbo.rad_dtCanciones ORDER BY NEWID()";
 | 
						|
            try
 | 
						|
            {
 | 
						|
                using var connection = _cf.CreateConnection();
 | 
						|
                // Dapper mapeará la columna "Ritmo" de la BD a la propiedad "Ritmo" del modelo Cancion.
 | 
						|
                return await connection.QueryAsync<Cancion>(sql);
 | 
						|
            }
 | 
						|
            catch (Exception ex)
 | 
						|
            {
 | 
						|
                _log.LogError(ex, "Error al obtener {Count} canciones aleatorias.", count);
 | 
						|
                return Enumerable.Empty<Cancion>();
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |