feat: Implement MercadoAgroFetcher scraper and repositories

This commit is contained in:
2025-07-01 11:39:04 -03:00
parent 075710287d
commit 2fdf80f5b4
8 changed files with 283 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
using Dapper;
using Mercados.Core.Entities;
using System.Data;
namespace Mercados.Infrastructure.Persistence.Repositories
{
public class CotizacionGanadoRepository : ICotizacionGanadoRepository
{
private readonly IDbConnectionFactory _connectionFactory;
public CotizacionGanadoRepository(IDbConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task GuardarMuchosAsync(IEnumerable<CotizacionGanado> cotizaciones)
{
using IDbConnection connection = _connectionFactory.CreateConnection();
// Dapper puede insertar una colección de objetos de una sola vez, ¡muy eficiente!
const string sql = @"
INSERT INTO CotizacionesGanado (
Categoria, Especificaciones, Maximo, Minimo, Promedio, Mediano,
Cabezas, KilosTotales, KilosPorCabeza, ImporteTotal, FechaRegistro
)
VALUES (
@Categoria, @Especificaciones, @Maximo, @Minimo, @Promedio, @Mediano,
@Cabezas, @KilosTotales, @KilosPorCabeza, @ImporteTotal, @FechaRegistro
);";
await connection.ExecuteAsync(sql, cotizaciones);
}
}
}

View File

@@ -0,0 +1,42 @@
using Dapper;
using Mercados.Core.Entities;
using System.Data;
namespace Mercados.Infrastructure.Persistence.Repositories
{
public class FuenteDatoRepository : IFuenteDatoRepository
{
private readonly IDbConnectionFactory _connectionFactory;
public FuenteDatoRepository(IDbConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task<FuenteDato?> ObtenerPorNombreAsync(string nombre)
{
using IDbConnection connection = _connectionFactory.CreateConnection();
const string sql = "SELECT * FROM FuentesDatos WHERE Nombre = @Nombre;";
return await connection.QuerySingleOrDefaultAsync<FuenteDato>(sql, new { Nombre = nombre });
}
public async Task CrearAsync(FuenteDato fuenteDato)
{
using IDbConnection connection = _connectionFactory.CreateConnection();
const string sql = @"
INSERT INTO FuentesDatos (Nombre, UltimaEjecucionExitosa, Url)
VALUES (@Nombre, @UltimaEjecucionExitosa, @Url);";
await connection.ExecuteAsync(sql, fuenteDato);
}
public async Task ActualizarAsync(FuenteDato fuenteDato)
{
using IDbConnection connection = _connectionFactory.CreateConnection();
const string sql = @"
UPDATE FuentesDatos
SET UltimaEjecucionExitosa = @UltimaEjecucionExitosa, Url = @Url
WHERE Id = @Id;";
await connection.ExecuteAsync(sql, fuenteDato);
}
}
}

View File

@@ -0,0 +1,7 @@
namespace Mercados.Infrastructure.Persistence.Repositories
{
// Esta interfaz no es estrictamente necesaria ahora, pero es útil para futuras abstracciones.
public interface IBaseRepository
{
}
}

View File

@@ -0,0 +1,9 @@
using Mercados.Core.Entities;
namespace Mercados.Infrastructure.Persistence.Repositories
{
public interface ICotizacionGanadoRepository : IBaseRepository
{
Task GuardarMuchosAsync(IEnumerable<CotizacionGanado> cotizaciones);
}
}

View File

@@ -0,0 +1,11 @@
using Mercados.Core.Entities;
namespace Mercados.Infrastructure.Persistence.Repositories
{
public interface IFuenteDatoRepository : IBaseRepository
{
Task<FuenteDato?> ObtenerPorNombreAsync(string nombre);
Task ActualizarAsync(FuenteDato fuenteDato);
Task CrearAsync(FuenteDato fuenteDato);
}
}