Ya perdí el hilo de los cambios pero ahi van.
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using GestionIntegral.Api.Models.Radios;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
// using System.Data; // Solo si se usa transacción para historial
|
||||
|
||||
namespace GestionIntegral.Api.Data.Repositories.Radios
|
||||
{
|
||||
public interface ICancionRepository
|
||||
{
|
||||
Task<IEnumerable<Cancion>> GetAllAsync(string? temaFilter, string? interpreteFilter, int? idRitmoFilter);
|
||||
Task<Cancion?> GetByIdAsync(int id);
|
||||
Task<Cancion?> CreateAsync(Cancion nuevaCancion /*, int idUsuario, IDbTransaction transaction - si hay historial */);
|
||||
Task<bool> UpdateAsync(Cancion cancionAActualizar /*, int idUsuario, IDbTransaction transaction */);
|
||||
Task<bool> DeleteAsync(int id /*, int idUsuario, IDbTransaction transaction */);
|
||||
Task<bool> ExistsByTemaAndInterpreteAsync(string tema, string interprete, int? excludeId = null); // Ejemplo de unicidad
|
||||
Task<IEnumerable<Cancion>> GetRandomCancionesAsync(int count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using GestionIntegral.Api.Models.Radios;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
// using System.Data; // Solo si se usa transacción para historial
|
||||
|
||||
namespace GestionIntegral.Api.Data.Repositories.Radios
|
||||
{
|
||||
public interface IRitmoRepository
|
||||
{
|
||||
Task<IEnumerable<Ritmo>> GetAllAsync(string? nombreFilter);
|
||||
Task<Ritmo?> GetByIdAsync(int id);
|
||||
Task<Ritmo?> CreateAsync(Ritmo nuevoRitmo /*, int idUsuario, IDbTransaction transaction - si hay historial */);
|
||||
Task<bool> UpdateAsync(Ritmo ritmoAActualizar /*, int idUsuario, IDbTransaction transaction */);
|
||||
Task<bool> DeleteAsync(int id /*, int idUsuario, IDbTransaction transaction */);
|
||||
Task<bool> ExistsByNameAsync(string nombreRitmo, int? excludeId = null);
|
||||
Task<bool> IsInUseAsync(int id); // Verificar si se usa en rad_dtCanciones
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
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 RitmoRepository : IRitmoRepository
|
||||
{
|
||||
private readonly DbConnectionFactory _cf;
|
||||
private readonly ILogger<RitmoRepository> _log;
|
||||
|
||||
public RitmoRepository(DbConnectionFactory cf, ILogger<RitmoRepository> log)
|
||||
{
|
||||
_cf = cf;
|
||||
_log = log;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Ritmo>> GetAllAsync(string? nombreFilter)
|
||||
{
|
||||
var sqlBuilder = new StringBuilder("SELECT Id, Ritmo AS NombreRitmo FROM dbo.rad_dtRitmos WHERE 1=1");
|
||||
var parameters = new DynamicParameters();
|
||||
if (!string.IsNullOrWhiteSpace(nombreFilter))
|
||||
{
|
||||
sqlBuilder.Append(" AND Ritmo LIKE @NombreFilterParam");
|
||||
parameters.Add("NombreFilterParam", $"%{nombreFilter}%");
|
||||
}
|
||||
sqlBuilder.Append(" ORDER BY Ritmo;");
|
||||
try
|
||||
{
|
||||
using var connection = _cf.CreateConnection();
|
||||
return await connection.QueryAsync<Ritmo>(sqlBuilder.ToString(), parameters);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "Error al obtener todos los Ritmos.");
|
||||
return Enumerable.Empty<Ritmo>();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Ritmo?> GetByIdAsync(int id)
|
||||
{
|
||||
const string sql = "SELECT Id, Ritmo AS NombreRitmo FROM dbo.rad_dtRitmos WHERE Id = @IdParam";
|
||||
try
|
||||
{
|
||||
using var connection = _cf.CreateConnection();
|
||||
return await connection.QuerySingleOrDefaultAsync<Ritmo>(sql, new { IdParam = id });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "Error al obtener Ritmo por ID: {IdRitmo}", id);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ExistsByNameAsync(string nombreRitmo, int? excludeId = null)
|
||||
{
|
||||
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.rad_dtRitmos WHERE Ritmo = @NombreRitmoParam");
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("NombreRitmoParam", nombreRitmo);
|
||||
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 ExistsByNameAsync para Ritmo: {NombreRitmo}", nombreRitmo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> IsInUseAsync(int id)
|
||||
{
|
||||
const string sql = "SELECT TOP 1 1 FROM dbo.rad_dtCanciones WHERE Ritmo = @IdParam"; // Columna 'Ritmo' en Canciones es FK a 'Id' en Ritmos
|
||||
try
|
||||
{
|
||||
using var connection = _cf.CreateConnection();
|
||||
return await connection.ExecuteScalarAsync<bool>(sql, new { IdParam = id });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "Error en IsInUseAsync para Ritmo ID: {IdRitmo}", id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Ritmo?> CreateAsync(Ritmo nuevoRitmo /*, int idUsuario, IDbTransaction transaction */)
|
||||
{
|
||||
// Sin historial, no se necesita transacción aquí para una sola inserción.
|
||||
const string sqlInsert = @"
|
||||
INSERT INTO dbo.rad_dtRitmos (Ritmo)
|
||||
OUTPUT INSERTED.Id, INSERTED.Ritmo AS NombreRitmo
|
||||
VALUES (@NombreRitmo);";
|
||||
try
|
||||
{
|
||||
using var connection = _cf.CreateConnection();
|
||||
return await connection.QuerySingleAsync<Ritmo>(sqlInsert, nuevoRitmo);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "Error al crear Ritmo: {NombreRitmo}", nuevoRitmo.NombreRitmo);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateAsync(Ritmo ritmoAActualizar /*, int idUsuario, IDbTransaction transaction */)
|
||||
{
|
||||
const string sqlUpdate = "UPDATE dbo.rad_dtRitmos SET Ritmo = @NombreRitmo WHERE Id = @Id;";
|
||||
try
|
||||
{
|
||||
using var connection = _cf.CreateConnection();
|
||||
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, ritmoAActualizar);
|
||||
return rowsAffected == 1;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_log.LogError(ex, "Error al actualizar Ritmo ID: {IdRitmo}", ritmoAActualizar.Id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(int id /*, int idUsuario, IDbTransaction transaction */)
|
||||
{
|
||||
const string sqlDelete = "DELETE FROM dbo.rad_dtRitmos 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 Ritmo ID: {IdRitmo}", id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user