feat: Add initial database migration with FluentMigrator
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Mercados.Infrastructure\Mercados.Infrastructure.csproj" />
|
<ProjectReference Include="..\Mercados.Infrastructure\Mercados.Infrastructure.csproj" />
|
||||||
|
<ProjectReference Include="..\Mercados.Database\Mercados.Database.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,20 +1,54 @@
|
|||||||
// Importamos los namespaces necesarios
|
using FluentMigrator.Runner; // <--- AÑADIR
|
||||||
|
using Mercados.Database.Migrations; // <--- AÑADIR
|
||||||
using Mercados.Infrastructure;
|
using Mercados.Infrastructure;
|
||||||
using Mercados.Infrastructure.Persistence;
|
using Mercados.Infrastructure.Persistence;
|
||||||
|
using System.Reflection; // <--- AÑADIR
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// 1. Registramos nuestra fábrica de conexiones como un Singleton.
|
// --- V INICIO DE NUESTRO CÓDIGO V ---
|
||||||
// Solo se creará una instancia que leerá la configuration una vez.
|
|
||||||
|
// 1. Registramos nuestra fábrica de conexiones.
|
||||||
builder.Services.AddSingleton<IDbConnectionFactory, SqlConnectionFactory>();
|
builder.Services.AddSingleton<IDbConnectionFactory, SqlConnectionFactory>();
|
||||||
|
|
||||||
|
// 2. Configurar FluentMigrator
|
||||||
|
builder.Services
|
||||||
|
.AddFluentMigratorCore()
|
||||||
|
.ConfigureRunner(rb => rb
|
||||||
|
// Usar el conector para SQL Server
|
||||||
|
.AddSqlServer()
|
||||||
|
// Obtener la cadena de conexión desde appsettings.json
|
||||||
|
.WithGlobalConnectionString(builder.Configuration.GetConnectionString("DefaultConnection"))
|
||||||
|
// Definir el ensamblado (proyecto) que contiene las migraciones
|
||||||
|
.ScanIn(typeof(CreateInitialTables).Assembly).For.Migrations())
|
||||||
|
// Habilitar el logging para ver qué hacen las migraciones en la consola
|
||||||
|
.AddLogging(lb => lb.AddFluentMigratorConsole());
|
||||||
|
|
||||||
|
|
||||||
|
// --- ^ FIN DE NUESTRO CÓDIGO ^ ---
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// --- V INICIO DE NUESTRO CÓDIGO DE EJECUCIÓN V ---
|
||||||
|
|
||||||
|
// 3. Ejecutar las migraciones al iniciar la aplicación (ideal para desarrollo y despliegues sencillos)
|
||||||
|
// Obtenemos el "scope" de los servicios para poder solicitar el MigrationRunner
|
||||||
|
using (var scope = app.Services.CreateScope())
|
||||||
|
{
|
||||||
|
var migrationRunner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
|
||||||
|
// Ejecuta las migraciones pendientes
|
||||||
|
migrationRunner.MigrateUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ^ FIN DE NUESTRO CÓDIGO DE EJECUCIÓN ^ ---
|
||||||
|
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
|
||||||
|
namespace Mercados.Database.Migrations
|
||||||
|
{
|
||||||
|
// El número es la versión única de esta migración.
|
||||||
|
// Usar un timestamp es una práctica común y segura.
|
||||||
|
[Migration(20250701113000)]
|
||||||
|
public class CreateInitialTables : Migration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Define las acciones a realizar para aplicar la migración (crear tablas, etc.).
|
||||||
|
/// </summary>
|
||||||
|
public override void Up()
|
||||||
|
{
|
||||||
|
// --- Tabla para Cotizaciones de Ganado ---
|
||||||
|
Create.Table("CotizacionesGanado")
|
||||||
|
.WithColumn("Id").AsInt64().PrimaryKey().Identity() // Usamos Int64 (long) para los IDs
|
||||||
|
.WithColumn("Categoria").AsString(100).NotNullable()
|
||||||
|
.WithColumn("Especificaciones").AsString(200).NotNullable()
|
||||||
|
.WithColumn("Maximo").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("Minimo").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("Promedio").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("Mediano").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("Cabezas").AsInt32().NotNullable()
|
||||||
|
.WithColumn("KilosTotales").AsInt32().NotNullable()
|
||||||
|
.WithColumn("KilosPorCabeza").AsInt32().NotNullable()
|
||||||
|
.WithColumn("ImporteTotal").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("FechaRegistro").AsDateTime().NotNullable();
|
||||||
|
|
||||||
|
// --- Tabla para Cotizaciones de Granos ---
|
||||||
|
Create.Table("CotizacionesGranos")
|
||||||
|
.WithColumn("Id").AsInt64().PrimaryKey().Identity()
|
||||||
|
.WithColumn("Nombre").AsString(50).NotNullable()
|
||||||
|
.WithColumn("Precio").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("VariacionPrecio").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("FechaOperacion").AsDateTime().NotNullable()
|
||||||
|
.WithColumn("FechaRegistro").AsDateTime().NotNullable();
|
||||||
|
|
||||||
|
// --- Tabla para Cotizaciones de Bolsa ---
|
||||||
|
Create.Table("CotizacionesBolsa")
|
||||||
|
.WithColumn("Id").AsInt64().PrimaryKey().Identity()
|
||||||
|
.WithColumn("Ticker").AsString(20).NotNullable()
|
||||||
|
.WithColumn("Mercado").AsString(50).NotNullable() // "EEUU", "Local"
|
||||||
|
.WithColumn("PrecioActual").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("Apertura").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("CierreAnterior").AsDecimal(18, 2).NotNullable()
|
||||||
|
.WithColumn("PorcentajeCambio").AsDecimal(18, 4).NotNullable() // Más precisión para porcentajes
|
||||||
|
.WithColumn("FechaRegistro").AsDateTime().NotNullable();
|
||||||
|
|
||||||
|
// --- Tabla para auditar las fuentes de datos ---
|
||||||
|
Create.Table("FuentesDatos")
|
||||||
|
.WithColumn("Id").AsInt64().PrimaryKey().Identity()
|
||||||
|
.WithColumn("Nombre").AsString(100).NotNullable().Unique() // El nombre debe ser único
|
||||||
|
.WithColumn("UltimaEjecucionExitosa").AsDateTime().NotNullable()
|
||||||
|
.WithColumn("Url").AsString(500).Nullable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Define las acciones para revertir la migración (eliminar las tablas).
|
||||||
|
/// Esto es útil si necesitas deshacer un cambio.
|
||||||
|
/// </summary>
|
||||||
|
public override void Down()
|
||||||
|
{
|
||||||
|
Delete.Table("FuentesDatos");
|
||||||
|
Delete.Table("CotizacionesBolsa");
|
||||||
|
Delete.Table("CotizacionesGranos");
|
||||||
|
Delete.Table("CotizacionesGanado");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user